const { Client, LocalAuth, MessageMedia } = require('whatsapp-web.js');
const qrcode = require('qrcode-terminal');
const express = require('express');
const bodyParser = require('body-parser');
const winston = require('winston');
const cors = require('cors');
const fs = require('fs');
const path = require('path');

// Setup Logger
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
    new winston.transports.Console({ format: winston.format.simple() })
  ],
});

// Setup Express
const app = express();
const port = process.env.PORT || 3000;
app.use(cors()); // Allow CORS for local development/admin panel
app.use(bodyParser.json());

// Setup WhatsApp Client
const client = new Client({
  authStrategy: new LocalAuth(),
  puppeteer: {
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
    headless: true,
    executablePath: process.env.CHROME_BIN || undefined // Use system Chrome if available
  }
});

let isReady = false;
let qrCodeData = null;
let connectionStatus = 'disconnected'; // disconnected, connecting, connected

client.on('qr', (qr) => {
  logger.info('QR Code received, please scan!');
  qrcode.generate(qr, { small: true });
  qrCodeData = qr;
  connectionStatus = 'scan_qr';
});

client.on('ready', () => {
  isReady = true;
  qrCodeData = null;
  connectionStatus = 'connected';
  logger.info('WhatsApp Client is ready!');
});

client.on('auth_failure', (msg) => {
  logger.error('Authentication failure:', msg);
  connectionStatus = 'auth_failure';
  isReady = false;
});

client.on('disconnected', (reason) => {
  isReady = false;
  qrCodeData = null;
  connectionStatus = 'disconnected';
  logger.warn('Client was logged out:', reason);
  // Reinitialize client after disconnect if needed
  client.initialize();
});

client.initialize();
connectionStatus = 'connecting';

// Helper function to format phone number
const formatPhoneNumber = (number) => {
  let formatted = number.replace(/\D/g, '');
  if (formatted.startsWith('0')) {
    formatted = '62' + formatted.slice(1);
  }
  if (!formatted.endsWith('@c.us')) {
    formatted += '@c.us';
  }
  return formatted;
};

// API Endpoint to check status
app.get('/status', (req, res) => {
    res.json({ 
        status: connectionStatus, 
        isReady: isReady,
        qr: qrCodeData 
    });
});

// API Endpoint to logout
app.post('/logout', async (req, res) => {
    try {
        await client.logout();
        res.json({ status: 'success', message: 'Logged out successfully' });
    } catch (error) {
        res.status(500).json({ status: 'error', message: 'Failed to logout', error: error.message });
    }
});

// API Endpoint to restart/initialize
app.post('/restart', async (req, res) => {
    try {
        await client.destroy();
        await client.initialize();
        res.json({ status: 'success', message: 'Client restarting...' });
    } catch (error) {
        res.status(500).json({ status: 'error', message: 'Failed to restart', error: error.message });
    }
});

// API Endpoint to send message with media
app.post('/send-media', async (req, res) => {
    if (!isReady) {
        return res.status(503).json({ status: 'error', message: 'WhatsApp client is not ready' });
    }

    const { number, message, filePath } = req.body;

    if (!number || !filePath) {
        return res.status(400).json({ status: 'error', message: 'Number and filePath are required' });
    }

    const chatId = formatPhoneNumber(number);

    try {
        // Check if the number is registered on WhatsApp
        // const isRegistered = await client.isRegisteredUser(chatId);
        // if (!isRegistered) {
        //     logger.warn(`Number not registered: ${number}`);
        //     return res.status(404).json({ status: 'error', message: 'Number is not registered on WhatsApp' });
        // }

        // Check if file exists
        if (!fs.existsSync(filePath)) {
            logger.error(`File not found: ${filePath}`);
            // Fallback to text message if file not found
            await client.sendMessage(chatId, message + "\n\n(Note: Lampiran foto tidak ditemukan)");
            return res.json({ status: 'warning', message: 'File not found, sent as text only' });
        }

        const media = MessageMedia.fromFilePath(filePath);
        await client.sendMessage(chatId, media, { caption: message });
        
        logger.info(`Media message sent to ${number}`);
        res.json({ status: 'success', message: 'Media sent successfully' });
    } catch (error) {
        logger.error(`Failed to send media to ${number}:`, error);
        res.status(500).json({ status: 'error', message: 'Failed to send media', error: error.message });
    }
});

// API Endpoint to send message
app.post('/send-message', async (req, res) => {
  if (!isReady) {
    return res.status(503).json({ status: 'error', message: 'WhatsApp client is not ready' });
  }

  const { number, message } = req.body;

  if (!number || !message) {
    return res.status(400).json({ status: 'error', message: 'Number and message are required' });
  }

  const chatId = formatPhoneNumber(number);

  try {
    // Check if the number is registered on WhatsApp
    // const isRegistered = await client.isRegisteredUser(chatId);
    // if (!isRegistered) {
    //     logger.warn(`Number not registered: ${number}`);
    //     return res.status(404).json({ status: 'error', message: 'Number is not registered on WhatsApp' });
    // }

    await client.sendMessage(chatId, message);
    logger.info(`Message sent to ${number}`);
    res.json({ status: 'success', message: 'Message sent successfully' });
  } catch (error) {
    logger.error(`Failed to send message to ${number}:`, error);
    res.status(500).json({ status: 'error', message: 'Failed to send message', error: error.message });
  }
});

app.listen(port, () => {
  logger.info(`WhatsApp Gateway running at http://localhost:${port}`);
});
