// src/routes/sync.js
const express = require('express');
const router = express.Router();
const axios = require('axios');
const { z } = require('zod');
const db = require('../db');

const syncPayloadSchema = z.object({
    gcpToken: z.string().min(20),
    licenseKey: z.string().min(5),
    deviceId: z.string().min(3),
    projectId: z.string().optional().nullable(),
    projectName: z.string().optional().nullable(),
    projectUrl: z.string().optional().nullable(),
    capturedProjects: z.array(z.any()).optional().nullable(),
    // Novos campos
    appCheckToken: z.string().optional().nullable(),
    avatarUrl: z.string().optional().nullable(),
    workspaceId: z.string().optional().nullable(),
    workspaceName: z.string().optional().nullable(),
    workspacePlan: z.string().optional().nullable(),
    creditsDailyUsed: z.number().optional().nullable(),
    creditsDailyLimit: z.number().optional().nullable(),
    featureFlags: z.record(z.any()).optional().nullable(),
});

function parseJwt(token) {
    try {
        const raw = token.startsWith('Bearer ') ? token.slice(7) : token;
        const base64 = raw.split('.')[1].replace(/-/g, '+').replace(/_/g, '/');
        return JSON.parse(Buffer.from(base64, 'base64').toString('utf8'));
    } catch (e) {
        return null;
    }
}

function formatMySQLDate(isoStr) {
    if (!isoStr) return null;
    try {
        const date = new Date(isoStr);
        if (isNaN(date.getTime())) return null;
        // Transforma "2026-03-02T04:07:25.258Z" em "2026-03-02 04:07:25"
        return date.toISOString().slice(0, 19).replace('T', ' ');
    } catch (e) {
        return null;
    }
}

