"use client";

import { use, useCallback, useEffect, useMemo, useState } from "react";
import { CheckCircle2, Loader2, MessageSquareWarning } from "lucide-react";
import { getSupabaseClient } from "@/lib/supabase";
import { cssDasFontesDaMarca, documentoLimpo, fontesDaMarca, htmlDasPaginas, paginasDoDocumento, registrarFontesDaMarca, type DocumentoDoBanner } from "@/lib/banner-editor/documento";

/**
 * A prova da arte aberta pelo cliente (link público, sem login).
 *
 * Fora de /dashboard de propósito: quem abre não tem conta. O token no
 * caminho é a única credencial; a leitura e a resposta vão por funções do
 * banco que só mostram a arte e só registram "aprovar" ou "pedir alteração".
 * Sem menu e sem link para o sistema: a página entrega a arte e mais nada.
 */

type Prova = {
  valida: boolean;
  motivo?: string;
  nome?: string;
  documento?: DocumentoDoBanner;
  situacao?: "aguardando" | "aprovada" | "alteracao";
  respostas?: Array<{ quando: string; situacao: "aprovada" | "alteracao"; nome: string; comentario: string }>;
  empresa?: string;
  /* Ligada a um item do orçamento (migration 232): a conversa da arte, com as respostas da loja. */
  conversa?: Array<{ de: "client" | "company"; texto: string; quando: string }>;
};

const MOTIVOS: Record<string, { titulo: string; texto: string }> = {
  inexistente: { titulo: "Link não encontrado", texto: "Confira se o endereço foi copiado inteiro. Se veio de uma conversa, pode ter sido cortado." },
  desativada: { titulo: "Link desativado", texto: "Quem enviou esta arte desativou o link. Peça um novo." },
};

/** Uma página da arte desenhada no tamanho da tela (o mesmo HTML do editor e do download). */
function PaginaDaProva({ pagina, numero, total }: { pagina: DocumentoDoBanner; numero: number; total: number }) {
  const html = useMemo(() => {
    const base = htmlDasPaginas([pagina], (p) => p.src);
    const fontes = cssDasFontesDaMarca(fontesDaMarca().map((f) => f.chave));
    return fontes ? base.replace("<style>", `<style>${fontes}`) : base;
  }, [pagina]);
  return (
    <figure className="mx-auto w-full" style={{ maxWidth: Math.min(900, pagina.largura) }}>
      <div className="relative w-full overflow-hidden rounded-[14px] bg-white shadow-[0_12px_40px_rgba(20,11,43,0.14)] ring-1 ring-black/5" style={{ aspectRatio: `${pagina.largura} / ${pagina.altura}` }}>
        <iframe title={`Página ${numero}`} srcDoc={html} sandbox="allow-scripts" className="absolute left-0 top-0 origin-top-left border-0" style={{ width: pagina.largura, height: pagina.altura, transform: "scale(var(--escala))" }} />
      </div>
      {total > 1 ? <figcaption className="mt-2 text-center text-[12px] font-semibold text-[#8A849E]">Página {numero} de {total}</figcaption> : null}
    </figure>
  );
}

