"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, Loader2, ReceiptText, Search } from "lucide-react";

import { CustomSelect } from "@/components/ui/custom-select";
import { ORIGENS } from "@/lib/fiscal/regras";

export type DadosFiscaisDoProduto = {
  fiscal_tipo: "" | "mercadoria" | "servico";
  ncm: string;
  cest: string;
  fiscal_origem: string;
  fiscal_perfil_id: string;
};

export const DADOS_FISCAIS_VAZIOS: DadosFiscaisDoProduto = {
  fiscal_tipo: "",
  ncm: "",
  cest: "",
  fiscal_origem: "",
  fiscal_perfil_id: "",
};

export function lerDadosFiscaisDoProduto(linha: Record<string, unknown> | null | undefined): DadosFiscaisDoProduto {
  const r = linha ?? {};
  const tipo = r.fiscal_tipo === "servico" ? "servico" : r.fiscal_tipo === "mercadoria" ? "mercadoria" : "";
  return {
    fiscal_tipo: tipo,
    ncm: typeof r.ncm === "string" ? r.ncm : "",
    cest: typeof r.cest === "string" ? r.cest : "",
    fiscal_origem: r.fiscal_origem === null || r.fiscal_origem === undefined ? "" : String(r.fiscal_origem),
    fiscal_perfil_id: typeof r.fiscal_perfil_id === "string" ? r.fiscal_perfil_id : "",
  };
}

/** O pedaço do PATCH do produto. */
export function patchFiscalDoProduto(dados: DadosFiscaisDoProduto) {
  const ncm = dados.ncm.replace(/\D/g, "");
  const cest = dados.cest.replace(/\D/g, "");
  return {
    fiscal_tipo: dados.fiscal_tipo || null,
    ncm: ncm || null,
    cest: cest || null,
    fiscal_origem: dados.fiscal_origem === "" ? null : Number(dados.fiscal_origem),
    fiscal_perfil_id: dados.fiscal_perfil_id || null,
  };
}

export function problemaNosDadosFiscais(dados: DadosFiscaisDoProduto): string | null {
  const ncm = dados.ncm.replace(/\D/g, "");
  const cest = dados.cest.replace(/\D/g, "");
  if (ncm && ncm.length !== 8) return "O NCM tem 8 números.";
  if (cest && cest.length !== 7) return "O CEST tem 7 números.";
  return null;
}

function ncmFormatado(valor: string) {
  const d = valor.replace(/\D/g, "").slice(0, 8);
  if (d.length <= 4) return d;
  if (d.length <= 6) return `${d.slice(0, 4)}.${d.slice(4)}`;
  return `${d.slice(0, 4)}.${d.slice(4, 6)}.${d.slice(6)}`;
}

type Perfil = { id: string; nome: string; tipo: string; padrao: boolean; ativo: boolean };

