import React, { useState } from 'react';
import { FileDown, Loader2, Camera, Activity, GraduationCap } from 'lucide-react';
import { TratamentoOrto } from '../types.ts';
import { HybridBackend } from '../services/backend.ts';
import { useToast } from '../contexts/ToastContext.tsx';
import { ORTO_SLOTS } from './OrthoPhotoWorkspace.tsx';

// ─── Helpers ──────────────────────────────────────────────────────

// Converte URL de imagem para base64 DataURL para uso no jsPDF
async function imgToDataUrl(url: string): Promise<string | null> {
  try {
    const res = await fetch(url);
    const blob = await res.blob();
    return await new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = reject;
      reader.readAsDataURL(blob);
    });
  } catch { return null; }
}

// Quebra texto em linhas para jsPDF
function splitText(text: string, maxW: number, charPerW = 2.5): string[] {
  if (!text) return [];
  const words = text.split(' ');
  const maxChars = Math.floor(maxW * charPerW);
  const lines: string[] = [];
  let line = '';
  for (const w of words) {
    if ((line + ' ' + w).length > maxChars && line) { lines.push(line); line = w; }
    else line = line ? `${line} ${w}` : w;
  }
  if (line) lines.push(line);
  return lines;
}

// ─── PDF 1: Documentação Fotográfica ─────────────────────────────

async function gerarPDFDocumentacao(t: TratamentoOrto) {
  const { default: jsPDF } = await import('jspdf');
  const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
  const W = 210, H = 297, M = 12;
  let y = M;

  const accent = [13, 148, 136]; // teal-600 (paleta do login)

  // ── Cabeçalho ──
  doc.setFillColor(...accent as [number, number, number]);
  doc.rect(0, 0, W, 22, 'F');
  doc.setTextColor(255, 255, 255);
  doc.setFontSize(13); doc.setFont('helvetica', 'bold');
  doc.text('DOCUMENTAÇÃO FOTOGRÁFICA ORTODÔNTICA', M, 9);
  doc.setFontSize(8); doc.setFont('helvetica', 'normal');
  doc.text('SCOREODONTO.COM', M, 15);
  doc.text(`Gerado em ${new Date().toLocaleString('pt-BR')}`, W - M, 15, { align: 'right' });
  y = 28;

  // ── Dados do paciente ──
  doc.setTextColor(30, 30, 30);
  doc.setFontSize(11); doc.setFont('helvetica', 'bold');
  doc.text(t.pacienteNome.toUpperCase(), M, y); y += 5;
  doc.setFontSize(8); doc.setFont('helvetica', 'normal');
  doc.setTextColor(100);
  const info = [
    `Aparelho: ${t.tipoAparelho || '—'}`,
    `Início: ${new Date(t.dataInicio).toLocaleDateString('pt-BR')}`,
    `Fase: ${t.faseAtual || '—'}`,
    `Progresso: ${t.percentualConcluido ?? '—'}%`,
    `Status: ${t.status}`,
  ].join('   |   ');
  doc.text(info, M, y); y += 4;
  doc.setDrawColor(...accent as [number, number, number]);
  doc.setLineWidth(0.3);
  doc.line(M, y, W - M, y); y += 6;

  // ── Fotos em grade ──
  const sessoes = await HybridBackend.getOrtoSessoes(t.id);
  const allFotos: Record<string, string> = {};
  for (const s of (sessoes.sessoes || [])) {
    for (const f of (s.fotos || [])) allFotos[f.slot] = f.url;
  }

  const cats = ['EXTRAORAL', 'INTRAORAL', 'COMPLEMENTAR'];
  const COLS = 5;
  const cellW = (W - M * 2 - (COLS - 1) * 3) / COLS;
  const cellH = cellW * 0.75;

  for (const cat of cats) {
    const slots = ORTO_SLOTS.filter(s => s.cat === cat);
    doc.setFontSize(7); doc.setFont('helvetica', 'bold');
    doc.setTextColor(...accent as [number, number, number]);
    doc.text(cat, M, y); y += 4;

    let col = 0;
    let rowY = y;
    for (const slot of slots) {
      const x = M + col * (cellW + 3);
      const url = allFotos[slot.key];
      if (url) {
        const dataUrl = await imgToDataUrl(url);
        if (dataUrl) {
          doc.addImage(dataUrl, 'JPEG', x, rowY, cellW, cellH);
        }
      } else {
        doc.setFillColor(240, 240, 240);
        doc.roundedRect(x, rowY, cellW, cellH, 1, 1, 'F');
        doc.setTextColor(180); doc.setFontSize(5.5);
        doc.text('SEM FOTO', x + cellW / 2, rowY + cellH / 2, { align: 'center' });
      }
      // Label
      doc.setFontSize(5); doc.setFont('helvetica', 'normal'); doc.setTextColor(80);
      doc.text(slot.label, x + cellW / 2, rowY + cellH + 2.5, { align: 'center' });
      col++;
      if (col >= COLS) { col = 0; rowY += cellH + 8; }
    }
    y = rowY + (col > 0 ? cellH + 8 : 0) + 4;

    if (y > H - 30) { doc.addPage(); y = M; }
  }

  // ── Rodapé ──
  doc.setTextColor(150); doc.setFontSize(6);
  doc.text(`SCOREODONTO.COM  ·  ${t.pacienteNome}  ·  Documentação Fotográfica`, W / 2, H - 6, { align: 'center' });

  doc.save(`FOTO_${t.pacienteNome.replace(/\s+/g, '_')}_${new Date().toISOString().slice(0, 10)}.pdf`);
}

