/* ============================================================
   EDUCARE — Plano de intervenção gerado por IA

   O QUE ISTO SUBSTITUI: até aqui o "Planejamento com IA" anunciado no
   painel era um template. genPlan() escolhia atividades de uma lista
   fixa por índice e costurava frases; a tela de "gerando…" era espera
   encenada. O mesmo plano saía para crianças diferentes, e a
   profissional acabava indo fazer o plano num chat de IA por fora, com
   o laudo do neuro na mão — e o resultado não voltava para o prontuário.

   O QUE A IA RECEBE: o que o sistema já sabe da criança (identificação,
   queixa, anamnese, avaliações aplicadas com escores e pareceres) e,
   quando a profissional escolhe, UM DOCUMENTO do prontuário — o laudo
   do neuropediatra, o relatório da escola. O documento vai como arquivo
   de verdade, não como texto colado: o Claude lê PDF nativamente.

   O QUE VOLTA: JSON com forma garantida pelo schema da Edge Function.
   O plano é salvo em plans, ligado ao paciente — que era o ponto: "eu
   queria que ficasse lá, porque depois, quando eu pedisse um relatório
   dessa criança, ia juntar tudo".
   ============================================================ */
(function () {
  const { useState, useEffect } = React;

  // O que o Claude consegue ler como arquivo. Um .docx anexado continua
  // valendo no prontuário, mas não pode ser mandado para a IA.
  const LEGIVEIS = ["application/pdf", "image/jpeg", "image/png", "image/webp"];
  const legivel = (mime) => LEGIVEIS.indexOf(mime) > -1;

  /* Blob → base64 sem prefixo data:. Via FileReader porque
     String.fromCharCode(...bytes) estoura a pilha em arquivo grande —
     um laudo de 3 MB são 3 milhões de argumentos numa chamada só. */
  function paraBase64(blob) {
    return new Promise((ok, falha) => {
      const fr = new FileReader();
      fr.onerror = () => falha(new Error("Não foi possível ler o documento."));
      fr.onloadend = () => {
        const s = String(fr.result || "");
        const virgula = s.indexOf(",");
        ok(virgula > -1 ? s.slice(virgula + 1) : s);
      };
      fr.readAsDataURL(blob);
    });
  }

  /* Contexto da criança. Só entra o que existe: campo vazio ou "—" não
     vira linha, porque a IA é instruída a não supor o que não recebeu —
     mandar "escola: —" convida a inventar. */
  function contextoDoPaciente(pid) {
    const p = (window.PATIENTS || []).find((x) => x.id === pid);
    if (!p) throw new Error("Paciente não encontrado.");
    const vivo = (v) => (v && v !== "—" ? v : null);

    const fichas = (window.ASSESSMENTS[pid] || []).filter((a) => a.status === "done");
    const avaliacoes = fichas.map((a) => ({
      nome: a.name,
      data: a.date,
      resultado: a.result,
      parecer: a.note || null,
      ficha: a.sheet || null,
    }));

    const anamnese = fichas
      .filter((a) => a.sheet && a.sheet.kind === "anamnese-infantil" && a.sheet.values)
      .map((a) => (window.EducareAnamneseInfantil
        ? window.EducareAnamneseInfantil.paraExibicao(a.sheet.values)
        : null))
      .filter(Boolean)[0] || null;

    return {
      paciente: {
        primeiro_nome: (p.name || "").split(" ")[0],
        idade: vivo(p.age),
        ano_escolar: vivo(p.grade),
        escola: vivo(p.school),
        situacao: p.status,
      },
      queixa_principal: vivo(p.complaint),
      hipoteses: (p.tags || []).length ? p.tags : null,
      medicacoes: vivo(p.meds),
      anamnese,
      avaliacoes: avaliacoes.length ? avaliacoes : null,
    };
  }

  // Documentos que a IA consegue ler, para a profissional escolher.
  async function documentosLegiveis(pid) {
    if (!window.EducareDocs) return [];
    const todos = await window.EducareDocs.listar(pid);
    return todos.filter((d) => legivel(d.mime_type));
  }

  async function gerar(pid, doc, preferencias) {
    const payload = contextoDoPaciente(pid);
    if (preferencias) payload.preferencias_da_profissional = preferencias;

    if (doc) {
      const { data, error } = await window.sb.storage
        .from("paciente-documentos").download(doc.storage_path);
      if (error || !data) throw new Error("Não foi possível ler o documento anexado.");
      payload.documento_anexado = { nome: doc.file_name, descricao: doc.description || null };
      payload.documento = { media_type: doc.mime_type, data: await paraBase64(data) };
    }

    return window.EducareIA.gerar("plano", payload);
  }

  /* Achata o plano para texto. O formato de plans nasceu do formulário
     antigo (título, nível, sessões, frequência, meta), então o corpo
     inteiro vai em "goal", que é o campo longo — e é o que o prontuário
     já sabe exibir, sem precisar de coluna nova. */
  function paraTextoDoProntuario(plano) {
    const linhas = [];
    if (plano.justificativa) linhas.push(plano.justificativa, "");
    (plano.eixos || []).forEach((e, i) => {
      linhas.push((i + 1) + ". " + e.nome);
      if (e.objetivo) linhas.push("   Objetivo: " + e.objetivo);
      (e.atividades || []).forEach((a) => linhas.push("   • " + a));
      if (e.criterio_de_avancao) linhas.push("   Avançar quando: " + e.criterio_de_avancao);
      linhas.push("");
    });
    if ((plano.materiais || []).length) linhas.push("Materiais: " + plano.materiais.join("; "), "");
    if ((plano.orientacoes_familia || []).length) {
      linhas.push("Para a família:");
      plano.orientacoes_familia.forEach((o) => linhas.push("   • " + o));
      linhas.push("");
    }
    if ((plano.orientacoes_escola || []).length) {
      linhas.push("Para a escola:");
      plano.orientacoes_escola.forEach((o) => linhas.push("   • " + o));
      linhas.push("");
    }
    if (plano.observacao) linhas.push("Observação: " + plano.observacao);
    return linhas.join("\n").trim();
  }

  function salvar(pid, plano) {
    const hoje = window.todayISO ? window.todayISO() : new Date().toISOString().slice(0, 10);
    const entry = {
      id: window.EducareDB.novoId(),
      title: plano.titulo || "Plano de intervenção",
      level: "—",
      sessions: (plano.eixos || []).length || 1,
      freq: plano.frequencia || "—",
      status: "Em andamento",
      progress: 0,
      goal: paraTextoDoProntuario(plano),
      created: window.fmtLongDate ? window.fmtLongDate(hoje) : hoje,
    };
    /* Entra na lista só depois que o banco confirma: antes entrava na hora
       e ficava como fantasma se o insert falhasse (auditoria 25/09). */
    return window.EducareDB.salvarPlano(pid, entry).then(() => {
      if (!window.PLANS[pid]) window.PLANS[pid] = [];
      window.PLANS[pid].unshift(entry);
      return entry;
    });
  }

  /* Adapta o plano da IA ao formato que a tela de resultado já desenha
     (título, meta, "sessões" com foco/atividades/materiais/obs). Cada
     eixo vira um cartão. Reaproveitar a tela evita reescrever o
     resultado e o PDF só porque a origem do plano mudou. */
  function paraFormatoDaTela(plano) {
    return {
      title: plano.titulo || "Plano de intervenção",
      goal: plano.justificativa || "",
      periodo: plano.periodo || "",
      frequencia: plano.frequencia || "",
      duracao_sessao: plano.duracao_sessao || "",
      sessions: (plano.eixos || []).map((e) => ({
        focus: e.nome + (e.objetivo ? " — " + e.objetivo : ""),
        activities: e.atividades || [],
        materiais: (plano.materiais || []).slice(0, 3),
        obs: e.criterio_de_avancao ? "Avançar quando: " + e.criterio_de_avancao : "",
      })),
      _bruto: plano,
    };
  }

  window.PlanoIA = { contextoDoPaciente, documentosLegiveis, gerar, salvar, paraTextoDoProntuario, paraFormatoDaTela, legivel };

  /* ---------------- seletor de documento ---------------- */

  function SeletorDeDocumento({ pid, valor, onChange }) {
    const [docs, setDocs] = useState(null);
    const [erroDocs, setErroDocs] = useState(false); // falha ao listar não é "nenhum documento"
    useEffect(() => {
      let vivo = true;
      setErroDocs(false);
      if (!pid) { setDocs([]); return; }
      documentosLegiveis(pid)
        .then((d) => { if (vivo) setDocs(d); })
        .catch(() => { if (vivo) { setDocs([]); setErroDocs(true); } });
      return () => { vivo = false; };
    }, [pid]);

    if (!pid) return null;
    if (docs === null) return <p className="help-text">Procurando documentos anexados…</p>;
    if (erroDocs) return <p className="help-text" style={{ color: "#DC2626" }}>Não foi possível listar os documentos deste paciente agora. O plano pode ser gerado sem documento.</p>;
    if (!docs.length) {
      return (
        <p className="help-text">
          Nenhum documento legível anexado a este paciente. Anexe o laudo ou o relatório
          na aba <b>Documentos</b> do prontuário para a IA considerá-lo.
        </p>
      );
    }
    return (
      <div className="fld">
        <label>Basear em um documento (opcional)</label>
        <select className="ctrl" value={(valor && valor.id) || ""}
          onChange={(e) => onChange(docs.find((d) => d.id === e.target.value) || null)}>
          <option value="">Não usar documento</option>
          {docs.map((d) => <option key={d.id} value={d.id}>{d.description || d.file_name}</option>)}
        </select>
        <p className="help-text" style={{ marginBottom: 0 }}>
          A IA lê o arquivo inteiro — laudo do neuro, relatório da escola, avaliação de outro profissional.
        </p>
      </div>
    );
  }

  window.SeletorDeDocumento = SeletorDeDocumento;
})();
