"use client";

/*
 * Registrar produção: "fiz 20 camisetas G pretas". Sai a composição × 20 e
 * entra +20 na célula G / Preta do produto pronto. Várias combinações de uma
 * vez (uma linha cada), prévia de cada uma antes de confirmar, e o desfazer
 * logo depois (só enquanto as peças não foram vendidas).
 */

import { useEffect, useState } from "react";
import { Factory, Loader2, Plus, Trash2, Undo2, CheckCircle2 } from "lucide-react";
import { Janela } from "./gaveta";
import { CampoNumero } from "./primitivos";
import { EscolhaDeCombinacao, escolhasIniciais, selecaoDasEscolhas, textoDasEscolhas, type Escolhas } from "./escolha-de-combinacao";
import { ResultadoDaProducao, usePrevia } from "./previa-do-produto";
import { Aviso } from "@/components/ui/aviso";
import { pedirJson } from "@/lib/estoque/use-estoque-v2";
import { qtd } from "@/lib/estoque/regras";
import type { AtributoDoProduto } from "@/lib/estoque/tipos";

type Linha = { id: number; escolhas: Escolhas; quantidade: number };
type Feita = { producao_id: string; texto: string; desfeita?: boolean; erro?: string };

function LinhaDaProducao({
  produtoId,
  atributos,
  linha,
  aoMudar,
  aoTirar,
  podeTirar,
}: {
  produtoId: string;
  atributos: AtributoDoProduto[];
  linha: Linha;
  aoMudar: (l: Linha) => void;
  aoTirar: () => void;
  podeTirar: boolean;
}) {
  const { previa, carregando, erro } = usePrevia(produtoId, linha.escolhas, atributos, linha.quantidade || 1);
  return (
    <div className="grid gap-4 rounded-2xl border border-[var(--ks-color-border-subtle)] p-4 lg:grid-cols-[minmax(0,1fr)_minmax(0,1.1fr)]">
      <div className="space-y-3">
        <EscolhaDeCombinacao atributos={atributos} valor={linha.escolhas} aoMudar={(e) => aoMudar({ ...linha, escolhas: e })} compacta />
        <div className="flex items-end gap-2">
          <label className="block w-40 text-[11px] font-bold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">
            Ficaram prontas
            <CampoNumero valor={linha.quantidade} aoMudar={(n) => aoMudar({ ...linha, quantidade: n })} rotulo="Quantas ficaram prontas" sufixo="un" className="mt-1" />
          </label>
          {podeTirar ? (
            <button type="button" onClick={aoTirar} className="ks-icon-button" aria-label="Tirar esta combinação">
              <Trash2 size={15} />
            </button>
          ) : null}
        </div>
      </div>
      <div className="min-w-0 rounded-xl bg-[var(--ks-color-bg-subtle)]/60 p-3">
        {erro ? <p className="text-sm text-rose-600">{erro}</p> : <ResultadoDaProducao previa={previa} carregando={carregando} />}
      </div>
    </div>
  );
}

