"use client";

import type { ReactNode } from "react";
import { AlertTriangle, BellRing, Building2, Clock, CreditCard, FileX2, Landmark, ListChecks, MapPinned, ReceiptText, ShieldAlert } from "lucide-react";

import type { PainelFiscal } from "@/lib/fiscal-owner";

import type { Aba } from "./painel-client";
import { Barra, haQuantoTempo, inteiro, mesPorExtenso, moeda, plural, Selo, type Tom } from "./ui";

const TAREFAS: Record<string, string> = {
  emitir: "Enviar nota à Spedy",
  emitir_pedido: "Nota automática de venda",
  consultar: "Consultar situação da nota",
  baixar_arquivos: "Guardar PDF e XML",
  cancelar: "Cancelar nota",
  conferir_compra: "Conferir compra de pacote",
};

export default function AbaVisaoGeral({ painel, irPara }: { painel: PainelFiscal; irPara: (aba: Aba) => void }) {
  const { resumo, regras, saude, emissores, vigias } = painel;
  const producao = painel.ambiente === "producao";
  const mes = mesPorExtenso(painel.competencia);
  const sobra = Math.max(0, regras.plano_spedy_notas - resumo.notasComValor);
  const usadasNoMes = emissores.reduce((acc, e) => acc + e.usadas, 0);
  const emitindo = emissores.filter((e) => e.status === "ativo").length;
  const suspensas = emissores.filter((e) => e.status === "suspenso").length;
  const percentualDaMargem = resumo.receitaDePacotes > 0 ? Math.round((resumo.margem / resumo.receitaDePacotes) * 100) : null;

  return (
    <div className="grid grid-cols-1 gap-4">
      {/* O plano da Spedy é o custo fixo de tudo: começa por ele. */}
      <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm sm:p-6">
        <div className="flex flex-wrap items-baseline justify-between gap-x-4 gap-y-1">
          <h2 className="text-sm font-semibold text-slate-900">
            {producao ? "Plano da Spedy" : "Conta de testes da Spedy"} <span className="font-normal text-slate-400">· {mes}</span>
          </h2>
          {producao ? (
            <span className="text-xs text-slate-500">
              {moeda(regras.plano_spedy_valor)} por mês · {plural(regras.plano_spedy_notas, "nota incluída", "notas incluídas")} ·{" "}
              {moeda(regras.plano_spedy_nota_excedente, 3)} a excedente
            </span>
          ) : (
            <span className="text-xs text-slate-500">Nada aqui tem valor fiscal</span>
          )}
        </div>

        {producao ? (
          <>
            <div className="mt-4 flex flex-wrap items-end gap-x-3 gap-y-1">
              <span className="text-4xl font-semibold tracking-tight text-slate-900 tabular-nums">{inteiro(resumo.notasComValor)}</span>
              <span className="pb-1.5 text-sm text-slate-500">de {inteiro(regras.plano_spedy_notas)} notas com valor fiscal</span>
            </div>
            <div className="mt-3">
              <Barra valor={resumo.notasComValor} maximo={regras.plano_spedy_notas} />
            </div>
            <p className="mt-3 text-sm text-slate-600">
              {resumo.notasExcedentes > 0 ? (
                <>
                  Passou {plural(resumo.notasExcedentes, "nota", "notas")} do plano:{" "}
                  <strong className="text-rose-700">{moeda(resumo.notasExcedentes * regras.plano_spedy_nota_excedente)}</strong> a mais na
                  fatura.
                </>
              ) : (
                <>Ainda cabem {plural(sobra, "nota", "notas")} no plano deste mês.</>
              )}
            </p>
            <p className="mt-1 text-xs leading-5 text-slate-500">
              Conta as notas autorizadas no mês, inclusive as canceladas depois.
              {resumo.notasEmTeste > 0
                ? ` Fora dela: ${plural(resumo.notasEmTeste, "nota de teste", "notas de teste")} em homologação — se a Spedy cobrar homologação, some estas também.`
                : ""}
            </p>
          </>
        ) : (
          <>
            <div className="mt-4 flex flex-wrap items-end gap-x-3 gap-y-1">
              <span className="text-4xl font-semibold tracking-tight text-slate-900 tabular-nums">
                {inteiro(resumo.notasComValor + resumo.notasEmTeste)}
              </span>
              <span className="pb-1.5 text-sm text-slate-500">notas de teste autorizadas no mês</span>
            </div>
            <p className="mt-3 text-sm text-slate-600">
              O sandbox serve para configurar e testar empresas antes da produção. Custo e margem valem só para o ambiente de produção.
            </p>
          </>
        )}
      </section>

      {/* Dinheiro do mês */}
      <div className="grid gap-4 md:grid-cols-3">
        <Numero
          icone={<ReceiptText size={18} />}
          rotulo="Receita de pacotes"
          valor={moeda(resumo.receitaDePacotes)}
          detalhe={`${plural(resumo.comprasAprovadas, "compra aprovada", "compras aprovadas")} em ${mes}`}
        />
        <Numero
          icone={<CreditCard size={18} />}
          rotulo="Custo da Spedy"
          valor={producao ? moeda(resumo.custoSpedy) : "—"}
          detalhe={producao ? (resumo.notasExcedentes > 0 ? "Plano mais as notas excedentes" : "Valor fixo do plano, com ou sem notas") : "Só em produção"}
        />
        <Numero
          icone={<ListChecks size={18} />}
          rotulo="Margem estimada"
          valor={producao ? moeda(resumo.margem) : "—"}
          tomDoValor={producao ? (resumo.margem >= 0 ? "text-emerald-700" : "text-rose-700") : undefined}
          detalhe={
            !producao
              ? "Só em produção"
              : percentualDaMargem === null
                ? "Sem venda de pacote neste mês ainda"
                : `${percentualDaMargem}% do que entrou com pacotes`
          }
        />
      </div>

      <div className="grid gap-4 md:grid-cols-2">
        <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
          <div className="flex items-center justify-between gap-3">
            <div className="flex items-center gap-2 text-sm font-semibold text-slate-900">
              <span className="rounded-lg bg-slate-100 p-1.5 text-slate-600">
                <Building2 size={16} />
              </span>
              Empresas emissoras
            </div>
            <button type="button" onClick={() => irPara("empresas")} className="text-sm font-medium text-slate-600 hover:text-slate-900">
              Ver empresas
            </button>
          </div>
          <p className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 tabular-nums">
            {inteiro(resumo.vagasUsadas)} <span className="text-base font-normal text-slate-500">de {inteiro(regras.limite_emissores)} vagas</span>
          </p>
          <div className="mt-3">
            <Barra valor={resumo.vagasUsadas} maximo={regras.limite_emissores} />
          </div>
          <p className="mt-3 text-xs text-slate-500">
            {plural(emitindo, "emitindo", "emitindo")}
            {suspensas ? ` · ${plural(suspensas, "suspensa", "suspensas")}` : ""}
            {emissores.length - emitindo - suspensas > 0 ? ` · ${plural(emissores.length - emitindo - suspensas, "configurando", "configurando")}` : ""}
            . A vaga conta quando a empresa é cadastrada na Spedy.
          </p>
        </section>

        <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
          <div className="flex items-center justify-between gap-3">
            <div className="flex items-center gap-2 text-sm font-semibold text-slate-900">
              <span className="rounded-lg bg-slate-100 p-1.5 text-slate-600">
                <ReceiptText size={16} />
              </span>
              Notas das empresas em {mes}
            </div>
            <button type="button" onClick={() => irPara("compras")} className="text-sm font-medium text-slate-600 hover:text-slate-900">
              Ver compras
            </button>
          </div>
          <p className="mt-4 text-2xl font-semibold tracking-tight text-slate-900 tabular-nums">
            {inteiro(usadasNoMes)}{" "}
            <span className="text-base font-normal text-slate-500">usadas de {inteiro(resumo.notasVendidas)} liberadas</span>
          </p>
          <div className="mt-3">
            <Barra valor={usadasNoMes} maximo={resumo.notasVendidas} tom="violeta" />
          </div>
          <p className="mt-3 text-xs text-slate-500">Pacotes e cortesias do mês. O que sobrar não passa para o mês seguinte.</p>
        </section>
      </div>

      {/* Saúde */}
      <section className="rounded-2xl border border-slate-200 bg-white shadow-sm">
        <div className="border-b border-slate-100 px-5 py-4">
          <h2 className="text-sm font-semibold text-slate-900">Saúde da emissão</h2>
          <p className="mt-0.5 text-xs text-slate-500">O que está acontecendo por trás das notas, neste ambiente.</p>
        </div>
        <div className="divide-y divide-slate-100">
          <LinhaDeSaude
            icone={<ListChecks size={16} />}
            titulo="Fila de trabalho"
            detalhe={
              saude.filaAtrasadas > 0
                ? `${plural(saude.filaAtrasadas, "tarefa passou", "tarefas passaram")} da hora há mais de 10 minutos. O servidor deste ambiente pode estar parado ou sem as chaves da Spedy.`
                : saude.filaPendentes > 0
                  ? `${plural(saude.filaPendentes, "tarefa agendada", "tarefas agendadas")} (envios, consultas e arquivos). Anda sozinha.`
                  : "Nada esperando."
            }
            selo={saude.filaAtrasadas > 0 ? { tom: "ambar", texto: `${saude.filaAtrasadas} atrasada${saude.filaAtrasadas === 1 ? "" : "s"}` } : { tom: "verde", texto: "Em dia" }}
          />
          <LinhaDeSaude
            icone={<Clock size={16} />}
            titulo="Notas paradas no caminho"
            detalhe={
              vigias.notasTravadas.length
                ? `${plural(vigias.notasTravadas.length, "nota está", "notas estão")} há mais de 30 minutos sem resposta: ${vigias.notasTravadas
                    .slice(0, 3)
                    .map((n) => `${n.empresa ?? "empresa"} (${n.modelo.toUpperCase()})`)
                    .join(", ")}. A fila consulta sozinha, mas vale olhar se o serviço de notas está no ar.`
                : "Nenhuma nota parada. Tudo que saiu já teve resposta."
            }
            selo={
              vigias.notasTravadas.length
                ? { tom: "ambar", texto: `${vigias.notasTravadas.length} parada${vigias.notasTravadas.length === 1 ? "" : "s"}` }
                : { tom: "verde", texto: "Em dia" }
            }
          />
          <LinhaDeSaude
            icone={<ShieldAlert size={16} />}
            titulo="Certificados vencendo"
            detalhe={
              vigias.certificadosVencendo.length
                ? vigias.certificadosVencendo
                    .slice(0, 4)
                    .map((c) => `${c.empresa}: ${(c.dias ?? 0) <= 0 ? "vencido" : `${c.dias} dia${c.dias === 1 ? "" : "s"}`}`)
                    .join(" · ")
                : "Nenhum certificado vence nos próximos 30 dias."
            }
            selo={
              vigias.certificadosVencendo.some((c) => (c.dias ?? 0) <= 0)
                ? { tom: "vermelho", texto: "Vencido" }
                : vigias.certificadosVencendo.length
                  ? { tom: "ambar", texto: `${vigias.certificadosVencendo.length} para renovar` }
                  : { tom: "verde", texto: "Em dia" }
            }
          />
          <LinhaDeSaude
            icone={<CreditCard size={16} />}
            titulo="Contestações e estornos de pacotes"
            detalhe={
              vigias.contestacoes.length
                ? `${vigias.contestacoes
                    .slice(0, 4)
                    .map((c) => `${c.empresa}: ${c.pacote} (${moeda(c.preco)}) ${c.status === "contestada" ? "contestado" : "estornado"} em ${new Date(c.quando).toLocaleDateString("pt-BR")}`)
                    .join(" · ")}. As notas já saíram e não voltam: quem contestou não compra de novo até o suporte liberar; se for má-fé, suspenda o emissor na aba Empresas.`
                : "Nenhum pagamento de pacote contestado ou estornado nos últimos 90 dias."
            }
            selo={
              vigias.contestacoes.some((c) => c.status === "contestada")
                ? { tom: "vermelho", texto: `${vigias.contestacoes.filter((c) => c.status === "contestada").length} contestação${vigias.contestacoes.filter((c) => c.status === "contestada").length === 1 ? "" : "ões"}` }
                : vigias.contestacoes.length
                  ? { tom: "ambar", texto: `${vigias.contestacoes.length} estorno${vigias.contestacoes.length === 1 ? "" : "s"}` }
                  : { tom: "verde", texto: "Em dia" }
            }
          />
          <LinhaDeSaude
            icone={<Landmark size={16} />}
            titulo="Alíquotas da reforma tributária"
            detalhe={`As notas saem com IBS ${vigias.reforma.ibsUf}% e CBS ${vigias.reforma.cbs}%, que valem no período de teste até ${new Date(`${vigias.reforma.valeAte}T12:00:00Z`).toLocaleDateString("pt-BR")}. Quando o cronograma virar, estas alíquotas precisam ser atualizadas no sistema.`}
            selo={
              vigias.reforma.situacao === "vencidas"
                ? { tom: "vermelho", texto: "Vencidas" }
                : vigias.reforma.situacao === "vence_em_breve"
                  ? { tom: "ambar", texto: "Vence em breve" }
                  : { tom: "verde", texto: "Valendo" }
            }
          />
          <LinhaDeSaude
            icone={<BellRing size={16} />}
            titulo="Avisos da Spedy"
            detalhe={
              saude.ultimoAvisoSpedy
                ? `Último aviso ${haQuantoTempo(saude.ultimoAvisoSpedy)} (qualquer ambiente).`
                : "Nenhum aviso recebido. Sem eles a fila consulta cada nota sozinha, só demora um pouco mais para atualizar."
            }
            selo={saude.ultimoAvisoSpedy ? { tom: "verde", texto: "Chegando" } : { tom: "cinza", texto: "Nenhum ainda" }}
          />
          <LinhaDeSaude
            icone={<CreditCard size={16} />}
            titulo="Avisos do Mercado Pago"
            detalhe={
              saude.ultimoAvisoMercadoPago
                ? `Último aviso ${haQuantoTempo(saude.ultimoAvisoMercadoPago)} (qualquer ambiente).`
                : "Chegam quando alguém paga um pacote. Sem aviso, a compra é conferida a cada 10 minutos."
            }
            selo={saude.ultimoAvisoMercadoPago ? { tom: "verde", texto: "Chegando" } : { tom: "cinza", texto: "Nenhum ainda" }}
          />
          <LinhaDeSaude
            icone={<AlertTriangle size={16} />}
            titulo="Avisos que falharam"
            detalhe={
              saude.avisosComFalha > 0
                ? "Entre os últimos 100 avisos recebidos, alguns não foram processados. A fila confere as notas e compras de novo sozinha."
                : "Os últimos avisos recebidos foram processados."
            }
            selo={saude.avisosComFalha > 0 ? { tom: "vermelho", texto: String(saude.avisosComFalha) } : { tom: "verde", texto: "Nenhum" }}
          />
          <LinhaDeSaude
            icone={<MapPinned size={16} />}
            titulo="Notas de serviço recusadas pelas prefeituras"
            detalhe={
              vigias.servicosRecusados.length
                ? `${plural(vigias.servicosRecusados.length, "nota de serviço recusada", "notas de serviço recusadas")} nos últimos 30 dias, ainda sem reenvio: ${vigias.servicosRecusados
                    .slice(0, 3)
                    .map((n) => `${n.empresa}${n.cidade ? ` (${n.cidade})` : ""}`)
                    .join(", ")}. Cada prefeitura tem o seu sistema, e a primeira recusa de uma cidade mostra o que ela exige. A lista está logo abaixo.`
                : "Nenhuma nota de serviço recusada nos últimos 30 dias."
            }
            selo={
              vigias.servicosRecusados.length
                ? { tom: "ambar", texto: `${vigias.servicosRecusados.length} recusada${vigias.servicosRecusados.length === 1 ? "" : "s"}` }
                : { tom: "verde", texto: "Nenhuma" }
            }
          />
          <LinhaDeSaude
            icone={<FileX2 size={16} />}
            titulo={`Notas recusadas em ${mes}`}
            detalhe="Rejeitadas pela SEFAZ ou pela prefeitura, ou com erro nos dados. A empresa vê o motivo e o caminho para corrigir na própria nota. Não gastam pacote."
            selo={resumo.rejeitadas > 0 ? { tom: "ambar", texto: inteiro(resumo.rejeitadas) } : { tom: "verde", texto: "Nenhuma" }}
          />
        </div>

        {vigias.servicosRecusados.length > 0 ? (
          <div className="border-t border-slate-100 px-5 py-4">
            <h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500">Notas de serviço recusadas pelas prefeituras</h3>
            <p className="mt-1 text-xs leading-5 text-slate-500">
              Somem daqui quando a empresa corrige e reenvia. A mensagem é a da prefeitura, como chegou.
            </p>
            <ul className="mt-3 grid gap-2">
              {vigias.servicosRecusados.map((nota) => (
                <li key={nota.id} className="rounded-xl border border-slate-100 bg-slate-50/70 px-3.5 py-2.5">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="text-sm font-medium text-slate-800">{nota.empresa}</span>
                    <span className="text-xs text-slate-500">{nota.cidade ?? "Cidade não informada"}</span>
                    {nota.provedor ? <Selo tom="cinza">{nota.provedor}</Selo> : null}
                    {nota.codigo ? <Selo tom="ambar">{nota.codigo}</Selo> : null}
                    <span className="text-xs text-slate-400">
                      {moeda(nota.valor)} · {haQuantoTempo(nota.quando)}
                    </span>
                  </div>
                  <p className="mt-1 break-words text-xs leading-5 text-slate-600">{nota.mensagem}</p>
                </li>
              ))}
            </ul>
          </div>
        ) : null}

        {saude.errosRecentes.length > 0 ? (
          <div className="border-t border-slate-100 px-5 py-4">
            <h3 className="text-xs font-semibold uppercase tracking-wider text-slate-500">Erros nas últimas 24 horas</h3>
            <ul className="mt-3 grid gap-2">
              {saude.errosRecentes.map((item) => (
                <li key={item.id} className="rounded-xl border border-slate-100 bg-slate-50/70 px-3.5 py-2.5">
                  <div className="flex flex-wrap items-center gap-2">
                    <span className="text-sm font-medium text-slate-800">{TAREFAS[item.tipo] ?? item.tipo}</span>
                    {item.desistiu ? <Selo tom="vermelho">Parou de tentar</Selo> : <Selo tom="cinza">Vai tentar de novo</Selo>}
                    <span className="text-xs text-slate-400">
                      {plural(item.tentativas, "tentativa", "tentativas")} · {haQuantoTempo(item.quando)}
                    </span>
                  </div>
                  <p className="mt-1 break-words text-xs leading-5 text-slate-600">{item.erro}</p>
                </li>
              ))}
            </ul>
          </div>
        ) : null}
      </section>
    </div>
  );
}

