"use client";

/*
 * A linha do tempo do estoque: cada movimento com o que entrou ou saiu, o
 * saldo depois e de onde veio (pedido, compra, produção, contagem, perda),
 * clicável. Serve à empresa inteira (aba Histórico), a um item (gaveta) ou a
 * uma célula.
 */

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { ArrowDownLeft, ArrowUpRight, Factory, Loader2, RefreshCw, Search } from "lucide-react";
import { Input } from "@/components/ui/input";
import { pedirJson } from "@/lib/estoque/use-estoque-v2";
import { nomeDoMovimento, origensDoMovimento, qtd, qtdComSinal, tomDoMovimento } from "@/lib/estoque/regras";
import type { Movimento } from "@/lib/estoque/tipos";

const DATA = new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "2-digit", year: "2-digit", hour: "2-digit", minute: "2-digit" });

const TIPOS_DO_FILTRO: Array<{ id: string; rotulo: string; tipos: string[] }> = [
  { id: "todos", rotulo: "Tudo", tipos: [] },
  { id: "vendas", rotulo: "Vendas", tipos: ["venda", "devolucao"] },
  { id: "compras", rotulo: "Compras e entradas", tipos: ["compra", "entrada", "saldo_inicial"] },
  { id: "producao", rotulo: "Produção", tipos: ["producao_entrada", "producao_saida"] },
  { id: "acertos", rotulo: "Contagens e perdas", tipos: ["contagem", "perda", "estorno_perda", "ajuste"] },
];

