const express = require('express');
const cors = require('cors');
const QRCode = require('qrcode');
const axios = require('axios');
const path = require('path');
const fs = require('fs');
const pino = require('pino');
const {
    default: makeWASocket,
    useMultiFileAuthState,
    DisconnectReason,
    fetchLatestBaileysVersion,
    delay
} = require('@whiskeysockets/baileys');

const app = express();
const PORT = process.env.PORT || 3000;
const WEBHOOK_URL = process.env.WEBHOOK_URL || 'http://localhost:8000/webhook';
const AUTH_DIR = path.join(__dirname, 'auth_info_baileys');

app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

let sock = null;
let currentQR = null;
let currentQRImage = null;
let connectionStatus = 'initializing'; // 'qr_ready', 'connecting', 'connected', 'disconnected'
let connectedUser = null;

// Initialize WhatsApp Baileys Socket
async function connectToWhatsApp() {
    connectionStatus = 'connecting';
    const { state, saveCreds } = await useMultiFileAuthState(AUTH_DIR);
    const { version, isLatest } = await fetchLatestBaileysVersion();

    console.log(`[WhatsApp Engine] Starting Baileys version ${version.join('.')} (Latest: ${isLatest})`);

    sock = makeWASocket({
        version,
        logger: pino({ level: 'silent' }),
        printQRInTerminal: true,
        auth: state,
        browser: ['WhatsApp CRM', 'Chrome', '120.0.0']
    });

    sock.ev.on('creds.update', saveCreds);

    sock.ev.on('connection.update', async (update) => {
        const { connection, lastDisconnect, qr } = update;

        if (qr) {
            currentQR = qr;
            connectionStatus = 'qr_ready';
            try {
                currentQRImage = await QRCode.toDataURL(qr);
                console.log('[WhatsApp Engine] New QR code generated. Scan from your phone.');
            } catch (err) {
                console.error('[WhatsApp Engine] QR Generation error:', err);
            }
        }

        if (connection === 'close') {
            const shouldReconnect = (lastDisconnect?.error)?.output?.statusCode !== DisconnectReason.loggedOut;
            console.log(`[WhatsApp Engine] Connection closed due to: ${lastDisconnect?.error?.message}. Reconnecting: ${shouldReconnect}`);
            
            connectedUser = null;
            currentQR = null;
            currentQRImage = null;
            connectionStatus = 'disconnected';

            if (shouldReconnect) {
                setTimeout(connectToWhatsApp, 3000);
            } else {
                console.log('[WhatsApp Engine] Logged out. Clearing credentials...');
                if (fs.existsSync(AUTH_DIR)) {
                    fs.rmSync(AUTH_DIR, { recursive: true, force: true });
                }
                setTimeout(connectToWhatsApp, 3000);
            }
        } else if (connection === 'open') {
            connectionStatus = 'connected';
            currentQR = null;
            currentQRImage = null;
            connectedUser = sock.user;
            console.log(`[WhatsApp Engine] ✅ Connected successfully as: ${sock.user?.id || 'User'}`);
        }
    });

    // Handle Incoming Messages & Forward to CRM Webhook
    sock.ev.on('messages.upsert', async ({ messages, type }) => {
        if (type !== 'notify') return;

        for (const msg of messages) {
            if (!msg.message || msg.key.fromMe) continue;

            const fromJid = msg.key.remoteJid;
            if (fromJid.endsWith('@g.us')) continue; // Skip group messages if personal CRM

            const senderPhone = fromJid.replace('@s.whatsapp.net', '').replace('@c.us', '');
            const pushName = msg.pushName || 'WhatsApp User';
            const messageId = msg.key.id;

            let textBody = '';
            let msgType = 'text';
            let mediaUrl = null;

            if (msg.message.conversation) {
                textBody = msg.message.conversation;
            } else if (msg.message.extendedTextMessage?.text) {
                textBody = msg.message.extendedTextMessage.text;
            } else if (msg.message.imageMessage) {
                msgType = 'image';
                textBody = msg.message.imageMessage.caption || '[Photo]';
            } else if (msg.message.documentMessage) {
                msgType = 'document';
                textBody = msg.message.documentMessage.fileName || '[Document]';
            } else if (msg.message.audioMessage) {
                msgType = 'audio';
                textBody = '[Voice Note]';
            }

            console.log(`[WhatsApp Engine] Incoming message from +${senderPhone} (${pushName}): ${textBody}`);

            // Forward to CRM Webhook
            try {
                await axios.post(WEBHOOK_URL, {
                    event_type: 'message_received',
                    data: {
                        id: messageId,
                        from: senderPhone,
                        pushname: pushName,
                        body: textBody,
                        type: msgType,
                        media: mediaUrl,
                        fromMe: false,
                        time: Math.floor(Date.now() / 1000)
                    }
                }, {
                    headers: { 'Content-Type': 'application/json' },
                    timeout: 10000
                });
            } catch (webhookErr) {
                console.error(`[WhatsApp Engine] Failed to forward message to CRM Webhook (${WEBHOOK_URL}):`, webhookErr.message);
            }
        }
    });
}