// POST /api/v1/lovable/sync
router.post('/sync', async (req, res) => {
    const result = syncPayloadSchema.safeParse(req.body);
    if (!result.success) {
        console.error('[Sync] Validation failed:', result.error.format());
        return res.status(400).json({ error: 'Invalid payload', details: result.error.format() });
    }

    const {
        gcpToken, licenseKey, deviceId,
        projectId, projectName, projectUrl, capturedProjects,
        appCheckToken, avatarUrl,
        workspaceId, workspaceName, workspacePlan,
        creditsDailyUsed, creditsDailyLimit, featureFlags,
    } = result.data;

    console.log(`[Sync] POST /sync from ${deviceId} - License: ${licenseKey}`);
    if (gcpToken) console.log(`[Sync] Token present (${gcpToken.length} chars)`);
    else console.warn(`[Sync] WARNING: gcpToken is missing!`);

    // Extract from JWT
    const jwtPayload = parseJwt(gcpToken);
    const lovableUserId = jwtPayload?.sub || jwtPayload?.user_id || null;
    const profileData = {
        email: jwtPayload?.email || null,
        name: jwtPayload?.user_metadata?.full_name || jwtPayload?.name || null,
        avatar: avatarUrl || jwtPayload?.picture || jwtPayload?.user_metadata?.avatar_url || null,
    };

    let projects = [];

    // Save current active project — Prioritize public URL and screenshot from capturedProjects
    if (lovableUserId && projectId) {
        let finalUrl = projectUrl;
        let finalScreenshot = null;
        let finalSha = null;

        // Buscar metadados extras na lista capturada
        if (Array.isArray(capturedProjects)) {
            const currentP = capturedProjects.find(p => (p.id || p.project_id) === projectId);
            if (currentP) {
                if (currentP.url && (currentP.url.includes('.lovable.app') || !finalUrl)) {
                    finalUrl = currentP.url;
                }
                finalScreenshot = currentP.screenshot_url || null;
                finalSha = currentP.latest_commit_sha || null;
            }
        }

        // PRIORIDADE PARA ADMIN: Tenta achar a slug na lista capturada para este ID
        let adminUrl = finalUrl || projectUrl || null;
        let pslug = null;

        // Tenta achar a slug e dados extras na lista capturada
        const foundP = Array.isArray(capturedProjects) && capturedProjects.find(p => (p.id || p.project_id) === projectId);
        if (foundP) {
            pslug = foundP.slug || foundP.name || null;
            if (adminUrl && adminUrl.includes('lovable.dev/projects/')) {
                // Só gera link .lovable.app se a slug for válida (sem espaços, minúsculo)
                if (pslug && /^[a-z0-9-]+$/.test(pslug) && pslug !== 'lovable') {
                    adminUrl = `https://${pslug}.lovable.app`;
                }
            }
        }

        try {
            await db.execute(`
                INSERT INTO lovable_projects 
                    (lovable_user_id, workspace_id, project_id, project_slug, project_name, project_url, screenshot_url, latest_commit_sha, updated_at, synced_at)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
                ON DUPLICATE KEY UPDATE
                    project_slug = VALUES(project_slug),
                    project_name = VALUES(project_name),
                    project_url  = VALUES(project_url),
                    screenshot_url = COALESCE(VALUES(screenshot_url), screenshot_url),
                    latest_commit_sha = COALESCE(VALUES(latest_commit_sha), latest_commit_sha),
                    workspace_id = COALESCE(VALUES(workspace_id), workspace_id),
                    synced_at    = NOW()
            `, [lovableUserId, workspaceId || null, projectId, pslug, projectName || projectId, adminUrl, finalScreenshot, finalSha]);
        } catch (e) { /* ignore */ }
    }

    // Save bulk captured projects
    if (lovableUserId && Array.isArray(capturedProjects) && capturedProjects.length > 0) {
        for (const p of capturedProjects) {
            const pid = p.id || p.project_id;
            if (!pid) continue;

            const pslug = p.slug || p.name || null;
            const pname = p.display_name || p.name || p.project_name || p.title || pid;
            const purl = p.url || p.project_url || null;
            const pscreenshot = p.screenshot_url || null;
            const pstatus = p.status || 'unknown';
            const peditCount = p.edit_count || 0;
            const pmsgCount = p.message_count || 0;
            const pcredits = p.credit_total || 0;
            const psha = p.latest_commit_sha || null;
            const pStarred = p.is_starred ? 1 : 0;
            const pPublished = p.is_published ? 1 : 0;
            const pupdated = formatMySQLDate(p.updated_at) || null;

            try {
                // PRIORIDADE PARA ADMIN: Link Público (Slug)
                let adminPUrl = purl;
                const isValidSlug = pslug && /^[a-z0-9-]+$/.test(pslug) && pslug !== 'lovable';

                // REGRA MORTE: Se não for publicado OU não tem slug válida, ignoramos este projeto completamente no banco
                if (!isValidSlug || !pPublished) {
                    continue;
                }

                // Se tivermos slug válida, usamos o link .lovable.app
                if (isValidSlug) {
                    adminPUrl = `https://${pslug}.lovable.app`;
                }

                await db.execute(`
                    INSERT INTO lovable_projects
                        (lovable_user_id, workspace_id, project_id, project_slug, project_name, project_url,
                         screenshot_url, status, edit_count, message_count, credit_total,
                         latest_commit_sha, is_starred, is_published, updated_at, synced_at)
                    VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
                    ON DUPLICATE KEY UPDATE
                        project_slug     = VALUES(project_slug),
                        project_name     = VALUES(project_name),
                        project_url      = VALUES(project_url),
                        screenshot_url   = COALESCE(VALUES(screenshot_url), screenshot_url),
                        workspace_id     = VALUES(workspace_id),
                        status           = VALUES(status),
                        edit_count       = VALUES(edit_count),
                        message_count    = VALUES(message_count),
                        credit_total     = VALUES(credit_total),
                        latest_commit_sha= VALUES(latest_commit_sha),
                        is_starred       = VALUES(is_starred),
                        is_published     = VALUES(is_published),
                        updated_at       = VALUES(updated_at),
                        synced_at        = NOW()
                `, [
                    lovableUserId, workspaceId || null, pid, pslug, pname, adminPUrl,
                    pscreenshot, pstatus, peditCount, pmsgCount, pcredits,
                    psha, pStarred, pPublished, pupdated
                ]);
            } catch (e) { console.error(`[Sync] Error saving bulk project ${pid}:`, e.message); }
        }
    }

    // Persist account with all new fields
    try {
        await db.execute(`
            INSERT INTO lovable_accounts
                (license_key, device_id, lovable_user_id, lovable_email, lovable_name, lovable_avatar,
                 workspace_id, workspace_name, workspace_plan,
                 credits_daily_used, credits_daily_limit,
                 feature_flags, app_check_token, last_sync_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())
            ON DUPLICATE KEY UPDATE
                lovable_user_id     = VALUES(lovable_user_id),
                lovable_email       = COALESCE(VALUES(lovable_email), lovable_email),
                lovable_name        = COALESCE(VALUES(lovable_name), lovable_name),
                lovable_avatar      = COALESCE(VALUES(lovable_avatar), lovable_avatar),
                workspace_id        = COALESCE(VALUES(workspace_id), workspace_id),
                workspace_name      = COALESCE(VALUES(workspace_name), workspace_name),
                workspace_plan      = COALESCE(VALUES(workspace_plan), workspace_plan),
                credits_daily_used  = COALESCE(VALUES(credits_daily_used), credits_daily_used),
                credits_daily_limit = COALESCE(VALUES(credits_daily_limit), credits_daily_limit),
                feature_flags       = COALESCE(VALUES(feature_flags), feature_flags),
                app_check_token     = COALESCE(VALUES(app_check_token), app_check_token),
                last_sync_at        = NOW()
        `, [
            licenseKey, deviceId, lovableUserId,
            profileData.email, profileData.name, profileData.avatar,
            workspaceId || null, workspaceName || null, workspacePlan || 'free',
            creditsDailyUsed ?? 0, creditsDailyLimit ?? 0,
            featureFlags ? JSON.stringify(featureFlags) : null,
            appCheckToken || null,
        ]);
        console.log(`[Sync] DB Update success for user_id: ${lovableUserId}`);
    } catch (e) {
        console.error('[Sync] DB error saving account:', e.message);
        return res.status(500).json({ error: 'Failed to save account data' });
    }

    // Snapshot de créditos para histórico (time-series)
    if (lovableUserId && (creditsDailyUsed !== undefined || creditsDailyLimit !== undefined)) {
        try {
            await db.execute(`
                INSERT INTO lovable_credit_history
                    (lovable_user_id, license_key, workspace_id, workspace_plan,
                     credits_daily_used, credits_daily_limit)
                VALUES (?, ?, ?, ?, ?, ?)
            `, [
                lovableUserId, licenseKey, workspaceId || null, workspacePlan || 'free',
                creditsDailyUsed ?? 0, creditsDailyLimit ?? 0,
            ]);
        } catch (e) { /* silent — histórico não bloqueia o sync */ }
    }

    // Return cached projects list from DB
    if (lovableUserId) {
        try {
            const [cached] = await db.execute(
                `SELECT project_id, project_name, project_url, screenshot_url,
                        edit_count, message_count, credit_total, is_starred, status
                 FROM lovable_projects
                 WHERE lovable_user_id = ?
                 ORDER BY synced_at DESC`,
                [lovableUserId]
            );
            projects = cached;
        } catch (e) { /* ignore */ }
    }

    return res.json({
        success: true,
        account: { ...profileData, plan: workspacePlan || 'free' },
        projects_synced: projects.length,
        projects: projects.map(p => ({ id: p.project_id, name: p.project_name, url: p.project_url })),
    });
});

