"use client";

import { useEffect, useRef, useState } from "react";
import { History, Loader2, RotateCcw, Save } from "lucide-react";
import { documentoLimpo, paginasDoDocumento, type DocumentoDoBanner } from "@/lib/banner-editor/documento";
import { VersoesIndisponiveis, guardarVersao, listarVersoes, type ResumoDaVersao } from "@/lib/banner-editor/versoes";
import { Miniatura } from "./paineis";

/*
  "Versões" do editor de artes: o banco guarda sozinho o jeito anterior da
  arte a cada 10 minutos de trabalho; aqui a pessoa vê a lista (com a
  miniatura da primeira página), guarda uma versão na hora e volta para
  qualquer uma. Voltar não perde nada: a arte de agora vira uma versão antes
  e o "Desfazer" também traz de volta.
*/

function quandoFoi(iso: string) {
  const data = new Date(iso);
  const minutos = Math.round((Date.now() - data.getTime()) / 60000);
  if (minutos < 1) return "Agora há pouco";
  if (minutos < 60) return `Há ${minutos} min`;
  const hora = data.toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" });
  const hoje = new Date();
  const ontem = new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate() - 1);
  if (data.toDateString() === hoje.toDateString()) return `Hoje, ${hora}`;
  if (data.toDateString() === ontem.toDateString()) return `Ontem, ${hora}`;
  return `${data.toLocaleDateString("pt-BR", { day: "2-digit", month: "2-digit" })}, ${hora}`;
}

function PrimeiraPagina({ versao }: { versao: ResumoDaVersao }) {
  const [pagina] = paginasDoDocumento(documentoLimpo(versao.documento, versao.largura, versao.altura));
  /* Cabe em 92 × 64 sem cortar, qualquer que seja o formato. */
  const largura = Math.max(8, Math.min(92, (64 * pagina.largura) / pagina.altura));
  return (
    <div className="flex h-[64px] w-[92px] shrink-0 items-center justify-center overflow-hidden rounded-[8px] bg-[#EEEDF3]">
      <Miniatura doc={pagina} largura={largura} />
    </div>
  );
}

