const axios = require('axios');
const crypto = require('crypto');

const LOVABLE_API_BASE = 'https://api.lovable.dev';

// Crockford base32 alphabet (used by TypeID spec)
const TYPEID_ALPHABET = '0123456789abcdefghjkmnpqrstvwxyz';

/**
 * Gera um TypeID válido (UUIDv7 + Crockford base32)
 * Formato: {prefix}_{26chars}
 * Ex: umsg_01khxk417fe07ayzf1ng7knnn5
 */
function generateTypeId(prefix) {
    const now = Date.now();
    const bytes = Buffer.alloc(16);

    // 48 bits de timestamp (ms)
    bytes[0] = Math.floor(now / 0x10000000000) & 0xff;
    bytes[1] = Math.floor(now / 0x100000000) & 0xff;
    bytes[2] = Math.floor(now / 0x1000000) & 0xff;
    bytes[3] = Math.floor(now / 0x10000) & 0xff;
    bytes[4] = Math.floor(now / 0x100) & 0xff;
    bytes[5] = now & 0xff;

    // Version 7 (bits 48-51)
    const rand = crypto.randomBytes(10);
    bytes[6] = 0x70 | (rand[0] & 0x0f);
    bytes[7] = rand[1];

    // Variant 10xx (bits 64-65)
    bytes[8] = 0x80 | (rand[2] & 0x3f);

    // Random bits (bytes 9-15)
    rand.copy(bytes, 9, 3, 10);

    // Codifica 16 bytes (128 bits) em 26 chars Crockford base32
    let n = BigInt('0x' + bytes.toString('hex'));
    const chars = new Array(26);
    for (let i = 25; i >= 0; i--) {
        chars[i] = TYPEID_ALPHABET[Number(n & 31n)];
        n >>= 5n;
    }
    return prefix + '_' + chars.join('');
}

/**
 * Busca os detalhes do projeto para obter o latest_commit_sha
 */
async function getProjectDetails(projectId, token) {
    try {
        const response = await axios.get(
            `${LOVABLE_API_BASE}/projects/${projectId}/details`,
            {
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Accept': 'application/json',
                    'Origin': 'https://lovable.dev',
                    'Referer': `https://lovable.dev/projects/${projectId}`,
                },
                timeout: 10000,
            }
        );
        return response.data?.latest_commit_sha || null;
    } catch (err) {
        console.warn(`⚠️ Não foi possível buscar details: ${err.message}`);
        return null;
    }
}

/**
 * Envia uma mensagem para o projeto no Lovable.dev
 */
async function sendMessage(projectId, token, sessionId, message) {
    try {
        console.log(`📤 Enviando para Lovable API...`);
        console.log(`   Project: ${projectId}`);
        console.log(`   Message: ${message.substring(0, 80)}...`);

        // Busca o commit SHA necessário para o header x-client-git-sha
        const commitSha = await getProjectDetails(projectId, token);
        console.log(`   Commit SHA: ${commitSha || '(não encontrado)'}`);

        const msgId = generateTypeId('umsg');
        const aiMsgId = generateTypeId('aimsg');

        const headers = {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json',
            'Accept': '*/*',
            'Origin': 'https://lovable.dev',
            'Referer': `https://lovable.dev/projects/${projectId}`,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36',
        };

        if (commitSha) {
            headers['x-client-git-sha'] = commitSha;
        }

        // Body exato que o Lovable.dev envia (descoberto via intercepção do fetch)
        const body = {
            id: msgId,
            message: message,
            files: [],
            selected_elements: [],
            chat_only: true,
            debug_mode: false,
            view: 'chat',
            view_description: 'The user is sending a message via API.',
            optimisticImageUrls: [],
            ai_message_id: aiMsgId,
            thread_id: 'main',
            current_page: '/',
            model: null,
            session_replay: null,
        };

        console.log(`   Body: ${JSON.stringify({ id: msgId, message: message.substring(0, 40) })}`);

        const response = await axios.post(
            `${LOVABLE_API_BASE}/projects/${projectId}/chat`,
            body,
            {
                headers,
                timeout: 120000, // 2 minutos — a IA pode demorar
                responseType: 'text', // SSE/streaming retorna texto
            }
        );

        console.log(`✅ Resposta do Lovable: ${response.status}`);
        const rawData = String(response.data);
        console.log(`   Preview: ${rawData.substring(0, 300)}`);

        // Tenta extrair a mensagem do SSE stream
        const reply = parseSSEResponse(rawData);

        return {
            success: true,
            data: response.data,
            reply: reply,
            status: response.status
        };

    } catch (err) {
        console.error(`❌ Erro ao chamar Lovable API: ${err.message}`);
        if (err.response) {
            console.error(`   Status: ${err.response.status}`);
            console.error(`   Body:`, JSON.stringify(err.response.data, null, 2));
            return {
                success: false,
                error: `Lovable API retornou ${err.response.status}: ${JSON.stringify(err.response.data)}`,
                status: err.response.status,
                data: err.response.data
            };
        }
        return { success: false, error: err.message };
    }
}

/**
 * Tenta extrair a resposta de texto de um SSE stream do Lovable
 * O formato típico é: data: {"type":"text","content":"..."}\n\n
 */
function parseSSEResponse(raw) {
    try {
        const lines = raw.split('\n');
        let fullText = '';

        for (const line of lines) {
            if (!line.startsWith('data:')) continue;
            const jsonStr = line.replace(/^data:\s*/, '').trim();
            if (!jsonStr || jsonStr === '[DONE]') continue;

            try {
                const parsed = JSON.parse(jsonStr);
                // Tenta vários campos comuns no SSE do Lovable
                if (parsed.content) fullText += parsed.content;
                else if (parsed.text) fullText += parsed.text;
                else if (parsed.delta?.text) fullText += parsed.delta.text;
                else if (parsed.message) fullText += parsed.message;
            } catch (e) {
                // Linha não é JSON válido, ignora
            }
        }

        return fullText || raw.substring(0, 500);
    } catch (e) {
        return raw.substring(0, 500);
    }
}

module.exports = { sendMessage };