export default function ProvaDaArte({ params }: { params: Promise<{ token: string }> }) {
  const { token } = use(params);
  const [prova, setProva] = useState<Prova | null>(null);
  const [falhou, setFalhou] = useState(false);
  const [nome, setNome] = useState("");
  const [comentario, setComentario] = useState("");
  const [pedindo, setPedindo] = useState(false);
  const [enviando, setEnviando] = useState<null | "aprovada" | "alteracao">(null);
  const [erro, setErro] = useState<string | null>(null);

  /* Lê a prova pelo token (a função do banco só devolve a arte e as respostas). */
  const ler = useCallback(async (): Promise<Prova | null> => {
    const { data, error } = await getSupabaseClient().rpc("ver_prova_da_arte", { p_token: token });
    if (error || !data) return null;
    const lida = data as Prova;
    if (lida.documento) registrarFontesDaMarca(lida.documento.fontesProprias);
    return lida;
  }, [token]);
  const carregar = useCallback(async () => {
    const lida = await ler();
    if (lida) setProva(lida);
    else setFalhou(true);
  }, [ler]);

  useEffect(() => {
    document.title = "Aprovação da arte";
    let vivo = true;
    ler().then((lida) => {
      if (!vivo) return;
      if (lida) setProva(lida);
      else setFalhou(true);
    });
    return () => {
      vivo = false;
    };
  }, [ler]);

  /* Cada iframe é desenhado no tamanho real e encolhido para caber na largura. */
  useEffect(() => {
    const ajustar = () => {
      for (const quadro of document.querySelectorAll<HTMLIFrameElement>("iframe[title^='Página']")) {
        const caixa = quadro.parentElement;
        if (caixa) caixa.style.setProperty("--escala", String(caixa.clientWidth / Math.max(1, quadro.offsetWidth)));
      }
    };
    ajustar();
    window.addEventListener("resize", ajustar);
    return () => window.removeEventListener("resize", ajustar);
  }, [prova]);

  const paginas = useMemo(() => {
    const doc = prova?.documento;
    return doc ? paginasDoDocumento(documentoLimpo(doc, doc.largura, doc.altura)) : [];
  }, [prova]);

  const responder = async (situacao: "aprovada" | "alteracao") => {
    if (situacao === "alteracao" && !comentario.trim()) {
      setErro("Escreva o que precisa mudar.");
      return;
    }
    setErro(null);
    setEnviando(situacao);
    const { data, error } = await getSupabaseClient().rpc("responder_prova_da_arte", { p_token: token, p_situacao: situacao, p_nome: nome, p_comentario: comentario });
    setEnviando(null);
    const resposta = data as { ok?: boolean; motivo?: string } | null;
    if (error || !resposta?.ok) {
      setErro(resposta?.motivo === "limite" ? "Esta arte já recebeu respostas demais. Fale direto com quem enviou." : "Não deu para enviar agora. Tente de novo em instantes.");
      return;
    }
    setPedindo(false);
    setComentario("");
    await carregar();
  };

  if (falhou || (prova && !prova.valida)) {
    const motivo = MOTIVOS[prova?.motivo || "inexistente"] || MOTIVOS.inexistente;
    return (
      <main className="flex min-h-screen items-center justify-center bg-[#F4F3F8] px-4">
        <div className="max-w-sm rounded-[18px] bg-white p-6 text-center shadow-[0_12px_40px_rgba(20,11,43,0.1)]">
          <h1 className="text-[18px] font-bold text-[#1F1B2E]">{motivo.titulo}</h1>
          <p className="mt-2 text-[14px] leading-relaxed text-[#6B6584]">{motivo.texto}</p>
        </div>
      </main>
    );
  }
  if (!prova) {
    return (
      <main className="flex min-h-screen items-center justify-center bg-[#F4F3F8] text-[14px] text-[#6B6584]">
        <Loader2 size={18} className="mr-2 animate-spin" /> Abrindo a arte…
      </main>
    );
  }

  const ultima = prova.respostas?.at(-1);
  return (
    <main className="min-h-screen bg-[#F4F3F8] px-4 pb-40 pt-8 text-[#1F1B2E]">
      <header className="mx-auto mb-6 max-w-[900px]">
        {prova.empresa ? <p className="text-[12px] font-bold uppercase tracking-[0.14em] text-[#7C3AED]">{prova.empresa}</p> : null}
        <h1 className="mt-1 text-[24px] font-extrabold leading-tight">{prova.nome}</h1>
        <p className="mt-1 text-[14px] text-[#6B6584]">Confira a arte com calma. Se estiver tudo certo, aprove; se precisar mudar algo, conte o que é.</p>
      </header>

      {prova.situacao !== "aguardando" && ultima ? (
        <div className={`mx-auto mb-6 flex max-w-[900px] items-start gap-3 rounded-[14px] px-4 py-3 ${prova.situacao === "aprovada" ? "bg-[#DCFCE7] text-[#14532D]" : "bg-[#FFF7E6] text-[#7C4A03]"}`}>
          {prova.situacao === "aprovada" ? <CheckCircle2 size={20} className="mt-0.5 shrink-0" /> : <MessageSquareWarning size={20} className="mt-0.5 shrink-0" />}
          <div>
            <p className="text-[14px] font-bold">{prova.situacao === "aprovada" ? "Arte aprovada" : "Alteração pedida"}{ultima.nome ? ` por ${ultima.nome}` : ""}</p>
            {ultima.comentario ? <p className="mt-0.5 whitespace-pre-line text-[13.5px]">{ultima.comentario}</p> : null}
            <p className="mt-0.5 text-[12px] opacity-75">{new Date(ultima.quando).toLocaleString("pt-BR")}</p>
          </div>
        </div>
      ) : null}

      {prova.conversa?.length ? (
        <section className="mx-auto mb-6 max-w-[900px] rounded-[14px] bg-white p-4 shadow-[0_6px_24px_rgba(20,11,43,0.06)] ring-1 ring-black/5" aria-label="Conversa sobre a arte">
          <p className="text-[12px] font-bold uppercase tracking-[0.12em] text-[#8A849E]">Conversa sobre a arte</p>
          <div className="mt-3 space-y-2">
            {prova.conversa.map((m, i) => (
              <div key={i} className={`flex ${m.de === "company" ? "justify-start" : "justify-end"}`}>
                <div className={`max-w-[80%] rounded-[12px] px-3 py-2 text-[13.5px] leading-snug ${m.de === "company" ? "bg-[#F1EFF6] text-[#1F1B2E]" : "bg-[#7C3AED] text-white"}`}>
                  <p className="text-[11px] font-bold opacity-75">{m.de === "company" ? prova.empresa || "Loja" : "Você"}</p>
                  <p className="whitespace-pre-line">{m.texto}</p>
                  <p className="mt-0.5 text-[10.5px] opacity-70">{new Date(m.quando).toLocaleString("pt-BR")}</p>
                </div>
              </div>
            ))}
          </div>
        </section>
      ) : null}

      <div className="space-y-8">
        {paginas.map((pagina, i) => (
          <PaginaDaProva key={i} pagina={pagina} numero={i + 1} total={paginas.length} />
        ))}
      </div>

      <div className="fixed inset-x-0 bottom-0 border-t border-black/5 bg-white/95 px-4 py-3 backdrop-blur">
        <div className="mx-auto max-w-[900px]">
          {pedindo ? (
            <div className="space-y-2">
              <textarea value={comentario} onChange={(e) => setComentario(e.target.value.slice(0, 2000))} autoFocus placeholder="O que precisa mudar? (ex.: trocar a foto da página 2, aumentar o telefone)" className="min-h-[84px] w-full rounded-[12px] border border-[#E6E3EE] px-3 py-2.5 text-[14px] outline-none focus:border-[#7C3AED]" aria-label="O que precisa mudar" />
              <div className="flex flex-wrap items-center gap-2">
                <input value={nome} onChange={(e) => setNome(e.target.value.slice(0, 80))} placeholder="Seu nome" className="h-11 min-w-0 flex-1 rounded-[12px] border border-[#E6E3EE] px-3 text-[14px] outline-none focus:border-[#7C3AED]" aria-label="Seu nome" />
                <button type="button" onClick={() => setPedindo(false)} className="h-11 rounded-[12px] px-4 text-[14px] font-semibold text-[#6B6584] hover:bg-[#F4F3F8]">
                  Voltar
                </button>
                <button type="button" disabled={enviando !== null} onClick={() => void responder("alteracao")} className="flex h-11 items-center gap-2 rounded-[12px] bg-[#1F1B2E] px-5 text-[14px] font-bold text-white disabled:opacity-60">
                  {enviando === "alteracao" ? <Loader2 size={16} className="animate-spin" /> : null} Enviar pedido
                </button>
              </div>
            </div>
          ) : (
            <div className="flex flex-wrap items-center gap-2">
              <input value={nome} onChange={(e) => setNome(e.target.value.slice(0, 80))} placeholder="Seu nome" className="h-11 min-w-0 flex-1 rounded-[12px] border border-[#E6E3EE] px-3 text-[14px] outline-none focus:border-[#7C3AED]" aria-label="Seu nome" />
              <button type="button" onClick={() => setPedindo(true)} className="h-11 rounded-[12px] border border-[#E6E3EE] px-4 text-[14px] font-semibold text-[#1F1B2E] hover:bg-[#F4F3F8]">
                Pedir alteração
              </button>
              <button type="button" disabled={enviando !== null} onClick={() => void responder("aprovada")} className="flex h-11 items-center gap-2 rounded-[12px] bg-[#16A34A] px-5 text-[14px] font-bold text-white hover:bg-[#15803D] disabled:opacity-60">
                {enviando === "aprovada" ? <Loader2 size={16} className="animate-spin" /> : <CheckCircle2 size={17} />} Aprovar arte
              </button>
            </div>
          )}
          {erro ? <p className="mt-2 text-[13px] font-semibold text-[#BE123C]">{erro}</p> : null}
        </div>
      </div>
    </main>
  );
}