export function BotaoDeVersoes({
  dono,
  arteId,
  atual,
  antesDeGuardar,
  aoVoltar,
  aoAvisar,
  classe,
}: {
  dono: string | null;
  arteId: string | null;
  /* A arte como está agora (todas as páginas). */
  atual: () => { nome: string; largura: number; altura: number; documento: DocumentoDoBanner } | null;
  /* Guarda a arte antes (a versão fica ligada a ela). */
  antesDeGuardar: () => Promise<string | null>;
  aoVoltar: (versao: ResumoDaVersao) => void;
  aoAvisar: (texto: string, tom?: "bom" | "ruim") => void;
  classe: string;
}) {
  const [aberto, setAberto] = useState(false);
  const [versoes, setVersoes] = useState<ResumoDaVersao[] | null>(null);
  const [indisponivel, setIndisponivel] = useState(false);
  const [guardando, setGuardando] = useState(false);
  const [voltando, setVoltando] = useState<string | null>(null);
  const caixa = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    if (!aberto) return;
    const fora = (e: MouseEvent) => {
      if (!caixa.current?.contains(e.target as Node)) setAberto(false);
    };
    document.addEventListener("mousedown", fora);
    return () => document.removeEventListener("mousedown", fora);
  }, [aberto]);

  const carregar = async (id: string | null) => {
    if (!id) {
      setVersoes([]);
      return;
    }
    try {
      setVersoes(await listarVersoes(id));
    } catch (erro) {
      if (erro instanceof VersoesIndisponiveis) setIndisponivel(true);
      setVersoes([]);
    }
  };

  const abrir = () => {
    const vai = !aberto;
    setAberto(vai);
    if (vai) void carregar(arteId);
  };

  /* Guarda a arte de agora como uma versão (antes de voltar para outra, ou pelo botão). */
  const guardarAgora = async (silencioso = false) => {
    const agora = atual();
    if (!dono || !agora) return false;
    const id = await antesDeGuardar();
    if (!id) {
      if (!silencioso) aoAvisar("Não deu para guardar a arte agora.", "ruim");
      return false;
    }
    try {
      const nova = await guardarVersao(dono, id, agora);
      setVersoes((l) => [nova, ...(l || [])].slice(0, 40));
      if (!silencioso) aoAvisar("Versão guardada.");
      return true;
    } catch (erro) {
      if (erro instanceof VersoesIndisponiveis) setIndisponivel(true);
      else if (!silencioso) aoAvisar(erro instanceof Error ? erro.message : "Não deu para guardar a versão.", "ruim");
      return false;
    }
  };

  const voltarPara = async (versao: ResumoDaVersao) => {
    setVoltando(versao.id);
    await guardarAgora(true);
    aoVoltar(versao);
    setVoltando(null);
    setAberto(false);
    aoAvisar(`A arte voltou para a versão de ${quandoFoi(versao.quando).toLowerCase()}.`);
  };

  return (
    <div ref={caixa} className="relative">
      <button type="button" onClick={abrir} title="Versões da arte" aria-label="Versões da arte" className={classe} data-botao-do-topo>
        <History size={18} />
      </button>
      {aberto ? (
        <div className="absolute left-0 top-[calc(100%+10px)] z-[60] w-[360px] rounded-[16px] bg-white p-4 text-[#1F1B2E] shadow-[0_18px_50px_rgba(20,11,43,0.28)] ring-1 ring-black/5" data-janela-do-topo>
          <p className="text-[14px] font-bold">Versões da arte</p>
          <p className="mt-1 text-[12px] leading-snug text-[#8A849E]">A cada 10 minutos de trabalho a arte guarda como estava. Voltar não perde nada: a de agora vira uma versão antes.</p>
          {indisponivel ? (
            <p className="mt-3 rounded-[10px] bg-[#FFF7E6] px-3 py-2.5 text-[12px] leading-snug text-[#8A5300]">O histórico de versões ainda não foi ligado no banco (falta aplicar a migration 225).</p>
          ) : (
            <>
              <button type="button" onClick={async () => { setGuardando(true); await guardarAgora(); setGuardando(false); }} disabled={guardando || !dono} className="mt-3 flex h-10 w-full items-center justify-center gap-2 rounded-[10px] bg-[#F1EEFB] text-[13px] font-bold text-[#5B21B6] transition hover:bg-[#E7E1F8] disabled:opacity-70">
                {guardando ? <Loader2 size={15} className="animate-spin" /> : <Save size={15} />} Guardar versão agora
              </button>
              {versoes === null ? (
                <p className="mt-4 flex items-center justify-center gap-2 text-[12.5px] text-[#8A849E]">
                  <Loader2 size={14} className="animate-spin" /> Abrindo as versões…
                </p>
              ) : versoes.length ? (
                <div className="mt-3 max-h-[360px] space-y-1.5 overflow-y-auto pr-1">
                  {versoes.map((versao) => (
                    <div key={versao.id} className="flex items-center gap-3 rounded-[12px] p-1.5 hover:bg-[#F6F4FB]">
                      <PrimeiraPagina versao={versao} />
                      <div className="min-w-0 flex-1">
                        <p className="text-[12.5px] font-bold">{quandoFoi(versao.quando)}</p>
                        <p className="truncate text-[11.5px] text-[#8A849E]">{versao.manual ? "Guardada por você" : "Guardada sozinha"}</p>
                      </div>
                      <button type="button" onClick={() => void voltarPara(versao)} disabled={voltando !== null} className="flex h-8 shrink-0 items-center gap-1.5 rounded-[8px] bg-white px-2.5 text-[11.5px] font-semibold text-[#4B4760] ring-1 ring-black/10 transition hover:text-[#1F1B2E] disabled:opacity-60">
                        {voltando === versao.id ? <Loader2 size={13} className="animate-spin" /> : <RotateCcw size={13} />} Voltar para esta
                      </button>
                    </div>
                  ))}
                </div>
              ) : (
                <p className="mt-4 text-center text-[12.5px] text-[#8A849E]">Ainda não há versões. Elas aparecem conforme você mexe na arte.</p>
              )}
            </>
          )}
        </div>
      ) : null}
    </div>
  );
}
