"use client";

import { useEffect, useMemo, useState } from "react";
import { Check, Loader2, Package, Plus, Settings2, Trash2, Wrench, X } from "lucide-react";

import { CampoDeCodigo } from "@/components/fiscal/campo-de-codigo";
import { pedirFiscal } from "@/components/fiscal/comum";
import { LinkOficial } from "@/components/fiscal/dica";
import { FormatoDoCodigo } from "@/components/fiscal/formato-do-codigo";
import { NOME_DO_ESTADO, UFS } from "@/lib/fiscal/tabelas";
import { Aviso } from "@/components/ui/aviso";
import CaixaDeConfirmacao, { type Confirmacao } from "@/components/ui/caixa-de-confirmacao";
import { CampoDecimal } from "@/components/ui/campo-decimal";
import { CustomSelect } from "@/components/ui/custom-select";
import { Dialog, DialogContent, DialogDescription, DialogTitle } from "@/components/ui/dialog";
import { Switch } from "@/components/ui/switch";
import { exigenciasDaCidade } from "@/lib/fiscal/emissor";
import {
  CSOSN,
  CST_ICMS,
  CST_PIS_COFINS,
  faltasDaMercadoria,
  faltasDoServico,
  lerRegrasDeMercadoria,
  lerRegrasDeServico,
  MODELOS_DE_MERCADORIA,
  MODELOS_DE_SERVICO,
  ORIGENS,
  regimeUsaCsosn,
  SEM_REGRAS_DE_MERCADORIA,
  TEXTO_DO_SIMPLES,
  TIPOS_DE_TRIBUTACAO_ISS,
  type Regime,
  type RegrasDeMercadoria,
  type RegrasDeServico,
} from "@/lib/fiscal/regras";

import { Campo, Escolha, Recolhivel, soDigitos, type PainelNaTela, type PerfilNaTela } from "./campos";

type Edicao =
  | { tipo: "mercadoria"; id: string | null; nome: string; padrao: boolean; regras: RegrasDeMercadoria }
  | { tipo: "servico"; id: string | null; nome: string; padrao: boolean; regras: RegrasDeServico };

const IPI_CSTS = [
  { value: "", label: "Sem IPI na nota" },
  { value: "50", label: "50 — Saída tributada" },
  { value: "51", label: "51 — Tributada com alíquota zero" },
  { value: "52", label: "52 — Isenta" },
  { value: "53", label: "53 — Não tributada" },
  { value: "54", label: "54 — Imune" },
  { value: "55", label: "55 — Com suspensão" },
  { value: "99", label: "99 — Outras saídas" },
];

const numeroOuNulo = (n: number) => (Number.isFinite(n) && n !== 0 ? n : null);

function edicaoDoPerfil(perfil: PerfilNaTela): Edicao {
  return perfil.tipo === "mercadoria"
    ? { tipo: "mercadoria", id: perfil.id, nome: perfil.nome, padrao: perfil.padrao, regras: lerRegrasDeMercadoria(perfil.regras) }
    : { tipo: "servico", id: perfil.id, nome: perfil.nome, padrao: perfil.padrao, regras: lerRegrasDeServico(perfil.regras) };
}

/**
 * Os códigos fiscais por inteiro, para o contador. A empresa não precisa abrir
 * esta janela: as perguntas do passo "Notas e impostos" montam a tributação no
 * padrão do regime.
 */