export function RegistrarProducao({
  aberta,
  produtos,
  produtoInicial,
  aoFechar,
  aoConcluir,
}: {
  aberta: boolean;
  /** Produtos que dá para produzir aqui (os ligados ao item pronto, ou o próprio). */
  produtos: Array<{ id: string; nome: string }>;
  produtoInicial?: string | null;
  aoFechar: () => void;
  /** Chamado quando algo mudou no estoque (registrou ou desfez). */
  aoConcluir: () => void;
}) {
  const [produtoId, setProdutoId] = useState<string | null>(null);
  const [atributos, setAtributos] = useState<AtributoDoProduto[] | null>(null);
  const [linhas, setLinhas] = useState<Linha[]>([]);
  const [observacao, setObservacao] = useState("");
  const [salvando, setSalvando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [feitas, setFeitas] = useState<Feita[] | null>(null);
  const [chave, setChave] = useState("");

  const chaveAgora = aberta ? `${produtoInicial ?? produtos[0]?.id ?? ""}` : "";
  if (chaveAgora !== chave) {
    setChave(chaveAgora);
    setProdutoId(aberta ? produtoInicial ?? produtos[0]?.id ?? null : null);
    setFeitas(null);
    setErro(null);
    setObservacao("");
  }

  useEffect(() => {
    if (!produtoId) return;
    let vivo = true;
    setAtributos(null);
    pedirJson<{ atributos: AtributoDoProduto[] }>(`/api/estoque/produto/${produtoId}`)
      .then((r) => {
        if (!vivo) return;
        setAtributos(r.atributos ?? []);
        setLinhas([{ id: Date.now(), escolhas: escolhasIniciais(r.atributos ?? []), quantidade: 1 }]);
      })
      .catch((e) => vivo && setErro((e as Error).message));
    return () => {
      vivo = false;
    };
  }, [produtoId]);

  async function registrar() {
    if (!produtoId || !atributos) return;
    const validas = linhas.filter((l) => l.quantidade > 0);
    if (!validas.length) return setErro("Diga quantas peças ficaram prontas.");
    setSalvando(true);
    setErro(null);
    const resultado: Feita[] = [];
    for (const l of validas) {
      try {
        const r = await pedirJson<{ producao_id: string; entrou: { celula: { rotulo: string }; quantidade: number } }>("/api/estoque/producao", {
          method: "POST",
          corpo: { produto_id: produtoId, selected_options: selecaoDasEscolhas(atributos, l.escolhas), quantidade: l.quantidade, observacao: observacao || null },
        });
        resultado.push({ producao_id: r.producao_id, texto: `+${qtd(r.entrou.quantidade)} em ${r.entrou.celula.rotulo}` });
      } catch (e) {
        resultado.push({ producao_id: "", texto: `${textoDasEscolhas(l.escolhas)} × ${qtd(l.quantidade)}`, erro: (e as Error).message });
      }
    }
    setSalvando(false);
    setFeitas(resultado);
    if (resultado.some((f) => f.producao_id)) aoConcluir();
  }

  async function desfazer(id: string) {
    try {
      await pedirJson(`/api/estoque/producao?id=${id}`, { method: "DELETE" });
      setFeitas((a) => (a ?? []).map((f) => (f.producao_id === id ? { ...f, desfeita: true } : f)));
      aoConcluir();
    } catch (e) {
      setFeitas((a) => (a ?? []).map((f) => (f.producao_id === id ? { ...f, erro: (e as Error).message } : f)));
    }
  }

  return (
    <Janela
      aberta={aberta}
      aoFechar={aoFechar}
      largura={980}
      titulo={
        <span className="flex items-center gap-2">
          <Factory className="h-5 w-5 text-[var(--ks-color-primary)]" /> Registrar produção
        </span>
      }
      texto="Diga o que ficou pronto. Os insumos da composição saem do estoque e as peças entram no produto pronto, na célula da combinação."
      rodape={
        feitas ? (
          <button type="button" onClick={aoFechar} className="ks-button ks-button-primary">
            Fechar
          </button>
        ) : (
          <>
            <button type="button" onClick={aoFechar} className="ks-button ks-button-secondary">
              Cancelar
            </button>
            <button type="button" onClick={() => void registrar()} disabled={salvando || !atributos} className="ks-button ks-button-primary">
              {salvando ? <Loader2 size={15} className="animate-spin" /> : <Factory size={15} />}
              Registrar produção
            </button>
          </>
        )
      }
    >
      {feitas ? (
        <ul className="space-y-2">
          {feitas.map((f, i) => (
            <li key={f.producao_id || i} className="flex flex-wrap items-center gap-3 rounded-xl border border-[var(--ks-color-border-subtle)] px-4 py-3">
              {f.erro && !f.producao_id ? (
                <Aviso tom="ruim" titulo={f.texto} className="w-full">
                  {f.erro}
                </Aviso>
              ) : (
                <>
                  <CheckCircle2 size={18} className={f.desfeita ? "text-slate-400" : "text-emerald-600"} />
                  <span className={`flex-1 text-sm font-semibold ${f.desfeita ? "text-slate-400 line-through" : "text-[var(--ks-color-text-primary)]"}`}>{f.texto}</span>
                  {f.desfeita ? (
                    <span className="text-xs font-semibold text-slate-500">desfeita: tudo voltou</span>
                  ) : (
                    <button type="button" onClick={() => void desfazer(f.producao_id)} className="ks-button ks-button-secondary ks-button-sm">
                      <Undo2 size={14} /> Desfazer
                    </button>
                  )}
                  {f.erro ? <p className="w-full text-xs text-rose-600">{f.erro}</p> : null}
                </>
              )}
            </li>
          ))}
        </ul>
      ) : (
        <div className="space-y-4">
          {produtos.length > 1 ? (
            <label className="block max-w-md text-xs font-medium text-[var(--ks-color-text-soft)]">
              Produto
              <select value={produtoId ?? ""} onChange={(e) => setProdutoId(e.target.value)} className="ks-field mt-1">
                {produtos.map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.nome}
                  </option>
                ))}
              </select>
            </label>
          ) : null}
          {!atributos ? (
            <div className="flex justify-center py-8">
              <Loader2 className="h-6 w-6 animate-spin text-[var(--ks-color-primary)]" />
            </div>
          ) : (
            <>
              {linhas.map((l) => (
                <LinhaDaProducao
                  key={l.id}
                  produtoId={produtoId!}
                  atributos={atributos}
                  linha={l}
                  podeTirar={linhas.length > 1}
                  aoMudar={(n) => setLinhas((a) => a.map((x) => (x.id === l.id ? n : x)))}
                  aoTirar={() => setLinhas((a) => a.filter((x) => x.id !== l.id))}
                />
              ))}
              {atributos.length ? (
                <button
                  type="button"
                  onClick={() => setLinhas((a) => [...a, { id: Date.now(), escolhas: escolhasIniciais(atributos), quantidade: 1 }])}
                  className="ks-button ks-button-secondary ks-button-sm"
                >
                  <Plus size={14} /> Outra combinação
                </button>
              ) : null}
              <label className="block text-xs font-medium text-[var(--ks-color-text-soft)]">
                Observação (opcional)
                <input value={observacao} onChange={(e) => setObservacao(e.target.value)} placeholder="Ex.: lote da semana" className="ks-field mt-1" maxLength={300} />
              </label>
            </>
          )}
          {erro ? (
            <Aviso tom="ruim" aoFechar={() => setErro(null)}>
              {erro}
            </Aviso>
          ) : null}
        </div>
      )}
    </Janela>
  );
}