// GET /api/v1/lovable/projects?licenseKey=...&deviceId=...
router.get('/projects', async (req, res) => {
    const { licenseKey, deviceId } = req.query;
    console.log(`[Projects] GET /projects - License: ${licenseKey}, Device: ${deviceId}`);

    if (!licenseKey || !deviceId) {
        return res.status(400).json({ error: 'licenseKey and deviceId required' });
    }

    try {
        const [accounts] = await db.execute(
            'SELECT lovable_user_id, lovable_email, lovable_name, workspace_plan FROM lovable_accounts WHERE license_key = ? ORDER BY last_sync_at DESC LIMIT 1',
            [licenseKey]
        );

        console.log(`[Projects] Accounts found: ${accounts.length}`);

        if (!accounts.length) return res.json({ account: null, projects: [] });

        const account = accounts[0];
        const [projects] = await db.execute(
            `SELECT project_id as id, project_name as name, project_url as url, 
                    screenshot_url, status, edit_count, message_count, credit_total, 
                    is_starred, is_published, updated_at 
             FROM lovable_projects 
             WHERE lovable_user_id = ? 
             ORDER BY updated_at DESC`,
            [account.lovable_user_id]
        );

        return res.json({ account, projects });
    } catch (e) {
        console.error('[Projects] CRITICAL ERROR:', e);
        return res.status(500).json({
            error: 'Internal server error during fetching projects',
            details: e.message
        });
    }
});

module.exports = router;