export function CamposFiscaisDoProduto({
  valor,
  aoMudar,
  nomeDoProduto,
}: {
  valor: DadosFiscaisDoProduto;
  aoMudar: (proximo: DadosFiscaisDoProduto) => void;
  nomeDoProduto?: string;
}) {
  const [aberto, setAberto] = useState(false);
  const [perfis, setPerfis] = useState<Perfil[]>([]);
  const [busca, setBusca] = useState("");
  const [resultados, setResultados] = useState<Array<{ codigo: string; descricao: string }>>([]);
  const [buscando, setBuscando] = useState(false);
  const [listaAberta, setListaAberta] = useState(false);
  const caixaRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!aberto) return;
    let vivo = true;
    fetch("/api/fiscal/perfis", { cache: "no-store" })
      .then((r) => (r.ok ? r.json() : { perfis: [] }))
      .then((json: { perfis?: Perfil[] }) => {
        if (vivo) setPerfis((json.perfis ?? []).filter((p) => p.ativo));
      })
      .catch(() => undefined);
    return () => {
      vivo = false;
    };
  }, [aberto]);

  useEffect(() => {
    const termo = busca.trim();
    if (termo.length < 3) {
      setResultados([]);
      return;
    }
    const relogio = setTimeout(async () => {
      setBuscando(true);
      try {
        const resposta = await fetch(`/api/fiscal/consultas/ncm?q=${encodeURIComponent(termo)}`, { cache: "no-store" });
        const json = (await resposta.json().catch(() => null)) as { resultados?: Array<{ codigo: string; descricao: string }> } | null;
        setResultados(json?.resultados ?? []);
        setListaAberta(true);
      } finally {
        setBuscando(false);
      }
    }, 350);
    return () => clearTimeout(relogio);
  }, [busca]);

  useEffect(() => {
    const fechar = (evento: MouseEvent) => {
      if (caixaRef.current && !caixaRef.current.contains(evento.target as Node)) setListaAberta(false);
    };
    window.addEventListener("mousedown", fechar);
    return () => window.removeEventListener("mousedown", fechar);
  }, []);

  const tipoEfetivo = valor.fiscal_tipo || "mercadoria";
  const perfisDoTipo = useMemo(() => perfis.filter((p) => p.tipo === tipoEfetivo), [perfis, tipoEfetivo]);
  const padrao = perfisDoTipo.find((p) => p.padrao);
  const ncmDigitos = valor.ncm.replace(/\D/g, "");
  const resumo =
    tipoEfetivo === "servico"
      ? "Sai na nota de serviço (NFS-e)"
      : ncmDigitos.length === 8
        ? `NCM ${ncmFormatado(ncmDigitos)}`
        : "Falta o NCM para emitir nota";

  const mudar = (parcial: Partial<DadosFiscaisDoProduto>) => aoMudar({ ...valor, ...parcial });

  return (
    <div className={`rounded-[20px] border border-slate-200/60 bg-white shadow-[0_2px_14px_rgba(0,0,0,0.02)] ${aberto ? "" : "overflow-hidden"} transition-all duration-300 hover:border-slate-300/80 hover:shadow-[0_8px_30px_rgba(0,0,0,0.06)]`}>
      <button
        type="button"
        onClick={() => setAberto((v) => !v)}
        className="w-full flex items-center justify-between gap-4 px-6 py-5 text-left bg-transparent transition-colors hover:bg-slate-50/50"
      >
        <span className="flex items-center gap-3">
          <span className="inline-flex h-10 w-10 shrink-0 items-center justify-center rounded-[12px] bg-slate-50 text-[var(--ks-color-primary-strong)] border border-slate-100 shadow-[0_2px_4px_rgba(0,0,0,0.02)]">
            <ReceiptText size={16} />
          </span>
          <span className="min-w-0">
            <span className="block text-[15px] font-bold text-slate-800 tracking-tight">Nota fiscal</span>
            <span
              className={`block text-[13px] font-medium mt-0.5 ${
                tipoEfetivo === "mercadoria" && ncmDigitos.length !== 8 ? "text-rose-600" : "text-slate-500"
              }`}
            >
              {resumo}
            </span>
          </span>
        </span>
        <ChevronDown size={18} className={`text-[var(--ks-color-text-soft)] transition-transform duration-200 ${aberto ? "rotate-180" : ""}`} />
      </button>
      <div className={`grid transition-all duration-200 ease-out ${aberto ? "grid-rows-[1fr] opacity-100" : "grid-rows-[0fr] opacity-0"}`}>
        <div className={aberto ? "" : "overflow-hidden"}>
          <div className="border-t border-[rgba(198,203,224,0.4)] p-5 space-y-5">
            <div className="space-y-2">
              <label className="text-xs font-medium text-[var(--ks-color-text-soft)] uppercase tracking-[0.16em]">O que é, para a nota</label>
              <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
                {[
                  { valor: "mercadoria" as const, titulo: "Produto", texto: "Sai na NF-e ou na NFC-e (ICMS)." },
                  { valor: "servico" as const, titulo: "Serviço", texto: "Sai na NFS-e da prefeitura (ISS)." },
                ].map((opcao) => {
                  const ativo = tipoEfetivo === opcao.valor;
                  return (
                    <button
                      key={opcao.valor}
                      type="button"
                      onClick={() => mudar({ fiscal_tipo: opcao.valor, fiscal_perfil_id: "" })}
                      className={`rounded-2xl px-4 py-3 text-left transition ${
                        ativo
                          ? "bg-[var(--ks-color-primary)] text-white shadow-[0_10px_24px_rgba(124,58,237,0.28)]"
                          : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-primary)] hover:bg-[var(--ks-color-bg-hover)]"
                      }`}
                    >
                      <span className="block text-sm font-bold">{opcao.titulo}</span>
                      <span className={`block text-xs ${ativo ? "text-white/80" : "text-[var(--ks-color-text-muted)]"}`}>{opcao.texto}</span>
                    </button>
                  );
                })}
              </div>
              <p className="text-xs text-[var(--ks-color-text-soft)]">
                Impressão personalizada sob encomenda costuma ser serviço (ISS); produto pronto de revenda é produto (ICMS). Na dúvida, confirme com o seu contador.
              </p>
            </div>

            {tipoEfetivo === "mercadoria" ? (
              <div className="grid grid-cols-1 gap-4 md:grid-cols-[minmax(0,1.4fr)_minmax(0,0.6fr)]">
                <div className="space-y-2" ref={caixaRef}>
                  <label className="text-xs font-medium text-[var(--ks-color-text-soft)] uppercase tracking-[0.16em]">NCM</label>
                  <div className="relative">
                    <input
                      value={ncmFormatado(valor.ncm)}
                      onChange={(e) => mudar({ ncm: e.target.value.replace(/\D/g, "").slice(0, 8) })}
                      inputMode="numeric"
                      placeholder="0000.00.00"
                      className="ks-field w-full tabular-nums"
                    />
                  </div>
                  <div className="relative">
                    <Search size={14} className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-[var(--ks-color-text-soft)]" />
                    <input
                      value={busca}
                      onChange={(e) => setBusca(e.target.value)}
                      onFocus={() => resultados.length && setListaAberta(true)}
                      placeholder={`Procurar NCM por nome (ex.: ${nomeDoProduto?.split(" ")[0]?.toLowerCase() || "adesivo"})`}
                      className="ks-field" style={{ paddingLeft: "2.25rem" }}
                    />
                    {buscando ? (
                      <Loader2 size={14} className="absolute right-3 top-1/2 -translate-y-1/2 animate-spin text-[var(--ks-color-primary)]" />
                    ) : null}
                    {listaAberta && resultados.length ? (
                      <ul className="absolute left-0 right-0 top-[calc(100%+6px)] z-30 max-h-72 overflow-y-auto rounded-2xl bg-white py-1 shadow-[0_18px_40px_rgba(26,26,43,0.16)]">
                        {resultados.map((item) => (
                          <li key={item.codigo}>
                            <button
                              type="button"
                              onClick={() => {
                                mudar({ ncm: item.codigo });
                                setListaAberta(false);
                                setBusca("");
                              }}
                              className="block w-full px-4 py-2.5 text-left text-xs leading-5 text-[var(--ks-color-text-primary)] hover:bg-[var(--ks-color-bg-hover)]"
                            >
                              {item.descricao}
                            </button>
                          </li>
                        ))}
                      </ul>
                    ) : null}
                  </div>
                  <p className="text-xs text-[var(--ks-color-text-soft)]">A classificação do produto na tabela da Receita. Seu contador ou a nota de compra do material costumam trazer.</p>
                </div>
                <div className="space-y-2">
                  <label className="text-xs font-medium text-[var(--ks-color-text-soft)] uppercase tracking-[0.16em]">CEST (se tiver)</label>
                  <input
                    value={valor.cest}
                    onChange={(e) => mudar({ cest: e.target.value.replace(/\D/g, "").slice(0, 7) })}
                    inputMode="numeric"
                    placeholder="0000000"
                    className="ks-field w-full tabular-nums"
                  />
                  <label className="mt-3 block text-xs font-medium text-[var(--ks-color-text-soft)] uppercase tracking-[0.16em]">Origem</label>
                  <CustomSelect
                    options={[
                      { value: "", label: "A da tributação" },
                      ...ORIGENS.map((o) => ({ value: String(o.codigo), label: `${o.codigo} · ${o.nome}` })),
                    ]}
                    value={valor.fiscal_origem}
                    onChange={(v) => mudar({ fiscal_origem: v })}
                  />
                </div>
              </div>
            ) : null}

            <div className="space-y-2">
              <label className="text-xs font-medium text-[var(--ks-color-text-soft)] uppercase tracking-[0.16em]">Tributação</label>
              <CustomSelect
                options={[
                  { value: "", label: padrao ? `Padrão da empresa (${padrao.nome})` : "Padrão da empresa" },
                  ...perfisDoTipo.map((p) => ({ value: p.id, label: p.nome })),
                ]}
                value={valor.fiscal_perfil_id}
                onChange={(v) => mudar({ fiscal_perfil_id: v })}
              />
              <p className="text-xs text-[var(--ks-color-text-soft)]">
                As tributações são criadas em Notas fiscais → Configuração. Deixe no padrão se este produto não tem nada diferente.
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}