// REST API Endpoints for CRM Integration

// 1. Connection Status & QR code
app.get('/status', (req, res) => {
    res.json({
        success: true,
        status: connectionStatus,
        is_connected: (connectionStatus === 'connected'),
        user: connectedUser ? {
            id: connectedUser.id,
            name: connectedUser.name || 'WhatsApp User',
            phone: (connectedUser.id || '').split(':')[0]
        } : null,
        qr_image: currentQRImage
    });
});

// 2. Send Text Message
app.post('/send-text', async (req, res) => {
    try {
        const { to, message } = req.body;
        if (!to || !message) {
            return res.status(400).json({ success: false, error: 'Recipient "to" and "message" are required.' });
        }

        if (connectionStatus !== 'connected' || !sock) {
            return res.status(503).json({ success: false, error: 'WhatsApp is not connected. Please scan QR code first.' });
        }

        const cleanNumber = to.replace(/[^0-9]/g, '');
        const jid = `${cleanNumber}@s.whatsapp.net`;

        const sent = await sock.sendMessage(jid, { text: message });

        return res.json({
            success: true,
            id: sent.key.id,
            status: 'sent'
        });
    } catch (err) {
        console.error('[WhatsApp Engine] Error sending text:', err);
        return res.status(500).json({ success: false, error: err.message });
    }
});

// 3. Send Media Message
app.post('/send-media', async (req, res) => {
    try {
        const { to, mediaUrl, type, caption, filename } = req.body;
        if (!to || !mediaUrl) {
            return res.status(400).json({ success: false, error: 'Recipient "to" and "mediaUrl" are required.' });
        }

        if (connectionStatus !== 'connected' || !sock) {
            return res.status(503).json({ success: false, error: 'WhatsApp is not connected. Please scan QR code first.' });
        }

        const cleanNumber = to.replace(/[^0-9]/g, '');
        const jid = `${cleanNumber}@s.whatsapp.net`;

        let mediaPayload = {};
        if (type === 'image') {
            mediaPayload = { image: { url: mediaUrl }, caption: caption || '' };
        } else if (type === 'document') {
            mediaPayload = { document: { url: mediaUrl }, fileName: filename || 'document.pdf', caption: caption || '' };
        } else if (type === 'audio') {
            mediaPayload = { audio: { url: mediaUrl }, mimetype: 'audio/mp4' };
        } else {
            mediaPayload = { image: { url: mediaUrl }, caption: caption || '' };
        }

        const sent = await sock.sendMessage(jid, mediaPayload);

        return res.json({
            success: true,
            id: sent.key.id,
            status: 'sent'
        });
    } catch (err) {
        console.error('[WhatsApp Engine] Error sending media:', err);
        return res.status(500).json({ success: false, error: err.message });
    }
});

// 4. Logout / Reset Session
app.post('/logout', async (req, res) => {
    try {
        if (sock) {
            await sock.logout();
        }
        if (fs.existsSync(AUTH_DIR)) {
            fs.rmSync(AUTH_DIR, { recursive: true, force: true });
        }
        setTimeout(connectToWhatsApp, 1000);
        return res.json({ success: true, message: 'Logged out. Generating new QR code.' });
    } catch (err) {
        return res.status(500).json({ success: false, error: err.message });
    }
});

// Start Server & Connect
app.listen(PORT, () => {
    console.log(`=======================================================`);
    console.log(` [WhatsApp Web QR Engine] Running on port ${PORT}`);
    console.log(` Forwarding webhooks to: ${WEBHOOK_URL}`);
    console.log(`=======================================================`);
    connectToWhatsApp();
});
