"use client";

/*
 * Conferir: o que merece um olhar no estoque. Cada achado diz o que é, por
 * que importa e o que fazer, com o botão que leva lá.
 *
 * "Juntar peças repetidas" ainda não existe no motor (os dois itens têm
 * linhas do tempo separadas): a tela explica o caminho manual e abre os dois.
 */

import { useCallback, useEffect, useState, type ReactNode } from "react";
import Link from "next/link";
import { CheckCircle2, ClipboardCheck, Copy, Loader2, MinusCircle, PackageX, RefreshCw, Scale, Unlink, AlertTriangle } from "lucide-react";
import { Aviso } from "@/components/ui/aviso";
import { pedirJson } from "@/lib/estoque/use-estoque-v2";
import { qtd, textoDaCombinacao, valoresDaCelula } from "@/lib/estoque/regras";
import type { Conferencia } from "@/lib/estoque/tipos";

function Bloco({
  Icone,
  cor,
  titulo,
  texto,
  quantos,
  children,
}: {
  Icone: typeof Scale;
  cor: string;
  titulo: string;
  texto: string;
  quantos: number;
  children: ReactNode;
}) {
  if (!quantos) return null;
  return (
    <section className="border-t border-[var(--ks-color-border-subtle)] px-5 py-5 first:border-t-0 sm:px-6">
      <header className="mb-3 flex items-start gap-3">
        <span className="flex h-9 w-9 shrink-0 items-center justify-center rounded-xl text-white" style={{ background: cor }}>
          <Icone size={17} />
        </span>
        <div className="min-w-0">
          <h3 className="flex items-center gap-2 text-[15px] font-extrabold tracking-tight text-[var(--ks-color-text-primary)]">
            {titulo}
            <span className="ks-num rounded-full bg-slate-100 px-2 py-0.5 text-[11px] font-bold text-slate-600">{quantos}</span>
          </h3>
          <p className="text-[13px] leading-5 text-[var(--ks-color-text-muted)]">{texto}</p>
        </div>
      </header>
      <ul>{children}</ul>
    </section>
  );
}

function Linha({ children, acao }: { children: ReactNode; acao?: ReactNode }) {
  return (
    <li className="flex flex-wrap items-center justify-between gap-3 border-t border-slate-100/60 py-2.5 first:border-t-0">
      <div className="min-w-0 flex-1 text-sm text-[var(--ks-color-text-primary)]">{children}</div>
      {acao ? <div className="flex shrink-0 flex-wrap gap-1.5">{acao}</div> : null}
    </li>
  );
}

const VERMELHO = "linear-gradient(135deg, #ff4d4f 0%, #e01329 100%)";
const VIOLETA = "linear-gradient(135deg, var(--ks-brand-500) 0%, var(--ks-brand-700) 100%)";
const CINZA = "linear-gradient(135deg, var(--ks-n-400) 0%, var(--ks-n-600) 100%)";