// ─── PDF 2: Evolução Ortodôntica ──────────────────────────────────

async function gerarPDFEvolucao(t: TratamentoOrto) {
  const { default: jsPDF } = await import('jspdf');
  const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
  const W = 210, H = 297, M = 14;
  let y = M;

  const accent = [5, 150, 105]; // emerald-600

  doc.setFillColor(...accent as [number, number, number]);
  doc.rect(0, 0, W, 22, 'F');
  doc.setTextColor(255); doc.setFontSize(13); doc.setFont('helvetica', 'bold');
  doc.text('RELATÓRIO DE EVOLUÇÃO ORTODÔNTICA', M, 9);
  doc.setFontSize(8); doc.setFont('helvetica', 'normal');
  doc.text('SCOREODONTO.COM', M, 15);
  doc.text(`Gerado em ${new Date().toLocaleString('pt-BR')}`, W - M, 15, { align: 'right' });
  y = 28;

  doc.setTextColor(30); doc.setFontSize(12); doc.setFont('helvetica', 'bold');
  doc.text(t.pacienteNome, M, y); y += 5;
  doc.setFontSize(8); doc.setFont('helvetica', 'normal'); doc.setTextColor(90);
  doc.text(`${t.tipoAparelho || '—'}  ·  Início: ${new Date(t.dataInicio).toLocaleDateString('pt-BR')}  ·  ${t.percentualConcluido ?? '—'}% concluído  ·  ${t.evolucoes.length} atendimento(s)`, M, y); y += 5;

  // Stats boxes
  const stats = [
    { l: 'ATENDIMENTOS', v: String(t.evolucoes.length) },
    { l: 'FASE ATUAL', v: t.faseAtual || '—' },
    { l: 'FIO ATUAL', v: t.fioAtual || '—' },
    { l: 'MESES REST.', v: t.mesesRestantes ? `${t.mesesRestantes}m` : '—' },
  ];
  const bw = (W - M * 2 - 9) / 4;
  stats.forEach((s, i) => {
    const bx = M + i * (bw + 3);
    doc.setFillColor(240, 253, 244);
    doc.roundedRect(bx, y, bw, 12, 1, 1, 'F');
    doc.setFontSize(9); doc.setFont('helvetica', 'bold'); doc.setTextColor(...accent as [number, number, number]);
    doc.text(s.v, bx + bw / 2, y + 6, { align: 'center' });
    doc.setFontSize(5.5); doc.setFont('helvetica', 'normal'); doc.setTextColor(120);
    doc.text(s.l, bx + bw / 2, y + 10.5, { align: 'center' });
  });
  y += 17;

  doc.setDrawColor(...accent as [number, number, number]); doc.setLineWidth(0.3);
  doc.line(M, y, W - M, y); y += 5;

  // Timeline
  const sorted = [...t.evolucoes].sort((a, b) => new Date(a.data).getTime() - new Date(b.data).getTime());
  for (const [i, ev] of sorted.entries()) {
    if (y > H - 25) { doc.addPage(); y = M; }

    // Número + data
    doc.setFillColor(...accent as [number, number, number]);
    doc.circle(M + 2.5, y + 2.5, 2.5, 'F');
    doc.setTextColor(255); doc.setFontSize(5.5); doc.setFont('helvetica', 'bold');
    doc.text(String(i + 1), M + 2.5, y + 3.2, { align: 'center' });

    const ex = M + 8;
    doc.setTextColor(30); doc.setFontSize(8); doc.setFont('helvetica', 'bold');
    doc.text(`${new Date(ev.data).toLocaleDateString('pt-BR')}  —  ${ev.tipo}`, ex, y + 3);
    y += 5;

    doc.setFontSize(7); doc.setFont('helvetica', 'normal'); doc.setTextColor(60);
    doc.text(ev.procedimento, ex, y + 2);
    y += 5;

    const tags: string[] = [];
    if (ev.fio) tags.push(`Fio: ${ev.fio}`);
    if (ev.elastico) tags.push(`Elástico: ${ev.elastico}`);
    if (ev.higiene != null) tags.push(`Higiene: ${ev.higiene}/10`);
    if (ev.cooperacao) tags.push(`Cooperação: ${ev.cooperacao}`);
    if (ev.procedimentos?.length) tags.push(...ev.procedimentos);
    if (tags.length) {
      doc.setFontSize(6.5); doc.setTextColor(80);
      doc.text(tags.join('  ·  '), ex, y + 2);
      y += 4;
    }
    if (ev.observacoes) {
      doc.setFontSize(6); doc.setTextColor(120); doc.setFont('helvetica', 'italic');
      doc.text(`Obs: ${ev.observacoes}`, ex, y + 2);
      doc.setFont('helvetica', 'normal');
      y += 4;
    }
    doc.setTextColor(180); doc.setFontSize(6);
    doc.text(`Próx. retorno: ${new Date(ev.proximoRetorno).toLocaleDateString('pt-BR')}`, ex, y + 2);
    y += 6;

    if (i < sorted.length - 1) {
      doc.setDrawColor(220); doc.setLineWidth(0.1);
      doc.line(M, y, W - M, y);
      y += 4;
    }
  }

  doc.setTextColor(150); doc.setFontSize(6);
  doc.text(`SCOREODONTO.COM  ·  ${t.pacienteNome}  ·  Evolução Ortodôntica`, W / 2, H - 6, { align: 'center' });
  doc.save(`EVOLUCAO_${t.pacienteNome.replace(/\s+/g, '_')}_${new Date().toISOString().slice(0, 10)}.pdf`);
}

