"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { ArrowLeft, Building2, Check, FileKey2, FlaskConical, Loader2, ReceiptText } from "lucide-react";

import { dataCurta, pedirFiscal } from "@/components/fiscal/comum";
import { Aviso } from "@/components/ui/aviso";
import { PageHeader } from "@/components/ui/page-header";

import { Ajuda } from "./ajuda";
import { passoFeito, type PainelNaTela } from "./campos";
import { PassoCertificado } from "./passo-certificado";
import { PassoEmpresa } from "./passo-empresa";
import { PassoNotas } from "./passo-notas";
import { PassoTestar } from "./passo-testar";

export type Etapa = "empresa" | "certificado" | "notas" | "testar";

const ETAPAS: Array<{ chave: Etapa; titulo: string; Icone: typeof Building2 }> = [
  { chave: "empresa", titulo: "Sua empresa", Icone: Building2 },
  { chave: "certificado", titulo: "Certificado digital", Icone: FileKey2 },
  { chave: "notas", titulo: "Notas e impostos", Icone: ReceiptText },
  { chave: "testar", titulo: "Testar e começar", Icone: FlaskConical },
];

/* Links antigos (?passo=tributacao, ?passo=produtos...) continuam abrindo o lugar certo. */
const ETAPA_DO_ENDERECO: Record<string, Etapa> = {
  empresa: "empresa",
  certificado: "certificado",
  notas: "notas",
  modelos: "notas",
  tributacao: "notas",
  produtos: "notas",
  testar: "testar",
  teste: "testar",
  producao: "testar",
};

export type PropsDoPasso = {
  painel: PainelNaTela;
  recarregar: () => Promise<PainelNaTela | null>;
  irPara: (etapa: Etapa) => void;
  /** Pedido que veio no endereço, como abrir a lista de produtos sem código fiscal. */
  abrir: string | null;
};

const NOMES_DOS_MODELOS: Record<"nfe" | "nfce" | "nfse", string> = { nfe: "Nota de produto", nfce: "Cupom fiscal", nfse: "Nota de serviço" };

function resumoDasEtapas(painel: PainelNaTela): Record<Etapa, { feito: boolean; resumo: string }> {
  const emissor = painel.emissor;
  const ligados = emissor ? (["nfe", "nfce", "nfse"] as const).filter((modelo) => emissor[modelo].ativo) : [];
  const validade = emissor?.certificado?.validade;
  return {
    empresa: {
      feito: passoFeito(painel, "empresa"),
      resumo: emissor?.cadastradoNaSpedy ? emissor.nomeFantasia || emissor.razaoSocial : "CNPJ, endereço e regime",
    },
    certificado: {
      feito: passoFeito(painel, "certificado"),
      resumo: validade ? `Válido até ${dataCurta(validade)}` : "Arquivo A1 e senha",
    },
    notas: {
      feito: passoFeito(painel, "modelos") && passoFeito(painel, "tributacao"),
      resumo: ligados.length ? ligados.map((modelo) => NOMES_DOS_MODELOS[modelo]).join(", ") : "Quais notas você vai emitir",
    },
    testar: {
      feito: passoFeito(painel, "teste"),
      resumo: passoFeito(painel, "teste") ? "Teste aprovado" : "Uma nota de teste de R$ 1,00",
    },
  };
}