export function ConferirEstoque({
  aoAbrirItem,
  aoContar,
  recarregar,
  aoContagem,
}: {
  aoAbrirItem: (itemId: string) => void;
  aoContar: (itemId: string, celulaId?: string | null) => void;
  recarregar: number;
  aoContagem?: (n: number) => void;
}) {
  const [c, setC] = useState<Conferencia | null>(null);
  const [erro, setErro] = useState<string | null>(null);
  const [carregando, setCarregando] = useState(true);

  const carregar = useCallback(async () => {
    setCarregando(true);
    try {
      const r = await pedirJson<Conferencia>("/api/estoque/conferir");
      setC(r);
      setErro(null);
      aoContagem?.(
        r.divergencias.length + r.sem_celula.length + r.negativos.length + r.duplicados.length
      );
    } catch (e) {
      setErro((e as Error).message);
    } finally {
      setCarregando(false);
    }
  }, [aoContagem]);

  useEffect(() => {
    void carregar();
  }, [carregar, recarregar]);

  if (erro) return <Aviso tom="ruim">{erro}</Aviso>;
  if (!c) {
    return (
      <div className="flex justify-center py-16">
        <Loader2 className="h-8 w-8 animate-spin text-[var(--ks-color-primary)]" />
      </div>
    );
  }

  const total = c.divergencias.length + c.sem_celula.length + c.negativos.length + c.no_minimo.length + c.duplicados.length + c.fora_de_composicao.length;
  const botao = "ks-button ks-button-secondary ks-button-sm";

  return (
    <div className="ks-surface overflow-hidden rounded-xl border border-[var(--ks-color-border-subtle)] shadow-sm">
      <div className="flex flex-wrap items-center justify-between gap-3 border-b border-[var(--ks-color-border-subtle)] bg-[var(--ks-color-bg-subtle)]/30 p-4">
        <p className="text-sm text-[var(--ks-color-text-secondary)]">
          {total === 0 ? (
            <span className="flex items-center gap-2 font-semibold text-emerald-700">
              <CheckCircle2 size={16} /> Tudo conferido: nenhum saldo diferente, negativo ou peça repetida.
            </span>
          ) : (
            <>A conferência olha a empresa inteira: saldos que não batem, células negativas ou no mínimo, peças repetidas e insumos que nenhum produto usa.</>
          )}
        </p>
        <button type="button" onClick={() => void carregar()} disabled={carregando} className="ks-button ks-button-secondary ks-button-sm">
          {carregando ? <Loader2 size={14} className="animate-spin" /> : <RefreshCw size={14} />} Conferir de novo
        </button>
      </div>

      <Bloco
        Icone={Scale}
        cor={VERMELHO}
        titulo="Saldo que não bate"
        texto="O saldo guardado é diferente da soma dos movimentos (ou do campo antigo do produto). Conte de novo: a contagem acerta e fica registrada."
        quantos={c.divergencias.length}
      >
        {c.divergencias.map((d, i) => {
          const itemId = typeof d.item_id === "string" ? d.item_id : null;
          const celulaId = typeof d.celula_id === "string" ? d.celula_id : null;
          return (
            <Linha
              key={i}
              acao={
                d.tipo === "espelho_diferente" && typeof d.produto_id === "string" ? (
                  <Link href={`/dashboard/products/${d.produto_id}`} className={botao}>
                    Abrir produto
                  </Link>
                ) : itemId ? (
                  <button type="button" className={botao} onClick={() => aoContar(itemId, celulaId)}>
                    <ClipboardCheck size={14} /> Acertar pela contagem
                  </button>
                ) : null
              }
            >
              {d.tipo === "item_diferente_das_celulas" ? (
                <>
                  <strong>{String(d.nome)}</strong>: o item diz {qtd(Number(d.saldo_do_item))}, as células somam {qtd(Number(d.soma_das_celulas))}.
                </>
              ) : d.tipo === "celula_diferente_da_linha_do_tempo" ? (
                <>
                  <strong>{String(d.rotulo)}</strong>: saldo {qtd(Number(d.saldo))}, a linha do tempo soma {qtd(Number(d.soma_dos_movimentos))}.
                </>
              ) : (
                <>
                  <strong>{String(d.produto)}</strong> ({textoDaCombinacao((d.combinacao as Record<string, string>) ?? {})}): o campo antigo mostra {qtd(Number(d.campo_antigo))}, a célula tem{" "}
                  {qtd(Number(d.celula))}.
                </>
              )}
            </Linha>
          );
        })}
      </Bloco>

      <Bloco
        Icone={Unlink}
        cor={VERMELHO}
        titulo="Produto pronto sem célula"
        texto="A venda deste produto não sabe de onde tirar. Ligue o item pronto ou a variação à célula na aba Estoque do produto."
        quantos={c.sem_celula.length}
      >
        {c.sem_celula.map((s, i) => (
          <Linha
            key={i}
            acao={
              <Link href={`/dashboard/products/${s.produto_id}?aba=estoque`} className={botao}>
                Ligar no produto
              </Link>
            }
          >
            <strong>{s.produto}</strong>
            {s.tipo === "pronto_sem_item" ? " sai como pronto, mas não tem item ligado." : ` · a variação ${textoDaCombinacao(s.combinacao ?? {})} não acha célula.`}
          </Linha>
        ))}
      </Bloco>

      <Bloco
        Icone={MinusCircle}
        cor={VERMELHO}
        titulo="Células negativas"
        texto="Saiu mais do que tinha (venda com “pode ficar negativo” ligado, ou entrada que faltou lançar). Conte a prateleira ou dê a entrada que faltou."
        quantos={c.negativos.length}
      >
        {c.negativos.map((n) => (
          <Linha
            key={n.celula_id}
            acao={
              <>
                <button type="button" className={botao} onClick={() => aoContar(n.item_id, n.celula_id)}>
                  <ClipboardCheck size={14} /> Contar
                </button>
                <button type="button" className="ks-button ks-button-ghost ks-button-sm" onClick={() => aoAbrirItem(n.item_id)}>
                  Abrir
                </button>
              </>
            }
          >
            <strong>{n.nome}</strong> {n.valor1 || n.valor2 ? `(${valoresDaCelula(n)})` : ""}: <span className="ks-num font-bold text-rose-600">{qtd(n.saldo)}</span>
          </Linha>
        ))}
      </Bloco>

      <Bloco
        Icone={AlertTriangle}
        cor={VIOLETA}
        titulo="No mínimo ou abaixo"
        texto="Hora de comprar ou produzir. O mínimo é o que você definiu no item (ou na célula)."
        quantos={c.no_minimo.length}
      >
        {c.no_minimo.map((n) => (
          <Linha
            key={n.celula_id}
            acao={
              <button type="button" className="ks-button ks-button-ghost ks-button-sm" onClick={() => aoAbrirItem(n.item_id)}>
                Abrir
              </button>
            }
          >
            <strong>{n.nome}</strong> {n.valor1 || n.valor2 ? `(${valoresDaCelula(n)})` : ""}: {qtd(n.saldo)} (mínimo {qtd(n.minimo)})
          </Linha>
        ))}
      </Bloco>

      <Bloco
        Icone={Copy}
        cor={VIOLETA}
        titulo="Parece a mesma peça"
        texto="Itens com o mesmo nome. Muito comum: o insumo (camiseta lisa) e o produto pronto com o mesmo nome. Se forem a mesma peça física, guarde num item só."
        quantos={c.duplicados.length}
      >
        {c.duplicados.map((d, i) => (
          <li key={i} className="border-t border-slate-100/60 py-3 first:border-t-0">
            <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">{d.nome}</p>
            <div className="mt-1.5 flex flex-wrap gap-1.5">
              {d.itens.map((it) => (
                <button key={it.item_id} type="button" onClick={() => aoAbrirItem(it.item_id)} className={botao}>
                  {it.papel === "pronto" ? "Pronto" : "Insumo"}: {it.nome} · {qtd(it.saldo)}
                </button>
              ))}
            </div>
            <p className="mt-2 text-xs leading-5 text-[var(--ks-color-text-muted)]">
              Juntar automático ainda não existe (cada item tem a sua linha do tempo). Para juntar: conte o item que vai sair até zerar, dê a mesma
              quantidade de entrada no que fica, troque nas composições e no produto (aba Estoque) e desligue o controle do que sobrou. Se não forem a
              mesma peça, dê nomes diferentes.
            </p>
          </li>
        ))}
      </Bloco>

      <Bloco
        Icone={PackageX}
        cor={CINZA}
        titulo="Insumos que nenhum produto usa"
        texto="Controlados, mas fora de qualquer composição, receita de opção ou serviço: a venda nunca tira nada deles. Ligue numa composição ou desligue o controle."
        quantos={c.fora_de_composicao.length}
      >
        {c.fora_de_composicao.map((f) => (
          <Linha
            key={f.item_id}
            acao={
              <button type="button" className="ks-button ks-button-ghost ks-button-sm" onClick={() => aoAbrirItem(f.item_id)}>
                Abrir
              </button>
            }
          >
            <strong>{f.nome}</strong> · saldo {qtd(f.saldo)}
          </Linha>
        ))}
      </Bloco>
    </div>
  );
}
