/**
 * license.js — Validação de licenças da extensão
 */
const express = require('express');
const router = express.Router();
const db = require('../db');
const crypto = require('crypto');

function generateSessionToken() {
    return 'SES-' + crypto.randomBytes(16).toString('hex').toUpperCase();
}

function timeRemaining(expiresAt) {
    if (!expiresAt) return { days: 0, str: '0d' };
    const diff = new Date(expiresAt) - new Date();
    const days = Math.max(0, Math.floor(diff / (1000 * 60 * 60 * 24)));
    const mins = Math.max(0, Math.ceil(diff / (1000 * 60)));
    if (days > 0) return { days, str: days + 'd' };
    if (mins > 60) return { days: 0, str: Math.floor(mins / 60) + 'h' };
    return { days: 0, str: mins + 'm' };
}

async function validateLicense(licenseKey, deviceId) {
    if (!licenseKey || !deviceId) {
        return { valid: false, message: 'Credenciais ausentes' };
    }

    const [rows] = await db.execute(
        'SELECT status, expires_at, bound_user FROM licenses WHERE license_key = ?',
        [licenseKey]
    );
    const license = rows[0];

    if (!license || (license.status !== 'active' && license.status !== 'valid')) {
        return { valid: false, message: 'Licença inválida ou inativa' };
    }

    if (license.expires_at && new Date(license.expires_at) < new Date()) {
        await db.execute("UPDATE licenses SET status = 'expired' WHERE license_key = ?", [licenseKey]);
        return { valid: false, message: 'Licença expirada' };
    }

    // O GET checkNENHUM não vincula mais licenças! O vínculo ocorre apenas no POST /api/validate-license.

    return {
        valid: true,
        message: '✅ Relovable Ativo!',
        time_str: timeRemaining(license.expires_at).str
    };
}

/**
 * GET /api/license/check/:token
 */
router.get('/license/check/:token', async (req, res) => {
    const licenseKey = req.params.token;
    const deviceId = req.query.deviceId || null;
    const ip = req.ip || req.headers['x-forwarded-for'] || null;
    const ua = req.headers['user-agent'] || null;

    try {
        const result = await validateLicense(licenseKey, deviceId);

        // Only log FAILURES — successful checks are too frequent (every tab switch / 5min heartbeat)
        if (!result.valid) {
            const logResult =
                (result.message || '').includes('expirada') ? 'expired' :
                    (result.message || '').includes('revogada') ? 'revoked' : 'invalid';

            await db.execute(
                `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, ?, ?, ?)`,
                [licenseKey || null, deviceId, logResult, ip, ua]
            ).catch(e => console.warn('[Monitor] Validation log failed:', e.message));

            return res.status(403).json(result);
        }
        res.json(result);
    } catch (err) {
        // Log the error
        await db.execute(
            `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'error', ?, ?)`,
            [licenseKey || null, deviceId, ip, ua]
        ).catch(() => { });

        res.status(500).json({ valid: false, message: 'Erro interno', details: err.message });
    }
});

/**
 * POST /api/validate-license
 */