export default function ConfiguracaoFiscalCliente() {
  const [painel, setPainel] = useState<PainelNaTela | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [etapa, setEtapa] = useState<Etapa | null>(null);
  const [abrir, setAbrir] = useState<string | null>(null);

  const recarregar = useCallback(async () => {
    try {
      const json = await pedirFiscal<PainelNaTela>("/api/fiscal/configuracao");
      setPainel(json);
      setErro(null);
      return json;
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível carregar a configuração.");
      return null;
    }
  }, []);

  /* Primeira carga: abre a etapa pedida no endereço; sem pedido, a primeira que falta. */
  useEffect(() => {
    let vivo = true;
    pedirFiscal<PainelNaTela>("/api/fiscal/configuracao")
      .then((json) => {
        if (!vivo) return;
        setPainel(json);
        const busca = new URLSearchParams(window.location.search);
        const pedido = ETAPA_DO_ENDERECO[busca.get("passo") ?? ""];
        if (pedido) setEtapa(pedido);
        setAbrir(busca.get("passo") === "produtos" ? "produtos" : busca.get("abrir"));
      })
      .catch((e: unknown) => {
        if (vivo) setErro(e instanceof Error ? e.message : "Não foi possível carregar a configuração.");
      });
    return () => {
      vivo = false;
    };
  }, []);

  const resumo = useMemo(() => (painel ? resumoDasEtapas(painel) : null), [painel]);
  const etapaAtual: Etapa = etapa ?? (resumo ? ETAPAS.find((item) => !resumo[item.chave].feito)?.chave ?? "testar" : "empresa");

  const irPara = useCallback((chave: Etapa) => {
    setEtapa(chave);
    setAbrir(null);
    const url = new URL(window.location.href);
    url.searchParams.set("passo", chave);
    url.searchParams.delete("abrir");
    window.history.replaceState(null, "", url.toString());
    window.scrollTo({ top: 0, behavior: "smooth" });
  }, []);

  const emTeste =
    painel?.ambiente === "sandbox" ||
    Boolean(painel?.emissor && !(["nfe", "nfce", "nfse"] as const).some((modelo) => painel.emissor?.[modelo].ativo && painel.emissor[modelo].ambiente === "producao"));

  const props: PropsDoPasso | null = painel ? { painel, recarregar, irPara, abrir } : null;

  return (
    <div className="space-y-6">
      <PageHeader
        eyebrow="Notas fiscais"
        title="Configurar notas fiscais"
        subtitle="Em quatro passos a sua empresa fica pronta para emitir nota de produto, cupom fiscal e nota de serviço."
        actions={
          <div className="flex flex-wrap items-center gap-2">
            {painel && emTeste ? (
              <span
                title="Enquanto estiver em teste, as notas não têm valor fiscal e não gastam o seu pacote."
                className="inline-flex items-center gap-2 rounded-full bg-gradient-to-r from-sky-500 to-indigo-600 px-3.5 py-1.5 text-xs font-bold text-white shadow-[0_8px_20px_rgba(14,116,244,0.28)]"
              >
                <FlaskConical size={14} />
                Modo de teste
              </span>
            ) : null}
            <Link href="/dashboard/notas-fiscais" className="ks-button ks-button-soft">
              <ArrowLeft size={16} />
              Emissão de notas
            </Link>
          </div>
        }
      />

      {erro ? <Aviso tom="ruim">{erro}</Aviso> : null}

      {painel && !painel.servidorPronto ? (
        <Aviso tom="atencao" titulo="Emissão de notas indisponível no momento">
          Você pode preencher e salvar os dados agora. A emissão volta a funcionar assim que o serviço for restabelecido; se demorar, fale com o suporte do Ktalogu.
        </Aviso>
      ) : null}

      {!painel || !props || !resumo ? (
        <div className="flex justify-center py-24">
          <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
        </div>
      ) : (
        <>
          <ol className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-4">
            {ETAPAS.map((item, indice) => {
              const ativa = etapaAtual === item.chave;
              const { feito, resumo: texto } = resumo[item.chave];
              return (
                <li key={item.chave}>
                  <button
                    type="button"
                    onClick={() => irPara(item.chave)}
                    aria-current={ativa ? "step" : undefined}
                    className={`flex w-full items-center gap-4 rounded-2xl px-4 py-4 text-left transition ${
                      ativa
                        ? "bg-[var(--ks-color-bg-elevated)] shadow-[0_16px_40px_rgba(26,26,43,0.12)] ring-2 ring-[var(--ks-color-primary)]"
                        : "bg-[var(--ks-color-bg-elevated)] shadow-[0_8px_24px_rgba(26,26,43,0.05)] hover:shadow-[0_14px_34px_rgba(26,26,43,0.10)]"
                    }`}
                  >
                    <span
                      className={`flex h-12 w-12 shrink-0 items-center justify-center rounded-2xl ${
                        feito
                          ? "bg-gradient-to-br from-emerald-400 to-emerald-600 text-white shadow-[0_8px_18px_rgba(16,185,129,0.3)]"
                          : ativa
                            ? "bg-gradient-to-br from-violet-500 to-purple-600 text-white shadow-[0_8px_18px_rgba(124,58,237,0.3)]"
                            : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-soft)]"
                      }`}
                    >
                      {feito ? <Check size={22} strokeWidth={3} /> : <item.Icone size={22} />}
                    </span>
                    <span className="min-w-0">
                      <span className="block text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">
                        Passo {indice + 1}
                        {feito ? " · pronto" : ""}
                      </span>
                      <span className="block truncate text-base font-extrabold text-[var(--ks-color-text-primary)]">{item.titulo}</span>
                      <span className="block truncate text-[13px] text-[var(--ks-color-text-muted)]">{texto}</span>
                    </span>
                  </button>
                </li>
              );
            })}
          </ol>

          <div className="grid grid-cols-1 items-start gap-6 2xl:grid-cols-[minmax(0,1fr)_360px]">
            <div className="min-w-0 rounded-3xl bg-[var(--ks-color-bg-elevated)] p-5 shadow-[0_10px_30px_rgba(26,26,43,0.06)] sm:p-8 xl:p-10">
              {etapaAtual === "empresa" ? <PassoEmpresa key="empresa" {...props} /> : null}
              {etapaAtual === "certificado" ? <PassoCertificado key="certificado" {...props} /> : null}
              {etapaAtual === "notas" ? <PassoNotas key="notas" {...props} /> : null}
              {etapaAtual === "testar" ? <PassoTestar key="testar" {...props} /> : null}
            </div>
            <aside className="2xl:sticky 2xl:top-4">
              <Ajuda etapa={etapaAtual} painel={painel} />
            </aside>
          </div>
        </>
      )}
    </div>
  );
}