export function LinhaDoTempo({
  item,
  celula,
  recarregar,
  aoAbrirProducao,
  aoAbrirItem,
  mostrarItem = false,
  compacta = false,
}: {
  item?: string | null;
  celula?: string | null;
  /** Muda o número para recarregar (depois de um lançamento). */
  recarregar?: number;
  aoAbrirProducao?: (producaoId: string) => void;
  aoAbrirItem?: (itemId: string) => void;
  /** Mostra o item na linha (histórico da empresa inteira). */
  mostrarItem?: boolean;
  compacta?: boolean;
}) {
  const [movimentos, setMovimentos] = useState<Movimento[]>([]);
  const [carregando, setCarregando] = useState(true);
  const [mais, setMais] = useState(false);
  const [erro, setErro] = useState<string | null>(null);
  const [filtro, setFiltro] = useState("todos");
  const [busca, setBusca] = useState("");

  const montarUrl = useCallback(
    (antes?: string) => {
      const p = new URLSearchParams();
      if (item) p.set("item", item);
      if (celula) p.set("celula", celula);
      if (antes) p.set("antes", antes);
      p.set("limite", compacta ? "40" : "80");
      return `/api/estoque/historico?${p.toString()}`;
    },
    [item, celula, compacta]
  );

  const carregar = useCallback(async () => {
    setCarregando(true);
    setErro(null);
    try {
      const r = await pedirJson<{ movimentos: Movimento[]; mais: boolean }>(montarUrl());
      setMovimentos(r.movimentos);
      setMais(r.mais);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não deu para ler a linha do tempo.");
    } finally {
      setCarregando(false);
    }
  }, [montarUrl]);

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

  async function carregarMais() {
    const ultimo = movimentos[movimentos.length - 1];
    if (!ultimo) return;
    setCarregando(true);
    try {
      const r = await pedirJson<{ movimentos: Movimento[]; mais: boolean }>(montarUrl(ultimo.em));
      setMovimentos((atual) => [...atual, ...r.movimentos.filter((m) => !atual.some((a) => a.id === m.id))]);
      setMais(r.mais);
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não deu para ler mais.");
    } finally {
      setCarregando(false);
    }
  }

  const tipos = TIPOS_DO_FILTRO.find((f) => f.id === filtro)?.tipos ?? [];
  const termo = busca.trim().toLowerCase();
  const visiveis = movimentos.filter(
    (m) =>
      (!tipos.length || tipos.includes(m.tipo)) &&
      (!termo ||
        m.rotulo?.toLowerCase().includes(termo) ||
        (m.observacao ?? "").toLowerCase().includes(termo) ||
        String(m.origem?.pedido_numero ?? "").includes(termo))
  );

  return (
    <div>
      <div className="flex flex-wrap items-center gap-2 pb-3">
        <div className="flex gap-1 overflow-x-auto [scrollbar-width:none]">
          {TIPOS_DO_FILTRO.map((f) => (
            <button
              key={f.id}
              type="button"
              onClick={() => setFiltro(f.id)}
              className={`shrink-0 rounded-full px-3 py-1.5 text-[12.5px] font-semibold transition-colors ${
                filtro === f.id ? "bg-[var(--ks-brand-600)] text-white" : "text-[var(--ks-color-text-secondary)] hover:bg-[var(--ks-color-bg-hover)]"
              }`}
            >
              {f.rotulo}
            </button>
          ))}
        </div>
        {!compacta ? (
          <div className="relative ml-auto w-full sm:w-64">
            <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400" />
            <Input placeholder="Item, pedido ou observação" value={busca} onChange={(e) => setBusca(e.target.value)} className="pl-9" />
          </div>
        ) : (
          <button type="button" onClick={() => void carregar()} className="ks-icon-button ml-auto" aria-label="Atualizar">
            <RefreshCw size={15} />
          </button>
        )}
      </div>

      {erro ? <p className="py-3 text-sm text-rose-600">{erro}</p> : null}

      {carregando && !movimentos.length ? (
        <div className="flex justify-center py-10">
          <Loader2 className="h-6 w-6 animate-spin text-[var(--ks-color-primary)]" />
        </div>
      ) : visiveis.length === 0 ? (
        <p className="py-10 text-center text-sm text-[var(--ks-color-text-muted)]">
          {movimentos.length ? "Nenhum movimento com esse filtro." : "Nada se mexeu aqui ainda. Entradas, vendas, produções e contagens aparecem nesta linha do tempo."}
        </p>
      ) : (
        <ol>
          {visiveis.map((m) => {
            const tom = tomDoMovimento(m.quantidade);
            const links = origensDoMovimento(m.origem);
            const dataTexto = DATA.format(new Date(m.em));
            return (
              <li key={m.id} className="flex items-start gap-3 border-t border-slate-100/60 py-3 first:border-t-0">
                <span
                  className={`mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-xl ${
                    m.tipo.startsWith("producao") ? "bg-violet-50 text-violet-600" : tom === "entra" ? "bg-emerald-50 text-emerald-600" : tom === "sai" ? "bg-rose-50 text-rose-600" : "bg-slate-100 text-slate-500"
                  }`}
                  aria-hidden
                >
                  {m.tipo.startsWith("producao") ? <Factory size={15} /> : tom === "sai" ? <ArrowUpRight size={15} /> : <ArrowDownLeft size={15} />}
                </span>
                <div className="min-w-0 flex-1">
                  <div className="flex flex-wrap items-baseline justify-between gap-x-3 gap-y-0.5">
                    <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
                      {nomeDoMovimento(m.tipo, m.quantidade)}
                      {mostrarItem || !celula ? (
                        aoAbrirItem && mostrarItem ? (
                          <button type="button" onClick={() => aoAbrirItem(m.item_id)} className="ml-1.5 font-normal text-[var(--ks-color-text-muted)] hover:text-[var(--ks-color-primary)] hover:underline">
                            · {m.rotulo}
                          </button>
                        ) : (
                          <span className="ml-1.5 font-normal text-[var(--ks-color-text-muted)]">· {m.rotulo}</span>
                        )
                      ) : null}
                    </p>
                    <p className="whitespace-nowrap text-right">
                      <span className={`ks-num text-sm font-bold tabular-nums ${tom === "entra" ? "text-emerald-600" : tom === "sai" ? "text-rose-600" : "text-slate-500"}`}>
                        {qtdComSinal(m.quantidade)}
                      </span>
                      <span className="ml-2 text-xs text-[var(--ks-color-text-soft)]">fica {qtd(m.saldo_depois)}</span>
                    </p>
                  </div>
                  <div className="mt-0.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-[var(--ks-color-text-muted)]">
                    <span className="whitespace-nowrap">{dataTexto}</span>
                    {m.por_nome ? <span>· {m.por_nome}</span> : null}
                    {links.map((l) =>
                      l.href ? (
                        <Link key={l.tipo} href={l.href} className="font-semibold text-[var(--ks-color-primary)] hover:underline">
                          {l.texto}
                        </Link>
                      ) : l.tipo === "producao" && aoAbrirProducao && m.origem.producao_id ? (
                        <button key={l.tipo} type="button" onClick={() => aoAbrirProducao(m.origem.producao_id!)} className="font-semibold text-[var(--ks-color-primary)] hover:underline">
                          {l.texto}
                        </button>
                      ) : (
                        <span key={l.tipo} className="font-medium text-[var(--ks-color-text-secondary)]">
                          {l.texto}
                        </span>
                      )
                    )}
                    {m.custo_unitario !== null && m.custo_unitario !== undefined && Number(m.custo_unitario) > 0 && m.quantidade > 0 ? (
                      <span>· custo {Number(m.custo_unitario).toLocaleString("pt-BR", { style: "currency", currency: "BRL", maximumFractionDigits: 4 })}</span>
                    ) : null}
                  </div>
                  {m.observacao ? <p className="mt-0.5 text-xs italic text-[var(--ks-color-text-soft)]">{m.observacao}</p> : null}
                </div>
              </li>
            );
          })}
        </ol>
      )}

      {mais ? (
        <div className="flex justify-center pt-2">
          <button type="button" onClick={() => void carregarMais()} disabled={carregando} className="ks-button ks-button-secondary ks-button-sm">
            {carregando ? <Loader2 size={14} className="animate-spin" /> : null}
            Ver mais antigos
          </button>
        </div>
      ) : null}
    </div>
  );
}