// ─── PDF 3: Caso Clínico para Tutoria ────────────────────────────

async function gerarPDFCasoClinico(t: TratamentoOrto) {
  const { default: jsPDF } = await import('jspdf');
  const doc = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
  const W = 210, H = 297, M = 14;
  let y = M;

  const accent = [13, 148, 136]; // teal-600 (paleta do login)

  doc.setFillColor(...accent as [number, number, number]);
  doc.rect(0, 0, W, 22, 'F');
  doc.setTextColor(255); doc.setFontSize(13); doc.setFont('helvetica', 'bold');
  doc.text('CASO CLÍNICO PARA TUTORIA ORTODÔNTICA', M, 9);
  doc.setFontSize(8); doc.setFont('helvetica', 'normal');
  doc.text('SCOREODONTO.COM  ·  CONFIDENCIAL', M, 15);
  doc.text(`Gerado em ${new Date().toLocaleString('pt-BR')}`, W - M, 15, { align: 'right' });
  y = 28;

  const field = (label: string, value: string | undefined | null) => {
    if (!value) return;
    doc.setFontSize(7); doc.setFont('helvetica', 'bold'); doc.setTextColor(120);
    doc.text(label.toUpperCase(), M, y); y += 3.5;
    doc.setFontSize(8); doc.setFont('helvetica', 'normal'); doc.setTextColor(30);
    const lines = splitText(value, W - M * 2);
    lines.forEach(l => { doc.text(l, M, y); y += 4; });
    y += 1;
  };

  const section = (title: string) => {
    if (y > H - 30) { doc.addPage(); y = M; }
    doc.setFillColor(...accent as [number, number, number]);
    doc.rect(M, y, W - M * 2, 7, 'F');
    doc.setTextColor(255); doc.setFontSize(8); doc.setFont('helvetica', 'bold');
    doc.text(title, M + 3, y + 4.5);
    doc.setTextColor(30);
    y += 10;
  };

  // ── Paciente ──
  section('IDENTIFICAÇÃO DO CASO');
  field('Paciente', t.pacienteNome);
  field('Responsável', t.responsavel);
  field('Aparelho', t.tipoAparelho);
  field('Data de Início', new Date(t.dataInicio).toLocaleDateString('pt-BR'));
  field('Status', t.status);
  field('Fase Atual', t.faseAtual);
  field('Fio Atual', t.fioAtual);
  field('Progresso', t.percentualConcluido != null ? `${t.percentualConcluido}%` : undefined);

  // ── Triagem ──
  if (t.triagem) {
    section('TRIAGEM CLÍNICA');
    field('Queixa Principal', t.triagem.queixaPrincipal);
    field('Histórico Médico', t.triagem.historicoMedico);
    field('Medicação', t.triagem.medicacao);
    field('Alergias', t.triagem.alergias);
    field('Hábitos', t.triagem.habitos);
    if (t.triagem.respiracaoBucal != null)
      field('Respiração Bucal', t.triagem.respiracaoBucal ? 'SIM' : 'NÃO');
  }

  // ── Diagnóstico ──
  if (t.diagnostico) {
    section('DIAGNÓSTICO ORTODÔNTICO');
    field('Classe de Angle', t.diagnostico.classeAngle);
    field('Perfil', t.diagnostico.perfil);
    field('Apinhamento', t.diagnostico.apinhamento);
    field('Mordida', t.diagnostico.mordida);
    field('Linha Média', t.diagnostico.linhaMedia);
  }

  // ── Plano de tratamento ──
  section('PLANO DE TRATAMENTO');
  field('Extrações', t.extracoes);
  field('Elásticos', t.elasticos);
  field('IPR Planejado', t.iprPlanejado);
  field('Tempo Estimado', t.tempoEstimado);
  field('Sequência de Fios', t.sequenciaFios);

  // ── Evoluções (últimas 5) ──
  section('EVOLUÇÕES RECENTES');
  const ultimas = [...t.evolucoes].sort((a, b) => new Date(b.data).getTime() - new Date(a.data).getTime()).slice(0, 5);
  for (const ev of ultimas) {
    if (y > H - 30) { doc.addPage(); y = M; }
    doc.setFontSize(7.5); doc.setFont('helvetica', 'bold'); doc.setTextColor(30);
    doc.text(`${new Date(ev.data).toLocaleDateString('pt-BR')} — ${ev.tipo}`, M, y); y += 4;
    doc.setFontSize(7); doc.setFont('helvetica', 'normal'); doc.setTextColor(60);
    doc.text(ev.procedimento, M + 3, y); y += 4;
    if (ev.fio || ev.cooperacao || ev.higiene != null) {
      const tags = [ev.fio && `Fio: ${ev.fio}`, ev.cooperacao && `Coop: ${ev.cooperacao}`, ev.higiene != null && `Higiene: ${ev.higiene}/10`].filter(Boolean).join('  |  ');
      doc.setTextColor(120); doc.setFontSize(6.5);
      doc.text(tags, M + 3, y); y += 5;
    }
    y += 1;
  }

  // ── Fotos ──
  const sessoes = await HybridBackend.getOrtoSessoes(t.id);
  const fotosIniciais = sessoes.sessoes?.find((s: any) => s.tipo === 'inicial')?.fotos || sessoes.sessoes?.[0]?.fotos || [];
  if (fotosIniciais.length > 0) {
    section('DOCUMENTAÇÃO FOTOGRÁFICA');
    const COLS = 4;
    const cellW = (W - M * 2 - (COLS - 1) * 3) / COLS;
    const cellH = cellW * 0.75;
    let col = 0, rowY = y;
    for (const f of fotosIniciais.slice(0, 12)) {
      if (rowY + cellH > H - 20) { doc.addPage(); rowY = M; col = 0; }
      const x = M + col * (cellW + 3);
      const dataUrl = await imgToDataUrl(f.url);
      if (dataUrl) doc.addImage(dataUrl, 'JPEG', x, rowY, cellW, cellH);
      col++;
      if (col >= COLS) { col = 0; rowY += cellH + 3; }
    }
    y = rowY + (col > 0 ? cellH + 3 : 0) + 5;
  }

  doc.setTextColor(150); doc.setFontSize(6);
  doc.text(`SCOREODONTO.COM  ·  CASO CLÍNICO CONFIDENCIAL  ·  ${t.pacienteNome}`, W / 2, H - 6, { align: 'center' });
  doc.save(`CASO_${t.pacienteNome.replace(/\s+/g, '_')}_${new Date().toISOString().slice(0, 10)}.pdf`);
}