router.post('/validate-license', async (req, res) => {
    const { license_key, lovable_user_id } = req.body;
    const ip = req.ip || req.headers['x-forwarded-for'] || null;
    const ua = req.headers['user-agent'] || null;
    const deviceId = req.body.device_id || null;

    const isMobile = req.body.is_mobile === true;

    if (!license_key) {
        await db.execute(
            `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'invalid', ?, ?)`,
            [null, deviceId, ip, ua]
        ).catch(() => { });
        return res.status(400).json({ status: 'invalid', message: 'Chave de licença obrigatória' });
    }

    if (!isMobile && (!lovable_user_id || lovable_user_id === 'unknown' || lovable_user_id.length < 10)) {
        await db.execute(
            `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'invalid', ?, ?)`,
            [license_key, deviceId, ip, ua]
        ).catch(() => { });
        return res.status(400).json({ status: 'invalid', message: 'Usuário Lovable não identificado. Faça login no Lovable.dev primeiro.' });
    }

    const key = license_key.trim().toUpperCase();

    try {
        const [rows] = await db.execute('SELECT * FROM licenses WHERE license_key = ?', [key]);
        const license = rows[0];

        if (!license) {
            await db.execute(
                `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'invalid', ?, ?)`,
                [key, deviceId, ip, ua]
            ).catch(() => { });
            return res.json({ status: 'invalid', message: 'Licença não encontrada' });
        }

        if (license.status === 'revoked') {
            await db.execute(
                `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'revoked', ?, ?)`,
                [key, deviceId, ip, ua]
            ).catch(() => { });
            return res.json({ status: 'invalid', message: 'Licença revogada' });
        }

        const now = new Date();

        if (license.expires_at && new Date(license.expires_at) < now) {
            await db.execute("UPDATE licenses SET status = 'expired' WHERE license_key = ?", [key]);
            await db.execute(
                `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'expired', ?, ?)`,
                [key, deviceId, ip, ua]
            ).catch(() => { });
            return res.json({ status: 'invalid', message: 'Licença expirada' });
        }

        // New restriction: 1 active license per Lovable account
        if (!license.bound_user) {
            if (isMobile) {
                return res.status(400).json({
                    status: 'invalid',
                    message: 'Esta licença ainda não foi ativada. Ative-a primeiro no computador através da extensão.'
                });
            }

            const [activeCheck] = await db.execute(
                'SELECT id, license_key FROM licenses WHERE bound_user = ? AND status IN ("active", "valid") AND expires_at > NOW()',
                [lovable_user_id]
            );
            if (activeCheck.length > 0) {
                return res.json({
                    status: 'invalid',
                    message: `Você já possui uma licença ativa (${activeCheck[0].license_key}). Para trocar, desvincule a antiga com o suporte.`
                });
            }
        }

        if (license.bound_user && !isMobile && license.bound_user !== lovable_user_id) {
            await db.execute(
                `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'invalid', ?, ?)`,
                [key, deviceId, ip, ua]
            ).catch(() => { });
            return res.json({ status: 'invalid', message: 'Licença já está em uso por outra conta Lovable' });
        }

        // Validation successful — log as ok
        await db.execute(
            `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'ok', ?, ?)`,
            [key, deviceId, ip, ua]
        ).catch(() => { });

        // Fetch the user's token (from the latest sync on any device)
        let lovableToken = null;
        try {
            const [accs] = await db.execute(
                'SELECT lovable_token FROM lovable_accounts WHERE license_key = ? AND lovable_token IS NOT NULL ORDER BY last_sync_at DESC LIMIT 1',
                [key]
            );
            if (accs.length > 0) lovableToken = accs[0].lovable_token;
        } catch (e) { }

        if (!license.bound_user) {
            const expiresAt = new Date(now.getTime() + license.duration_minutes * 60 * 1000);

            // Format JS Date to MySQL timestamp string format "YYYY-MM-DD HH:MM:SS"
            const mysqlExpiresAt = expiresAt.toISOString().slice(0, 19).replace('T', ' ');

            await db.execute(`
                UPDATE licenses
                SET bound_user = ?, bound_at = CURRENT_TIMESTAMP,
                    activated_at = CURRENT_TIMESTAMP, expires_at = ?, last_seen_at = CURRENT_TIMESTAMP
                WHERE license_key = ?
            `, [lovable_user_id, mysqlExpiresAt, key]);

            return res.json({
                status: 'valid',
                session_token: generateSessionToken(),
                plan_name: license.plan_name,
                time_str: timeRemaining(expiresAt).str,
                authToken: lovableToken,
                message: '✅ Licença ativada com sucesso!'
            });
        }

        await db.execute("UPDATE licenses SET last_seen_at = CURRENT_TIMESTAMP WHERE license_key = ?", [key]);
        return res.json({
            status: 'valid',
            session_token: generateSessionToken(),
            plan_name: license.plan_name,
            authToken: lovableToken,
            time_str: timeRemaining(license.expires_at).str
        });

    } catch (err) {
        console.error('❌ Erro na validação de licença:', err);
        await db.execute(
            `INSERT INTO license_validation_logs (license_key, device_id, result, ip_address, user_agent) VALUES (?, ?, 'error', ?, ?)`,
            [key, deviceId, ip, ua]
        ).catch(() => { });
        return res.status(500).json({ status: 'error', message: 'Erro interno no servidor' });
    }
});

/**
 * GET /api/status
 */
router.get('/status', async (req, res) => {
    try {
        const [rows] = await db.execute('SELECT COUNT(*) as total FROM licenses');
        res.json({ status: 'ok', total_licenses: rows[0].total });
    } catch (err) {
        res.status(500).json({ status: 'error', message: err.message });
    }
});

module.exports = { router, validateLicense };
