import { join }       from 'path';
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync } from 'fs';
import { createRequire } from 'module';
import fetch from 'node-fetch';
import { syncWrite, syncWritePdf } from './sync.js';

const require     = createRequire(import.meta.url);
const PDFDocument = require('pdfkit');

// ── CV storage helpers ────────────────────────────────────────────────────────

export function menteeDir(botDir, slug) {
  return join(botDir, 'mentees', slug);
}

export function saveCvFile(botDir, slug, cvType, ext, buffer) {
  const dir = menteeDir(botDir, slug);
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  writeFileSync(join(dir, `${cvType}.${ext}`), buffer);
}

export function saveCvText(botDir, slug, cvType, text) {
  const dir = menteeDir(botDir, slug);
  if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
  writeFileSync(join(dir, `${cvType}.txt`), text, 'utf8');
}

export function hasCv(botDir, slug, cvType) {
  const dir = menteeDir(botDir, slug);
  if (!existsSync(dir)) return false;
  return readdirSync(dir).some(f => f.startsWith(cvType + '.'));
}

export function readCvText(botDir, slug, cvType) {
  const txtPath = join(menteeDir(botDir, slug), `${cvType}.txt`);
  return existsSync(txtPath) ? readFileSync(txtPath, 'utf8') : '';
}

// ── Group registry ────────────────────────────────────────────────────────────

export function groupExistsForLead(botDir, leadId) {
  // Check local mirror of group.json across all mentee dirs
  const menteesDir = join(botDir, 'mentees');
  if (!existsSync(menteesDir)) return null;
  for (const slug of readdirSync(menteesDir)) {
    const gp = join(menteesDir, slug, 'group.json');
    if (!existsSync(gp)) continue;
    try {
      const g = JSON.parse(readFileSync(gp, 'utf8'));
      if (String(g.leadId) === String(leadId)) return g;
    } catch { /* skip */ }
  }
  return null;
}

// ── AI call (OpenAI) ──────────────────────────────────────────────────────────

async function aiRaw(prompt) {
  const res = await fetch('https://api.anthropic.com/v1/messages', {
    method: 'POST',
    headers: {
      'x-api-key': process.env.ANTHROPIC_API_KEY,
      'anthropic-version': '2023-06-01',
      'content-type': 'application/json',
    },
    body: JSON.stringify({
      model: 'claude-sonnet-4-5',
      max_tokens: 3000,
      messages: [{ role: 'user', content: prompt }],
    }),
    signal: AbortSignal.timeout(90000),
  });
  const data = await res.json();
  if (!res.ok || data.type === 'error') throw new Error(data.error?.message || 'AI error');
  return (data.content || []).filter(b => b.type === 'text').map(b => b.text).join('').trim();
}

// ── Language detection from phone prefix ─────────────────────────────────────

function detectLangFromPhone(phone) {
  if (!phone) return 'English';
  const digits = phone.replace(/\D/g, '');
  if (digits.startsWith('55') || digits.startsWith('351')) return 'Portuguese';
  if (digits.startsWith('34') || digits.startsWith('52') || digits.startsWith('54') ||
      digits.startsWith('56') || digits.startsWith('57') || digits.startsWith('58') ||
      digits.startsWith('51') || digits.startsWith('591') || digits.startsWith('595') ||
      digits.startsWith('593') || digits.startsWith('598')) return 'Spanish';
  if (digits.startsWith('33')) return 'French';
  return 'English';
}

// ── Report generation ─────────────────────────────────────────────────────────

async function generateReportText(leadInfo, cvTexts, lang) {
  const prompt = `You are a career analyst at Ecobe. Based on the information below, write a professional and detailed report about the client so the coach has an excellent first impression.

The report should cover:
- General profile and personal presentation
- Relevant professional experience
- Identified competencies and skills
- Career goals and ambitions
- Notes on LinkedIn vs personal CV (if differences exist)
- Initial coaching recommendations

CLIENT PROFILE:
Name: ${leadInfo.name}
Email: ${leadInfo.email || 'N/A'}
Phone: ${leadInfo.phone || 'N/A'}
Description: ${leadInfo.description || 'N/A'}

DOCUMENT CONTENT:
${cvTexts || '(no documents available)'}

Write in ${lang}. Be detailed, professional and insightful. Use sections with clear titles (markdown ## ).`;

  return aiRaw(prompt);
}