export function AjustesDoContador({
  tipo,
  painel,
  perfilInicial,
  aoFechar,
  aoSalvar,
}: {
  tipo: "mercadoria" | "servico";
  painel: PainelNaTela;
  perfilInicial?: string | null;
  aoFechar: () => void;
  aoSalvar: () => Promise<unknown>;
}) {
  const emissor = painel.emissor;
  const regime: Regime = emissor?.regime ?? "simplesNacional";
  const exige = exigenciasDaCidade(emissor?.nfse.cidade?.opcoes ?? null);
  const perfis = useMemo(() => painel.perfis.filter((p) => p.ativo && p.tipo === tipo), [painel.perfis, tipo]);
  const modelosDeMercadoria = MODELOS_DE_MERCADORIA.filter((m) => m.regimes.includes(regime));

  const novo = (): Edicao => {
    if (tipo === "mercadoria") {
      const modelo = modelosDeMercadoria[0];
      return {
        tipo,
        id: null,
        nome: modelo?.nome ?? "Venda de produtos",
        padrao: perfis.length === 0,
        regras: modelo ? { ...modelo.regras } : { ...SEM_REGRAS_DE_MERCADORIA, informacoesAdicionais: regimeUsaCsosn(regime) ? TEXTO_DO_SIMPLES : null },
      };
    }
    const modelo = MODELOS_DE_SERVICO[0];
    const principal = emissor?.cnaes.find((c) => c.principal)?.codigo ?? null;
    return { tipo, id: null, nome: modelo.nome, padrao: perfis.length === 0, regras: { ...modelo.regras, cnae: exige.cnae ? principal : modelo.regras.cnae } };
  };

  const [edicao, setEdicao] = useState<Edicao>(() => {
    const escolhido = perfis.find((p) => p.id === perfilInicial) ?? perfis.find((p) => p.padrao) ?? perfis[0];
    return escolhido ? edicaoDoPerfil(escolhido) : novo();
  });
  const [salvando, setSalvando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [salvo, setSalvo] = useState(false);
  const [confirmacao, setConfirmacao] = useState<Confirmacao | null>(null);

  useEffect(() => {
    if (!salvo) return;
    const relogio = setTimeout(() => setSalvo(false), 2500);
    return () => clearTimeout(relogio);
  }, [salvo]);

  const faltas = edicao.tipo === "mercadoria" ? faltasDaMercadoria(edicao.regras, regime) : faltasDoServico(edicao.regras, exige);

  const mudarMercadoria = (parcial: Partial<RegrasDeMercadoria>) =>
    setEdicao((atual) => (atual.tipo === "mercadoria" ? { ...atual, regras: { ...atual.regras, ...parcial } } : atual));
  const mudarServico = (parcial: Partial<RegrasDeServico>) =>
    setEdicao((atual) => (atual.tipo === "servico" ? { ...atual, regras: { ...atual.regras, ...parcial } } : atual));

  const salvar = async () => {
    setSalvando(true);
    setErro(null);
    try {
      const json = await pedirFiscal<{ perfil: { id: string } }>(edicao.id ? `/api/fiscal/perfis/${edicao.id}` : "/api/fiscal/perfis", {
        method: edicao.id ? "PUT" : "POST",
        json: { nome: edicao.nome, tipo: edicao.tipo, padrao: edicao.padrao, regras: edicao.regras },
      });
      await aoSalvar();
      setEdicao((atual) => ({ ...atual, id: json.perfil?.id ?? atual.id }) as Edicao);
      setSalvo(true);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível salvar.");
    } finally {
      setSalvando(false);
    }
  };

  const excluir = (perfil: PerfilNaTela) =>
    setConfirmacao({
      titulo: `Excluir "${perfil.nome}"?`,
      texto: "Os produtos que usavam esta tributação passam a usar a principal.",
      confirmar: "Excluir",
      tom: "perigo",
      aoConfirmar: async () => {
        setConfirmacao(null);
        try {
          await pedirFiscal(`/api/fiscal/perfis/${perfil.id}`, { method: "DELETE" });
          await aoSalvar();
          if (edicao.id === perfil.id) setEdicao(novo());
        } catch (e) {
          setErro(e instanceof Error ? e.message : "Não foi possível excluir.");
        }
      },
    });

  return (
    <Dialog open onOpenChange={(v) => !v && !salvando && aoFechar()}>
      <DialogContent
        hideClose
        className="flex h-[92vh] w-[calc(100vw-24px)] max-w-[1180px] flex-col gap-0 overflow-hidden rounded-[28px] border-0 bg-[var(--ks-color-bg-elevated)] p-0 shadow-[0_30px_80px_rgba(26,26,43,0.28)]"
      >
        <DialogTitle className="sr-only">Ajustes do contador</DialogTitle>
        <DialogDescription className="sr-only">Os códigos fiscais usados nas notas.</DialogDescription>

        <header className="flex items-center gap-4 border-b border-[var(--ks-color-border-subtle)] px-6 py-5">
          <span className="flex h-12 w-12 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-500 to-purple-600 text-white">
            <Settings2 size={22} />
          </span>
          <div className="min-w-0 flex-1">
            <h2 className="text-xl font-extrabold text-[var(--ks-color-text-primary)]">Ajustes do contador · {tipo === "mercadoria" ? "produtos" : "serviços"}</h2>
            <p className="text-sm text-[var(--ks-color-text-muted)]">Os códigos fiscais que saem em cada nota. Mexa aqui com a orientação do seu contador.</p>
          </div>
          <button type="button" onClick={aoFechar} className="rounded-full p-2 text-[var(--ks-color-text-soft)] hover:bg-[var(--ks-color-bg-hover)]" aria-label="Fechar">
            <X size={20} />
          </button>
        </header>

        <div className="grid min-h-0 flex-1 grid-cols-1 lg:grid-cols-[280px_minmax(0,1fr)]">
          <nav className="min-h-0 overflow-y-auto border-b border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-inset)]/50 p-4 lg:border-b-0 lg:border-r">
            <p className="px-2 pb-2 text-[11px] font-bold uppercase tracking-[0.14em] text-[var(--ks-color-text-soft)]">Tributações</p>
            <ul className="space-y-1">
              {perfis.map((perfil) => {
                const lista = perfil.tipo === "mercadoria" ? faltasDaMercadoria(lerRegrasDeMercadoria(perfil.regras), regime) : faltasDoServico(lerRegrasDeServico(perfil.regras), exige);
                const ativo = edicao.id === perfil.id;
                return (
                  <li key={perfil.id} className="group flex items-center gap-1">
                    <button
                      type="button"
                      onClick={() => {
                        setErro(null);
                        setEdicao(edicaoDoPerfil(perfil));
                      }}
                      className={`min-w-0 flex-1 rounded-xl px-3 py-2.5 text-left transition ${ativo ? "bg-[var(--ks-color-bg-elevated)] shadow-sm" : "hover:bg-[var(--ks-color-bg-elevated)]/70"}`}
                    >
                      <span className="flex items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
                        <span className="truncate">{perfil.nome}</span>
                        {perfil.padrao ? <span className="rounded-full bg-[var(--ks-color-primary)] px-2 py-0.5 text-[9px] font-bold uppercase tracking-[0.08em] text-white">Principal</span> : null}
                      </span>
                      <span className={`block truncate text-xs ${lista.length ? "text-rose-600" : "text-emerald-600"}`}>{lista.length ? "Incompleta" : "Completa"}</span>
                    </button>
                    {!perfil.padrao ? (
                      <button
                        type="button"
                        onClick={() => excluir(perfil)}
                        className="rounded-lg p-2 text-rose-500 opacity-0 transition hover:bg-rose-500/10 group-hover:opacity-100"
                        aria-label={`Excluir ${perfil.nome}`}
                      >
                        <Trash2 size={14} />
                      </button>
                    ) : null}
                  </li>
                );
              })}
            </ul>
            <button
              type="button"
              onClick={() => {
                setErro(null);
                setEdicao(novo());
              }}
              className={`mt-2 flex w-full items-center gap-2 rounded-xl px-3 py-2.5 text-sm font-bold transition ${
                edicao.id === null ? "bg-[var(--ks-color-bg-elevated)] text-[var(--ks-color-primary)] shadow-sm" : "text-[var(--ks-color-primary)] hover:bg-[var(--ks-color-bg-elevated)]/70"
              }`}
            >
              <Plus size={15} />
              Nova tributação
            </button>
          </nav>

          <div className="min-h-0 space-y-6 overflow-y-auto px-6 py-6">
            {erro ? (
              <Aviso tom="ruim" aoFechar={() => setErro(null)}>
                {erro}
              </Aviso>
            ) : null}

            {edicao.id === null ? (
              <div className="space-y-2">
                <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Começar de um modelo</p>
                <div className="flex flex-wrap gap-2">
                  {(edicao.tipo === "mercadoria" ? modelosDeMercadoria : MODELOS_DE_SERVICO).map((modelo) => (
                    <button
                      key={modelo.chave}
                      type="button"
                      title={modelo.descricao}
                      onClick={() =>
                        setEdicao((atual) =>
                          ({
                            ...atual,
                            nome: modelo.nome,
                            regras:
                              atual.tipo === "servico"
                                ? { ...(modelo.regras as RegrasDeServico), aliquotaIss: atual.regras.aliquotaIss, cnae: atual.regras.cnae }
                                : { ...(modelo.regras as RegrasDeMercadoria) },
                          }) as Edicao
                        )
                      }
                      className={`rounded-full px-3.5 py-2 text-xs font-bold transition ${
                        edicao.nome === modelo.nome ? "bg-[var(--ks-color-primary)] text-white" : "bg-[var(--ks-color-bg-inset)] text-[var(--ks-color-text-secondary)] hover:bg-[var(--ks-color-bg-hover)]"
                      }`}
                    >
                      {modelo.nome}
                    </button>
                  ))}
                </div>
              </div>
            ) : null}

            <div className="grid grid-cols-1 gap-5 md:grid-cols-[minmax(0,1fr)_auto]">
              <Campo rotulo="Nome desta tributação">
                <input value={edicao.nome} onChange={(e) => setEdicao({ ...edicao, nome: e.target.value.slice(0, 80) } as Edicao)} className="ks-field" />
              </Campo>
              <label className="flex items-end gap-3 pb-2.5">
                <Switch checked={edicao.padrao} onCheckedChange={(padrao) => setEdicao({ ...edicao, padrao } as Edicao)} />
                <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Principal</span>
              </label>
            </div>

            {edicao.tipo === "mercadoria" ? (
              <EditorDeMercadoria regras={edicao.regras} regime={regime} mudar={mudarMercadoria} />
            ) : (
              <EditorDeServico
                regras={edicao.regras}
                mudar={mudarServico}
                exige={exige}
                cnaes={emissor?.cnaes ?? []}
                cidade={emissor?.nfse.cidade ? { codigo: emissor.nfse.cidade.codigo, nome: emissor.nfse.cidade.nome } : null}
              />
            )}
          </div>
        </div>

        <footer className="flex flex-col gap-3 border-t border-[var(--ks-color-border-subtle)] px-6 py-4 sm:flex-row sm:items-center sm:justify-between">
          <p className={`text-sm ${faltas.length ? "text-rose-600" : "text-emerald-700"}`}>
            {faltas.length ? (
              `Falta preencher: ${faltas.join(", ")}.`
            ) : (
              <span className="inline-flex items-center gap-1.5 font-semibold">
                <Check size={15} /> Completa
              </span>
            )}
          </p>
          <div className="flex items-center gap-2">
            {salvo ? <span className="text-sm font-semibold text-emerald-700">Salvo</span> : null}
            <button type="button" onClick={aoFechar} className="ks-button ks-button-ghost">
              Fechar
            </button>
            <button type="button" onClick={() => void salvar()} disabled={salvando || edicao.nome.trim().length < 2} className="ks-button ks-button-primary">
              {salvando ? <Loader2 size={16} className="animate-spin" /> : null}
              Salvar
            </button>
          </div>
        </footer>
        <CaixaDeConfirmacao pedido={confirmacao} aoFechar={() => setConfirmacao(null)} />
      </DialogContent>
    </Dialog>
  );
}

function EditorDeMercadoria({ regras, regime, mudar }: { regras: RegrasDeMercadoria; regime: Regime; mudar: (parcial: Partial<RegrasDeMercadoria>) => void }) {
  const simples = regimeUsaCsosn(regime);
  const cfop = (valor: number | null) => (valor ? String(valor) : "");
  const lerCfop = (texto: string) => {
    const d = soDigitos(texto).slice(0, 4);
    return d ? Number(d) : null;
  };
  const pisComAliquota = CST_PIS_COFINS.find((c) => c.codigo === regras.pisCst)?.comAliquota;
  const cofinsComAliquota = CST_PIS_COFINS.find((c) => c.codigo === regras.cofinsCst)?.comAliquota;

  return (
    <div className="space-y-6">
      <div className="flex items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
        <Package size={16} className="text-[var(--ks-color-primary)]" /> Nota de produto e cupom fiscal · {simples ? "Simples Nacional" : "regime normal"}
      </div>
      <Campo rotulo="Natureza da operação" dica="Aparece no topo da nota. Ex.: Venda de mercadoria.">
        <input value={regras.natureza} onChange={(e) => mudar({ natureza: e.target.value.slice(0, 60) })} className="ks-field" />
      </Campo>

      <div className="grid grid-cols-1 gap-5 md:grid-cols-3">
        <Campo
          rotulo="CFOP dentro do estado"
          ajuda="O CFOP diz à Receita o que a operação é: venda de produção própria, revenda, brinde, conserto. Clique na lupa e procure pelo nome."
          link="cfop"
        >
          <CampoDeCodigo tipo="cfop" valor={cfop(regras.cfopInterno)} aoMudar={(v) => mudar({ cfopInterno: lerCfop(v) })} maximoDeDigitos={4} placeholder="5101" />
        </Campo>
        <Campo rotulo="CFOP para outro estado" ajuda="O mesmo código, começando em 6. Vale para venda para empresa de outro estado.">
          <CampoDeCodigo tipo="cfop" valor={cfop(regras.cfopInterestadual)} aoMudar={(v) => mudar({ cfopInterestadual: lerCfop(v) })} maximoDeDigitos={4} placeholder="6101" />
        </Campo>
        <Campo rotulo="CFOP para consumidor de outro estado" ajuda="Venda para pessoa física de outro estado. Vazio usa o CFOP de outro estado.">
          <CampoDeCodigo tipo="cfop" valor={cfop(regras.cfopInterestadualConsumidor)} aoMudar={(v) => mudar({ cfopInterestadualConsumidor: lerCfop(v) })} maximoDeDigitos={4} placeholder="6107" />
        </Campo>
      </div>

      {simples ? (
        <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
          <Campo
            rotulo="Situação do ICMS no Simples (CSOSN)"
            className="md:col-span-2"
            ajuda="Diz como o ICMS entra na nota de quem é do Simples. O comum é 102, tributada sem passar crédito ao cliente."
            link="cst"
          >
            <CustomSelect
              options={CSOSN.map((c) => ({ value: String(c.codigo), label: `${c.codigo} — ${c.nome}` }))}
              value={regras.csosn ? String(regras.csosn) : ""}
              onChange={(v) => mudar({ csosn: Number(v) || null })}
              placeholder="Escolha o CSOSN"
            />
          </Campo>
          {regras.csosn === 101 ? (
            <Campo rotulo="Alíquota de crédito do Simples (%)" dica="A da faixa de faturamento do mês.">
              <CampoDecimal valor={regras.aliquotaCreditoSimples} aoMudar={(n) => mudar({ aliquotaCreditoSimples: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
            </Campo>
          ) : null}
          {regras.csosn === 900 ? (
            <Campo rotulo="Alíquota de ICMS (%)" dica="Só se houver ICMS destacado.">
              <CampoDecimal valor={regras.aliquotaIcms} aoMudar={(n) => mudar({ aliquotaIcms: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
            </Campo>
          ) : null}
        </div>
      ) : (
        <div className="grid grid-cols-1 gap-5 md:grid-cols-3">
          <Campo
            rotulo="Situação do ICMS (CST)"
            className="md:col-span-3"
            ajuda="Diz como o ICMS incide no item. No regime normal o comum é 00, tributada integralmente."
            link="cst"
          >
            <CustomSelect
              options={CST_ICMS.map((c) => ({ value: String(c.codigo), label: c.nome }))}
              value={regras.cstIcms === null ? "" : String(regras.cstIcms)}
              onChange={(v) => mudar({ cstIcms: v === "" ? null : Number(v) })}
              placeholder="Escolha o CST"
            />
          </Campo>
          {regras.cstIcms === 0 || regras.cstIcms === 20 ? (
            <Campo rotulo="Alíquota de ICMS (%)">
              <CampoDecimal valor={regras.aliquotaIcms} aoMudar={(n) => mudar({ aliquotaIcms: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
            </Campo>
          ) : null}
          {regras.cstIcms === 20 ? (
            <Campo rotulo="Redução da base (%)">
              <CampoDecimal valor={regras.reducaoBaseIcms} aoMudar={(n) => mudar({ reducaoBaseIcms: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
            </Campo>
          ) : null}
        </div>
      )}

      <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
        <Campo rotulo="PIS" ajuda="Contribuição federal sobre a venda. No Simples vai como 49 (outras operações), porque já está no DAS.">
          <CustomSelect
            options={CST_PIS_COFINS.map((c) => ({ value: String(c.codigo), label: c.nome }))}
            value={regras.pisCst === null ? "" : String(regras.pisCst)}
            onChange={(v) => mudar({ pisCst: v === "" ? null : Number(v) })}
            placeholder="Situação do PIS"
          />
        </Campo>
        <Campo rotulo="COFINS" ajuda="A outra contribuição federal, que anda junto com o PIS.">
          <CustomSelect
            options={CST_PIS_COFINS.map((c) => ({ value: String(c.codigo), label: c.nome }))}
            value={regras.cofinsCst === null ? "" : String(regras.cofinsCst)}
            onChange={(v) => mudar({ cofinsCst: v === "" ? null : Number(v) })}
            placeholder="Situação do COFINS"
          />
        </Campo>
        {pisComAliquota ? (
          <Campo rotulo="Alíquota do PIS (%)" dica="Ex.: 0,65 no Lucro Presumido.">
            <CampoDecimal valor={regras.pisAliquota} aoMudar={(n) => mudar({ pisAliquota: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
          </Campo>
        ) : null}
        {cofinsComAliquota ? (
          <Campo rotulo="Alíquota do COFINS (%)" dica="Ex.: 3 no Lucro Presumido.">
            <CampoDecimal valor={regras.cofinsAliquota} aoMudar={(n) => mudar({ cofinsAliquota: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
          </Campo>
        ) : null}
      </div>

      <Campo rotulo="Informações complementares" dica="Saem no rodapé de toda nota com esta tributação.">
        <textarea value={regras.informacoesAdicionais ?? ""} onChange={(e) => mudar({ informacoesAdicionais: e.target.value.slice(0, 1000) || null })} rows={3} className="ks-field resize-none" />
      </Campo>

      <Recolhivel titulo="Origem, IPI e reforma tributária">
        <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
          <Campo rotulo="Origem padrão" className="md:col-span-2">
            <CustomSelect
              options={ORIGENS.map((o) => ({ value: String(o.codigo), label: `${o.codigo} · ${o.nome}` }))}
              value={String(regras.origem)}
              onChange={(v) => mudar({ origem: Number(v) || 0 })}
            />
          </Campo>
          <Campo rotulo="IPI" dica="Só para indústria que recolhe IPI.">
            <CustomSelect options={IPI_CSTS} value={regras.ipiCst === null ? "" : String(regras.ipiCst)} onChange={(v) => mudar({ ipiCst: v === "" ? null : Number(v) })} />
          </Campo>
          {regras.ipiCst !== null ? (
            <Campo rotulo="Alíquota do IPI (%) e enquadramento">
              <div className="flex gap-2">
                <CampoDecimal valor={regras.ipiAliquota} aoMudar={(n) => mudar({ ipiAliquota: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
                <input
                  value={regras.ipiEnquadramento ?? ""}
                  onChange={(e) => mudar({ ipiEnquadramento: soDigitos(e.target.value).slice(0, 3) || null })}
                  placeholder="999"
                  className="ks-field tabular-nums"
                  style={{ width: "6rem", flexShrink: 0 }}
                />
              </div>
            </Campo>
          ) : null}
          <Campo
            rotulo="CST do IBS/CBS"
            ajuda="Reforma tributária: desde 2026 a nota de quem é do regime normal leva este grupo. Vazio vale como 000, tributação integral."
            link="ibsCbs"
            dica={<LinkOficial chave="ibsCbs" rotulo="Ver a tabela oficial de CST e classificação" />}
          >
            <CampoDeCodigo
              tipo="cstIbsCbs"
              valor={regras.ibsCbsCst === null ? "" : String(regras.ibsCbsCst).padStart(3, "0")}
              aoMudar={(v) => mudar({ ibsCbsCst: v ? Number(v) : null })}
              maximoDeDigitos={3}
              zerosNaFrente
              placeholder="000"
            />
          </Campo>
          <Campo
            rotulo="Classificação tributária do IBS/CBS"
            ajuda="Anda junto com o CST e diz em qual regra da lei a operação se encaixa. Para a venda comum é 000001."
          >
            <CampoDeCodigo
              tipo="classificacaoIbsCbs"
              valor={regras.ibsCbsClassificacao === null ? "" : String(regras.ibsCbsClassificacao).padStart(6, "0")}
              aoMudar={(v) => mudar({ ibsCbsClassificacao: Number(v) || null })}
              maximoDeDigitos={6}
              zerosNaFrente
              placeholder="000001"
            />
          </Campo>
        </div>
      </Recolhivel>

      <Recolhivel titulo="Vendas para consumidor de outro estado (partilha do ICMS)">
        <EstadosDeDestino regras={regras} mudar={mudar} />
      </Recolhivel>
    </div>
  );
}

/**
 * A partilha do ICMS com o estado de destino. O sistema calcula sozinho a parte
 * que é regra (a alíquota entre estados vem de resolução do Senado), mas a
 * alíquota interna de cada estado é lei estadual e muda: quem informa é o
 * contador. Sem ela, a nota para com um aviso dizendo exatamente isso.
 */
function EstadosDeDestino({ regras, mudar }: { regras: RegrasDeMercadoria; mudar: (parcial: Partial<RegrasDeMercadoria>) => void }) {
  const estados = Object.keys(regras.aliquotaInternaPorUf ?? {}).sort();
  const disponiveis = UFS.filter((uf) => !estados.includes(uf));

  const mudarEstado = (uf: string, campo: "interna" | "fcp", valor: number | null) => {
    const internas = { ...(regras.aliquotaInternaPorUf ?? {}) };
    const fcps = { ...(regras.fcpPorUf ?? {}) };
    if (campo === "interna") {
      if (valor === null) delete internas[uf];
      else internas[uf] = valor;
    } else if (valor === null) delete fcps[uf];
    else fcps[uf] = valor;
    mudar({ aliquotaInternaPorUf: internas, fcpPorUf: fcps });
  };

  const tirarEstado = (uf: string) => {
    const internas = { ...(regras.aliquotaInternaPorUf ?? {}) };
    const fcps = { ...(regras.fcpPorUf ?? {}) };
    delete internas[uf];
    delete fcps[uf];
    mudar({ aliquotaInternaPorUf: internas, fcpPorUf: fcps });
  };

  return (
    <div className="space-y-4">
      <p className="text-sm leading-6 text-[var(--ks-color-text-muted)]">
        Quando a empresa vende para uma pessoa física de outro estado, o ICMS é dividido entre os dois estados. Informe aqui a alíquota
        interna do estado de destino — o sistema calcula o resto e põe na nota. Sem isso, a nota para e avisa.
      </p>

      {estados.length === 0 ? (
        <p className="text-sm text-[var(--ks-color-text-soft)]">Nenhum estado informado ainda.</p>
      ) : (
        <ul className="space-y-3">
          {estados.map((uf) => (
            <li key={uf} className="grid grid-cols-[auto_1fr_1fr_auto] items-end gap-3">
              <span className="pb-3 text-sm font-bold tabular-nums text-[var(--ks-color-text-primary)]">{uf}</span>
              <Campo rotulo="Alíquota interna (%)" ajuda={`A alíquota de ICMS que o estado ${uf} cobra nas vendas dentro dele.`}>
                <CampoDecimal
                  valor={regras.aliquotaInternaPorUf?.[uf] ?? null}
                  aoMudar={(n) => mudarEstado(uf, "interna", numeroOuNulo(n))}
                  casas={4}
                  zeroVazio
                  className="ks-field"
                />
              </Campo>
              <Campo rotulo="FCP (%)" opcional ajuda="Fundo de Combate à Pobreza: alguns estados cobram um adicional de 1% a 2%.">
                <CampoDecimal
                  valor={regras.fcpPorUf?.[uf] ?? null}
                  aoMudar={(n) => mudarEstado(uf, "fcp", numeroOuNulo(n))}
                  casas={4}
                  zeroVazio
                  className="ks-field"
                />
              </Campo>
              <button
                type="button"
                onClick={() => tirarEstado(uf)}
                title={`Tirar ${uf}`}
                aria-label={`Tirar ${uf}`}
                className="mb-1 flex h-9 w-9 items-center justify-center rounded-xl text-[var(--ks-color-text-soft)] transition-colors hover:bg-rose-500/10 hover:text-rose-600"
              >
                <Trash2 size={16} />
              </button>
            </li>
          ))}
        </ul>
      )}

      {disponiveis.length ? (
        <div className="max-w-xs">
          <CustomSelect
            options={[{ value: "", label: "Adicionar estado…" }, ...disponiveis.map((uf) => ({ value: uf, label: `${uf} — ${NOME_DO_ESTADO[uf] ?? uf}` }))]}
            value=""
            onChange={(uf) => {
              if (uf) mudarEstado(uf, "interna", 0);
            }}
          />
        </div>
      ) : null}
    </div>
  );
}

function EditorDeServico({
  regras,
  mudar,
  exige,
  cnaes,
  cidade,
}: {
  regras: RegrasDeServico;
  mudar: (parcial: Partial<RegrasDeServico>) => void;
  exige: ReturnType<typeof exigenciasDaCidade>;
  cnaes: Array<{ codigo: string; principal: boolean }>;
  cidade: { codigo: string; nome: string } | null;
}) {
  return (
    <div className="space-y-6">
      <div className="flex items-center gap-2 text-sm font-bold text-[var(--ks-color-text-primary)]">
        <Wrench size={16} className="text-[var(--ks-color-primary)]" /> Nota de serviço
      </div>
      <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
        <Campo
          rotulo="Código do serviço (lista nacional)"
          ajuda="O item da lista da Lei Complementar 116 que descreve o que a empresa faz. Procure pelo nome: adesivo, gráfica, comunicação visual."
          link="lc116"
        >
          <CampoDeCodigo
            tipo="lc116"
            valor={regras.codigoLc116 ?? ""}
            aoMudar={(v) => mudar({ codigoLc116: v || null })}
            somenteDigitos={false}
            maximoDeDigitos={6}
            placeholder="13.05"
          />
        </Campo>
        <Campo rotulo="Alíquota do ISS (%)" ajuda="O imposto da prefeitura sobre o serviço. Vai de 2% a 5% conforme a cidade e o serviço; o contador sabe a sua." dica="No Simples, a da sua faixa. Fora dele, a da prefeitura.">
          <CampoDecimal valor={regras.aliquotaIss} aoMudar={(n) => mudar({ aliquotaIss: numeroOuNulo(n) })} casas={4} zeroVazio className="ks-field" />
        </Campo>
        {exige.codigoMunicipal ? (
          <Campo rotulo="Código do serviço na prefeitura" dica="A prefeitura da sua cidade exige.">
            <input value={regras.codigoMunicipal ?? ""} onChange={(e) => mudar({ codigoMunicipal: e.target.value.trim().slice(0, 20) || null })} className="ks-field tabular-nums" />
          </Campo>
        ) : exige.codigoMunicipalOpcional ? (
          <Campo rotulo="Código do serviço na prefeitura" opcional dica="Só algumas prefeituras têm. Se na nota já emitida o código municipal aparece como um traço, deixe vazio.">
            <input value={regras.codigoMunicipal ?? ""} onChange={(e) => mudar({ codigoMunicipal: e.target.value.trim().slice(0, 20) || null })} className="ks-field tabular-nums" />
          </Campo>
        ) : null}
        {exige.cnae ? (
          <Campo rotulo="Atividade (CNAE)" dica="A prefeitura da sua cidade exige.">
            <CustomSelect
              options={[{ value: "", label: "Escolha" }, ...cnaes.map((c) => ({ value: c.codigo, label: `${c.codigo}${c.principal ? " (principal)" : ""}` }))]}
              value={regras.cnae ?? ""}
              onChange={(v) => mudar({ cnae: v || null })}
            />
          </Campo>
        ) : null}
        {exige.codigoMunicipal ? (
          <div className="col-span-full -mt-2">
            <FormatoDoCodigo
              ibge={cidade?.codigo}
              cidade={cidade?.nome}
              codigo={regras.codigoMunicipal}
              cnae={regras.cnae}
              cnaes={cnaes.map((c) => c.codigo)}
              aoEscolherCnae={exige.cnae ? (cnae) => mudar({ cnae }) : undefined}
            />
          </div>
        ) : null}
        {exige.nbs ? (
          <Campo rotulo="Código NBS" dica="A prefeitura da sua cidade exige.">
            <input value={regras.nbs ?? ""} onChange={(e) => mudar({ nbs: e.target.value.trim().slice(0, 12) || null })} className="ks-field tabular-nums" />
          </Campo>
        ) : null}
        {exige.codigoTributacaoNacional ? (
          <Campo rotulo="Código de tributação nacional">
            <input value={regras.codigoTributacaoNacional ?? ""} onChange={(e) => mudar({ codigoTributacaoNacional: e.target.value.trim().slice(0, 12) || null })} className="ks-field tabular-nums" />
          </Campo>
        ) : null}
        {exige.anexoSimples ? (
          <Campo rotulo="Anexo do Simples Nacional">
            <CustomSelect
              options={[{ value: "", label: "Escolha" }, ...["I", "II", "III", "IV", "V"].map((a) => ({ value: a, label: `Anexo ${a}` }))]}
              value={regras.anexoSimples ?? ""}
              onChange={(v) => mudar({ anexoSimples: (v || null) as RegrasDeServico["anexoSimples"] })}
            />
          </Campo>
        ) : null}
      </div>

      <Campo rotulo="Quem paga o ISS">
        <Escolha
          colunas={3}
          valor={regras.issRetido}
          aoMudar={(issRetido) => mudar({ issRetido })}
          opcoes={[
            { valor: "nunca", titulo: "A empresa", texto: "O cliente não desconta o ISS." },
            { valor: "cliente_pj", titulo: "Cliente com CNPJ desconta", texto: "Quando o cliente é empresa." },
            { valor: "sempre", titulo: "O cliente sempre desconta", texto: "Em toda nota." },
          ]}
        />
      </Campo>

      <Campo rotulo="Informações complementares" dica="Saem na nota de serviço.">
        <textarea value={regras.informacoesAdicionais ?? ""} onChange={(e) => mudar({ informacoesAdicionais: e.target.value.slice(0, 1000) || null })} rows={3} className="ks-field resize-none" />
      </Campo>

      <Recolhivel titulo="Natureza, local do ISS e reforma tributária">
        <div className="grid grid-cols-1 gap-5 md:grid-cols-2">
          <Campo rotulo="Natureza da tributação">
            <CustomSelect
              options={TIPOS_DE_TRIBUTACAO_ISS.map((t) => ({ value: t.valor, label: t.nome }))}
              value={regras.tipoTributacao}
              onChange={(v) => mudar({ tipoTributacao: v as RegrasDeServico["tipoTributacao"] })}
            />
          </Campo>
          <Campo rotulo="Onde o ISS é devido">
            <CustomSelect
              options={[
                { value: "", label: "Na cidade da empresa (padrão)" },
                { value: "customerMunicipality", label: "Na cidade do cliente" },
                { value: "serviceProvisionMunicipality", label: "Onde o serviço foi feito" },
              ]}
              value={regras.localIncidencia ?? ""}
              onChange={(v) => mudar({ localIncidencia: (v || null) as RegrasDeServico["localIncidencia"] })}
            />
          </Campo>
          <Campo rotulo="Situação do PIS/COFINS (padrão nacional)">
            <input value={regras.cstPisCofins ?? ""} onChange={(e) => mudar({ cstPisCofins: soDigitos(e.target.value).slice(0, 2) || null })} className="ks-field tabular-nums" />
          </Campo>
          <Campo rotulo="CST do IBS/CBS" dica="Vazio vale como 000, tributação integral.">
            <CampoDeCodigo
              tipo="cstIbsCbs"
              valor={regras.ibsCbsCst === null ? "" : String(regras.ibsCbsCst).padStart(3, "0")}
              aoMudar={(v) => mudar({ ibsCbsCst: v ? Number(v) : null })}
              maximoDeDigitos={3}
              zerosNaFrente
              placeholder="000"
            />
          </Campo>
          <Campo rotulo="Classificação tributária do IBS/CBS" dica="Vazio vale como 000001, o caso comum.">
            <CampoDeCodigo
              tipo="classificacaoIbsCbs"
              valor={regras.ibsCbsClassificacao === null ? "" : String(regras.ibsCbsClassificacao).padStart(6, "0")}
              aoMudar={(v) => mudar({ ibsCbsClassificacao: Number(v) || null })}
              maximoDeDigitos={6}
              zerosNaFrente
              placeholder="000001"
            />
          </Campo>
          <Campo
            rotulo="Indicador da operação do IBS/CBS"
            opcional
            ajuda="Diz onde o IBS e a CBS são devidos. São seis números e aparecem na nota de serviço já emitida, ao lado do CST."
            dica="Seis números, como 030101. Vazio fica por conta do padrão."
          >
            <input
              value={regras.ibsCbsIndicadorOperacao ?? ""}
              onChange={(e) => mudar({ ibsCbsIndicadorOperacao: soDigitos(e.target.value).slice(0, 6) || null })}
              inputMode="numeric"
              placeholder="030101"
              className="ks-field tabular-nums"
            />
          </Campo>
        </div>
      </Recolhivel>
    </div>
  );
}