// ─── Componente de botões ─────────────────────────────────────────

interface Props { t: TratamentoOrto; }

export const OrthoReports: React.FC<Props> = ({ t }) => {
  const toast = useToast();
  const [loading, setLoading] = useState<string | null>(null);

  const run = async (tipo: string, fn: () => Promise<void>) => {
    setLoading(tipo);
    try { await fn(); toast.success('PDF GERADO E BAIXADO!'); }
    catch (err) { console.error(err); toast.error('ERRO AO GERAR PDF.'); }
    finally { setLoading(null); }
  };

  const btns = [
    {
      id: 'foto', icon: <Camera size={15} />, label: 'DOCUMENTAÇÃO FOTOGRÁFICA',
      desc: 'Grade completa dos 15 slots com fotos',
      color: 'bg-emerald-600 hover:bg-emerald-700',
      fn: () => gerarPDFDocumentacao(t),
    },
    {
      id: 'evolucao', icon: <Activity size={15} />, label: 'EVOLUÇÃO ORTODÔNTICA',
      desc: 'Timeline cronológico de todos os atendimentos',
      color: 'bg-emerald-600 hover:bg-emerald-700',
      fn: () => gerarPDFEvolucao(t),
    },
    {
      id: 'caso', icon: <GraduationCap size={15} />, label: 'CASO CLÍNICO (TUTORIA)',
      desc: 'Triagem + diagnóstico + plano + evoluções + fotos',
      color: 'bg-violet-600 hover:bg-violet-700',
      fn: () => gerarPDFCasoClinico(t),
    },
  ];

  return (
    <div className="bg-white border border-gray-200 rounded-xl shadow-sm overflow-hidden">
      <div className="px-5 py-4 border-b border-gray-100 bg-gray-50 flex items-center gap-2">
        <FileDown size={16} className="text-teal-500" />
        <h3 className="font-black text-gray-700 uppercase text-sm">RELATÓRIOS E PDFs</h3>
      </div>
      <div className="p-5 grid grid-cols-1 sm:grid-cols-3 gap-3">
        {btns.map(b => (
          <button key={b.id} onClick={() => run(b.id, b.fn)} disabled={!!loading}
            className={`flex flex-col items-center gap-2 p-4 rounded-xl text-white transition-all disabled:opacity-50 ${b.color} shadow-sm`}>
            {loading === b.id
              ? <Loader2 size={20} className="animate-spin" />
              : b.icon}
            <span className="text-[10px] font-black uppercase leading-tight text-center">{b.label}</span>
            <span className="text-[9px] font-medium opacity-70 text-center leading-tight">{b.desc}</span>
          </button>
        ))}
      </div>
      <p className="px-5 pb-4 text-[10px] text-gray-400 font-bold uppercase text-center">
        PDFs GERADOS LOCALMENTE — NENHUM DADO É ENVIADO PARA SERVIDORES EXTERNOS
      </p>
    </div>
  );
};