function buildReportPDF(reportText, clientName) {
  return new Promise((resolve, reject) => {
    const doc    = new PDFDocument({ margin: 50 });
    const chunks = [];
    doc.on('data',  c => chunks.push(c));
    doc.on('end',   () => resolve(Buffer.concat(chunks)));
    doc.on('error', reject);

    doc.fontSize(20).font('Helvetica-Bold').text('ECOBE — Client Report', { align: 'center' });
    doc.moveDown(0.5);
    doc.fontSize(14).font('Helvetica').text(clientName, { align: 'center' });
    doc.moveDown(0.3);
    doc.fontSize(10).text(
      new Date().toLocaleDateString('en-GB', { day: '2-digit', month: 'long', year: 'numeric' }),
      { align: 'center' }
    );
    doc.moveDown(1);
    doc.moveTo(50, doc.y).lineTo(545, doc.y).stroke();
    doc.moveDown(1);

    for (const line of reportText.split('\n')) {
      const t = line.trim();
      if (!t) { doc.moveDown(0.4); continue; }
      const isTitle = /^#{1,3}\s/.test(t) || /^\*{2}[^*]+\*{2}$/.test(t);
      if (isTitle) {
        doc.moveDown(0.6).fontSize(12).font('Helvetica-Bold')
          .text(t.replace(/^#{1,3}\s*|\*\*/g, '')).moveDown(0.2);
      } else {
        doc.fontSize(10).font('Helvetica').text(t, { lineGap: 3 });
      }
    }
    doc.end();
  });
}

// ── Main: generate report + create WA group ───────────────────────────────────

const GROUP_CREATED_MSG = {
  'Portuguese': (name, link) => `Grupo criado: *${name}*\n🔗 ${link}\n\n⚠️ Peça ao cliente para guardar o número do bot na agenda antes de entrar no grupo.`,
  'Spanish':    (name, link) => `Grupo creado: *${name}*\n🔗 ${link}\n\n⚠️ Pide al cliente que guarde el número del bot en su agenda antes de unirse al grupo.`,
  'French':     (name, link) => `Groupe créé : *${name}*\n🔗 ${link}\n\n⚠️ Demandez au client d'enregistrer le numéro du bot dans ses contacts avant de rejoindre le groupe.`,
  'English':    (name, link) => `Group created: *${name}*\n🔗 ${link}\n\n⚠️ Ask the client to save the bot's number in their contacts before joining the group.`,
};

export async function generateAndSendReport(sock, jid, botDir, pending) {
  const { leadId, leadName, slug, email, phone, description } = pending;

  const lang = detectLangFromPhone(phone);

  // 1. Assemble CV texts (up to 3 000 chars each to stay within token limits)
  const cvPersonal = readCvText(botDir, slug, 'cv-personal');
  const cvLinkedin = readCvText(botDir, slug, 'cv-linkedin');
  const cvTexts = [
    cvPersonal ? `=== Personal CV ===\n${cvPersonal.slice(0, 3000)}` : '',
    cvLinkedin ? `=== LinkedIn CV ===\n${cvLinkedin.slice(0, 3000)}` : '',
  ].filter(Boolean).join('\n\n');

  // 2. Generate report text via AI
  const reportText = await generateReportText(
    { name: leadName, email, phone, description },
    cvTexts,
    lang
  );
  if (!reportText) throw new Error('Empty report');

  // 3. Send report as text
  await sock.sendMessage(jid, { text: `📋 *Report — ${leadName}*\n\n${reportText}` });

  // 4. Build PDF, sync (API + local), send as document
  const pdfBuffer = await buildReportPDF(reportText, leadName);
  await syncWritePdf(botDir, slug, pdfBuffer);
  await sock.sendMessage(jid, {
    document: pdfBuffer,
    mimetype: 'application/pdf',
    fileName: `${slug}_report.pdf`,
  });

  // 5. Create WhatsApp group (skip if already exists)
  if (groupExistsForLead(botDir, leadId)) return;

  const groupName  = `Ecobe | ${leadName}`;
  const group      = await sock.groupCreate(groupName, []);
  const groupJid   = group?.id || group?.gid;
  if (!groupJid) throw new Error('groupCreate did not return id');

  const inviteCode = await sock.groupInviteCode(groupJid).catch(() => null);
  const inviteLink = inviteCode ? `https://chat.whatsapp.com/${inviteCode}` : '(link unavailable)';

  const groupData = {
    leadId, leadName, leadSlug: slug, groupJid, inviteLink,
    phase: 'onboarding', createdAt: new Date().toISOString(),
  };
  await syncWrite(botDir, slug, 'group', groupData);

  const notifFn = GROUP_CREATED_MSG[lang] || GROUP_CREATED_MSG['English'];
  await sock.sendMessage(jid, { text: notifFn(groupName, inviteLink) });
}