function Numero({
  icone,
  rotulo,
  valor,
  detalhe,
  tomDoValor,
}: {
  icone: ReactNode;
  rotulo: string;
  valor: string;
  detalhe: string;
  tomDoValor?: string;
}) {
  return (
    <section className="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
      <div className="flex items-center gap-2 text-sm font-medium text-slate-500">
        <span className="rounded-lg bg-slate-100 p-1.5 text-slate-600">{icone}</span>
        {rotulo}
      </div>
      <p className={`mt-3 text-2xl font-semibold tracking-tight tabular-nums ${tomDoValor ?? "text-slate-900"}`}>{valor}</p>
      <p className="mt-1 text-xs text-slate-500">{detalhe}</p>
    </section>
  );
}

function LinhaDeSaude({
  icone,
  titulo,
  detalhe,
  selo,
}: {
  icone: ReactNode;
  titulo: string;
  detalhe: string;
  selo: { tom: Tom; texto: string };
}) {
  return (
    <div className="flex items-start gap-3 px-5 py-4">
      <span className="mt-0.5 rounded-lg bg-slate-100 p-1.5 text-slate-500">{icone}</span>
      <div className="min-w-0 flex-1">
        <p className="text-sm font-medium text-slate-900">{titulo}</p>
        <p className="mt-0.5 text-xs leading-5 text-slate-500">{detalhe}</p>
      </div>
      <Selo tom={selo.tom}>{selo.texto}</Selo>
    </div>
  );
}
