import { join } from 'path';
import { rmSync } from 'node:fs';
import { Client, LocalAuth } from 'whatsapp-web.js';
import { getServerIntegration, upsertServerIntegration } from 'officerdb';
import { DATA_PATH } from '@@/data-path';
import { handleWhatsAppMessage } from './handler';

let client: Client | null = null;
let currentQR: string | null = null;
let clientReady = false;

type QRListener = (qr: string | null, event: 'qr' | 'authenticated' | 'disconnected') => void;
const qrListeners = new Set<QRListener>();

export async function startWhatsAppBot(): Promise<void> {
  if (client) {
    await stopWhatsAppBot();
  }

  clientReady = false;
  currentQR = null;

  client = new Client({
    authStrategy: new LocalAuth({ dataPath: join(DATA_PATH, '.wwebjs_auth') }),
    puppeteer: {
      headless: true,
      args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu'],
    },
  });

  client.on('qr', (qr) => {
    currentQR = qr;
    for (const listener of qrListeners) {
      listener(qr, 'qr');
    }
    console.log('[whatsapp] QR code received — scan with your phone');
  });

  client.on('ready', () => {
    clientReady = true;
    currentQR = null;
    for (const listener of qrListeners) {
      listener(null, 'authenticated');
    }
    const phone = client?.info?.wid?.user ?? 'unknown';
    console.log(`[whatsapp] Bot ready — phone: ${phone}`);
  });

  client.on('authenticated', () => {
    console.log('[whatsapp] Authenticated');
  });

  client.on('auth_failure', (msg) => {
    console.error('[whatsapp] Auth failure:', msg);
  });

  client.on('disconnected', (reason) => {
    clientReady = false;
    currentQR = null;
    for (const listener of qrListeners) {
      listener(null, 'disconnected');
    }
    console.log('[whatsapp] Disconnected:', reason);
  });

  client.on('message', (msg) => {
    handleWhatsAppMessage(msg).catch((err) => {
      console.error('[whatsapp] Unhandled error in message handler:', err);
    });
  });

  await client.initialize();
}

export async function stopWhatsAppBot(): Promise<void> {
  if (client) {
    try {
      await client.destroy();
    } catch {
      // May fail if not connected
    }
    client = null;
    clientReady = false;
    currentQR = null;
    console.log('[whatsapp] Bot stopped');
  }
}

export function isWhatsAppBotRunning(): boolean {
  return client !== null && clientReady;
}

export function getWhatsAppBotPhone(): string | null {
  if (!client || !clientReady) return null;
  return client.info?.wid?.user ?? null;
}

export function getWhatsAppQR(): string | null {
  return currentQR;
}

export function subscribeQR(listener: QRListener): () => void {
  qrListeners.add(listener);
  return () => {
    qrListeners.delete(listener);
  };
}

export function getWhatsAppClient(): Client | null {
  return client;
}

export async function startWhatsAppBotIfConfigured(): Promise<void> {
  const integration = await getServerIntegration('whatsapp');
  if (!integration?.enabled) return;

  await startWhatsAppBot();
}

export async function disconnectWhatsApp(): Promise<void> {
  if (client) {
    try {
      await client.logout();
    } catch {
      // May fail if not authenticated
    }
  }
  await stopWhatsAppBot();

  // Remove cached session so a new QR is shown on next connect
  const authPath = join(DATA_PATH, '.wwebjs_auth');
  rmSync(authPath, { recursive: true, force: true });

  await upsertServerIntegration('whatsapp', {}, false);
}
