"use client";

/*
 * A prévia ao vivo: escolha a combinação e veja o que sai do estoque — a
 * MESMA conta que a loja, o PDV e o orçamento fazem na hora da venda
 * (estoque_disponivel). Também a conta da produção (o que sai da composição
 * e em qual célula do pronto entra).
 */

import { useEffect, useRef, useState } from "react";
import { ArrowRight, Loader2, PackageCheck, PackageOpen, Factory } from "lucide-react";
import { EscolhaDeCombinacao, escolhasIniciais, selecaoDasEscolhas, type Escolhas } from "./escolha-de-combinacao";
import { CampoNumero } from "./primitivos";
import { pedirJson } from "@/lib/estoque/use-estoque-v2";
import { qtd, quantoDaParaFazer, unidade, dinheiro } from "@/lib/estoque/regras";
import type { AtributoDoProduto, Celula, Disponibilidade } from "@/lib/estoque/tipos";

export type RespostaDaPrevia = {
  produto: { id: string; nome: string; modo: string };
  venda: Disponibilidade;
  producao: {
    quantidade: number;
    tem_item_pronto: boolean;
    entra: Celula | null;
    falta_entrar: string | null;
    sai: Array<{ celula: Celula | null; item_id: string; nome: string; quantidade: number; falta_escolher: string | null }>;
    custo_total: number;
    custo_unitario: number;
  };
};

export function usePrevia(produtoId: string | null, escolhas: Escolhas, atributos: AtributoDoProduto[], quantidade: number, recarregar = 0) {
  const [previa, setPrevia] = useState<RespostaDaPrevia | null>(null);
  const [carregando, setCarregando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const ultimo = useRef(0);
  const chave = JSON.stringify([produtoId, escolhas, quantidade, recarregar]);
  useEffect(() => {
    if (!produtoId) return;
    const n = ++ultimo.current;
    setCarregando(true);
    const t = setTimeout(() => {
      pedirJson<RespostaDaPrevia>("/api/estoque/previa", {
        method: "POST",
        corpo: { produto_id: produtoId, selected_options: selecaoDasEscolhas(atributos, escolhas), quantidade: quantidade > 0 ? quantidade : 1 },
      })
        .then((r) => {
          if (n === ultimo.current) {
            setPrevia(r);
            setErro(null);
          }
        })
        .catch((e) => n === ultimo.current && setErro((e as Error).message))
        .finally(() => n === ultimo.current && setCarregando(false));
    }, 220);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [chave]);
  return { previa, carregando, erro };
}

/** "Ao vender N sai…" + "Dá para vender agora". */
export function ResultadoDaVenda({ previa, carregando }: { previa: RespostaDaPrevia | null; carregando: boolean }) {
  if (!previa) {
    return (
      <div className="flex justify-center py-6">
        <Loader2 className="h-5 w-5 animate-spin text-[var(--ks-color-primary)]" />
      </div>
    );
  }
  const v = previa.venda;
  const da = quantoDaParaFazer(v);
  const pedido = Number(v.pedido) || 1;
  return (
    <div className={carregando ? "opacity-60 transition-opacity" : "transition-opacity"}>
      <div className="flex flex-wrap items-end justify-between gap-3">
        <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">
          Ao vender {qtd(pedido)} {pedido === 1 ? "unidade" : "unidades"} sai:
        </p>
        {v.motivo === "falta_escolher" ? null : (
          <div className="text-right">
            <p className="text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">Dá para vender agora</p>
            <p className="ks-num text-2xl font-extrabold tabular-nums text-[var(--ks-color-primary)]">
              {da === null ? "sem limite" : qtd(da)}
            </p>
          </div>
        )}
      </div>
      {v.motivo === "falta_escolher" ? (
        <p className="mt-2 rounded-xl bg-[var(--ks-brand-50)] px-3 py-2 text-sm text-[var(--ks-brand-700)]">
          Falta escolher {v.itens.find((i) => i.sem_celula)?.falta_escolher ?? "a variação"} para saber de qual célula sai{" "}
          <strong>{v.itens.find((i) => i.sem_celula)?.nome}</strong>. Na loja o cliente é obrigado a escolher.
        </p>
      ) : null}
      {v.itens.length === 0 ? (
        <p className="mt-2 text-sm text-[var(--ks-color-text-muted)]">
          Nada. Este produto não tira nada do estoque na venda{v.modo === "nenhum" ? " (não controla)" : ""} — e nunca é bloqueado por falta de saldo.
        </p>
      ) : (
        <ul className="mt-2">
          {v.itens.map((it, i) => {
            const depois = Number(it.saldo) - Number(it.precisa);
            const falta = depois < 0 && !it.permite_negativo;
            return (
              <li key={`${it.celula_id ?? it.item_id}-${i}`} className="flex items-center gap-3 border-t border-slate-100/60 py-2 first:border-t-0">
                <span className={`flex h-7 w-7 shrink-0 items-center justify-center rounded-lg ${it.papel === "pronto" ? "bg-emerald-50 text-emerald-600" : "bg-violet-50 text-violet-600"}`}>
                  {it.papel === "pronto" ? <PackageCheck size={14} /> : <PackageOpen size={14} />}
                </span>
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-semibold text-[var(--ks-color-text-primary)]">{it.rotulo ?? it.nome}</p>
                  <p className="text-[11px] text-[var(--ks-color-text-muted)]">
                    {it.sem_celula
                      ? `escolha ${it.falta_escolher ?? "a variação"}`
                      : (it.linhas ?? []).some((l) => String(l.origem).startsWith("composicao:se_opcao") || String(l.origem).startsWith("receita") || String(l.origem).startsWith("servico"))
                        ? "pela opção escolhida"
                        : it.papel === "pronto"
                          ? "produto pronto"
                          : "da composição"}
                  </p>
                </div>
                <div className="text-right">
                  <p className="ks-num text-sm font-bold tabular-nums text-rose-600">−{qtd(it.precisa)} <span className="text-[11px] font-normal text-slate-400">{unidade(it.unidade)}</span></p>
                  {!it.sem_celula ? (
                    <p className={`flex items-center justify-end gap-1 text-[11px] ${falta ? "font-semibold text-rose-600" : "text-[var(--ks-color-text-soft)]"}`}>
                      {qtd(it.saldo)} <ArrowRight size={10} /> {qtd(depois)}
                      {falta ? " · falta" : depois < 0 ? " · fica negativo" : ""}
                    </p>
                  ) : null}
                </div>
              </li>
            );
          })}
        </ul>
      )}
      {v.itens.length > 0 && !v.limita && v.motivo !== "falta_escolher" ? (
        <p className="mt-2 text-[11px] text-[var(--ks-color-text-soft)]">
          Nenhum desses itens trava a venda (todos podem ficar negativos): o número acima é quanto o saldo de hoje cobre.
        </p>
      ) : null}
    </div>
  );
}

/** "Ao produzir N: sai da composição… e entra em…". */
export function ResultadoDaProducao({ previa, carregando }: { previa: RespostaDaPrevia | null; carregando: boolean }) {
  if (!previa) {
    return (
      <div className="flex justify-center py-6">
        <Loader2 className="h-5 w-5 animate-spin text-[var(--ks-color-primary)]" />
      </div>
    );
  }
  const p = previa.producao;
  return (
    <div className={carregando ? "opacity-60 transition-opacity" : "transition-opacity"}>
      <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">
        Ao produzir {qtd(p.quantidade)} sai da composição:
      </p>
      {p.sai.length === 0 ? (
        <p className="mt-1 text-sm text-[var(--ks-color-text-muted)]">Nada controlado. A composição deste produto não tem insumo que baixa estoque (só custo).</p>
      ) : (
        <ul className="mt-1">
          {p.sai.map((s, i) => {
            const depois = s.celula ? s.celula.saldo - s.quantidade : null;
            return (
              <li key={`${s.item_id}-${i}`} className="flex items-center justify-between gap-3 border-t border-slate-100/60 py-1.5 first:border-t-0">
                <span className="min-w-0 truncate text-sm text-[var(--ks-color-text-primary)]">
                  {s.celula?.rotulo ?? s.nome}
                  {!s.celula ? <span className="ml-1 text-xs text-rose-600">(escolha {s.falta_escolher})</span> : null}
                </span>
                <span className="whitespace-nowrap text-right">
                  <span className="ks-num text-sm font-bold text-rose-600">−{qtd(s.quantidade)}</span>
                  {s.celula ? (
                    <span className={`ml-2 text-[11px] ${depois! < 0 ? "font-semibold text-rose-600" : "text-[var(--ks-color-text-soft)]"}`}>
                      {qtd(s.celula.saldo)} → {qtd(depois)}
                    </span>
                  ) : null}
                </span>
              </li>
            );
          })}
        </ul>
      )}
      <div className="mt-3 flex items-center gap-3 rounded-xl bg-emerald-50 px-3 py-2.5">
        <Factory size={16} className="shrink-0 text-emerald-600" />
        <p className="text-sm text-emerald-900">
          {p.entra ? (
            <>
              Entra <strong>+{qtd(p.quantidade)}</strong> em <strong>{p.entra.rotulo}</strong> ({qtd(p.entra.saldo)} → {qtd(p.entra.saldo + p.quantidade)})
            </>
          ) : p.tem_item_pronto ? (
            <>Escolha {p.falta_entrar} para saber em qual célula do produto pronto entra.</>
          ) : (
            <>O produto ainda não está ligado a um item pronto: ligue na aba Estoque do produto.</>
          )}
          {p.custo_total > 0 ? <span className="block text-xs text-emerald-800">Custo de cada peça: {dinheiro(p.custo_unitario)} (vira o custo médio do pronto)</span> : null}
        </p>
      </div>
    </div>
  );
}

/** Prévia completa com o seletor de combinação e a quantidade. */
export function PreviaDoProduto({
  produtoId,
  atributos,
  mostrar = "venda",
  recarregar = 0,
  titulo,
}: {
  produtoId: string;
  atributos: AtributoDoProduto[];
  mostrar?: "venda" | "producao";
  recarregar?: number;
  titulo?: string;
}) {
  const [escolhas, setEscolhas] = useState<Escolhas>(() => escolhasIniciais(atributos));
  const [quantidade, setQuantidade] = useState(1);
  const { previa, carregando, erro } = usePrevia(produtoId, escolhas, atributos, quantidade, recarregar);
  return (
    <div className="grid gap-5 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.1fr)]">
      <div className="space-y-3">
        {titulo ? <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">{titulo}</p> : null}
        <EscolhaDeCombinacao atributos={atributos} valor={escolhas} aoMudar={setEscolhas} compacta />
        <label className="block max-w-[180px] text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">
          Quantidade
          <CampoNumero valor={quantidade} aoMudar={setQuantidade} rotulo="Quantidade da prévia" zeroVazio={false} className="mt-1" />
        </label>
      </div>
      <div className="min-w-0 rounded-2xl bg-[var(--ks-color-bg-subtle)]/60 p-4">
        {erro ? <p className="text-sm text-rose-600">{erro}</p> : mostrar === "venda" ? <ResultadoDaVenda previa={previa} carregando={carregando} /> : <ResultadoDaProducao previa={previa} carregando={carregando} />}
      </div>
    </div>
  );
}
