"use client";

import { useCallback, useEffect, useState } from "react";
import { Loader2, Undo2 } from "lucide-react";

import { Aviso } from "@/components/ui/aviso";
import { CampoDecimal } from "@/components/ui/campo-decimal";

import { dataCurta, moeda, pedirFiscal } from "./comum";
import { Dica } from "./dica";

type ItemParaDevolver = {
  indice: number;
  descricao: string;
  quantidade: number;
  unidade: string | null;
  valorUnitario: number;
  valorTotal: number;
};

type NotaParaDevolver = {
  id: string;
  numero: number | null;
  chave: string | null;
  emitidaEm: string | null;
  destinatario: { nome: string | null; documento: string | null } | null;
  itens: ItemParaDevolver[];
  jaDevolvida: Array<{ id: string; numero: number | null; status: string; created_at: string }>;
};

/**
 * Devolver uma venda: o cliente trouxe de volta o que comprou.
 *
 * A nota de devolução espelha a venda — mesmos produtos, mesma tributação — e
 * aponta para a nota original item a item, como a SEFAZ passou a exigir. Aqui
 * a pessoa só escolhe o que voltou e diz por quê.
 */
export function PainelDeDevolucao({ notaId, aoEmitir }: { notaId: string; aoEmitir: () => void }) {
  const [nota, setNota] = useState<NotaParaDevolver | null>(null);
  const [quantidades, setQuantidades] = useState<Record<number, number>>({});
  const [motivo, setMotivo] = useState("");
  const [carregando, setCarregando] = useState(true);
  const [enviando, setEnviando] = useState(false);
  const [erro, setErro] = useState<string | null>(null);

  const carregar = useCallback(async () => {
    setCarregando(true);
    setErro(null);
    try {
      const resposta = await pedirFiscal<{ nota: NotaParaDevolver }>(`/api/fiscal/notas/${notaId}/devolucao`);
      setNota(resposta.nota);
      setQuantidades(Object.fromEntries(resposta.nota.itens.map((item) => [item.indice, item.quantidade])));
    } catch (e) {
      setErro(e instanceof Error ? e.message : "Não foi possível abrir a devolução.");
    } finally {
      setCarregando(false);
    }
  }, [notaId]);

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

  const escolhidos = (nota?.itens ?? [])
    .map((item) => ({ item, quantidade: Number(quantidades[item.indice] ?? 0) }))
    .filter((linha) => linha.quantidade > 0);
  const total = escolhidos.reduce((soma, linha) => soma + (linha.item.valorUnitario || 0) * linha.quantidade, 0);
  const podeEmitir = escolhidos.length > 0 && motivo.trim().length >= 5 && !enviando;

  const emitir = async () => {
    setEnviando(true);
    setErro(null);
    try {
      await pedirFiscal(`/api/fiscal/notas/${notaId}/devolucao`, {
        method: "POST",
        json: { motivo: motivo.trim(), itens: escolhidos.map((linha) => ({ indice: linha.item.indice, quantidade: linha.quantidade })) },
      });
      aoEmitir();
    } catch (e) {
      setErro(e instanceof Error ? e.message : "A nota de devolução não saiu.");
    } finally {
      setEnviando(false);
    }
  };

  if (carregando) {
    return (
      <div className="flex items-center justify-center rounded-2xl bg-[var(--ks-color-bg-inset)] py-8">
        <Loader2 size={18} className="animate-spin text-[var(--ks-color-text-soft)]" />
      </div>
    );
  }

  return (
    <div className="space-y-4 rounded-2xl bg-[var(--ks-color-bg-inset)] p-4">
      <div>
        <p className="flex items-center text-sm font-bold text-[var(--ks-color-text-primary)]">
          O que o cliente devolveu?
          <Dica titulo="Nota de devolução">
            A empresa emite uma nota de entrada espelhando a venda, com os mesmos impostos e apontando para a nota original. É assim que a
            mercadoria volta para o estoque e o imposto é recuperado.
          </Dica>
        </p>
        <p className="text-xs leading-5 text-[var(--ks-color-text-muted)]">
          Deixe a quantidade cheia para devolver tudo, ou reduza para devolver só uma parte.
        </p>
      </div>

      {nota?.jaDevolvida.length ? (
        <Aviso tom="atencao">
          Esta nota já tem {nota.jaDevolvida.length === 1 ? "uma devolução" : `${nota.jaDevolvida.length} devoluções`}
          {nota.jaDevolvida[0].numero ? ` (a última é a nº ${nota.jaDevolvida[0].numero})` : ""}. Confira antes de emitir outra.
        </Aviso>
      ) : null}

      <ul className="space-y-2">
        {(nota?.itens ?? []).map((item) => (
          <li key={item.indice} className="flex flex-wrap items-end justify-between gap-3 rounded-xl bg-[var(--ks-color-bg-elevated)] px-3 py-2">
            <div className="min-w-0 flex-1">
              <p className="truncate text-sm font-semibold text-[var(--ks-color-text-primary)]">{item.descricao}</p>
              <p className="text-xs text-[var(--ks-color-text-muted)]">
                Vendidos {item.quantidade} {item.unidade ?? "un"} · {moeda(item.valorUnitario)} cada
              </p>
            </div>
            <label className="w-28 space-y-1">
              <span className="block text-[11px] font-semibold uppercase tracking-[0.08em] text-[var(--ks-color-text-soft)]">Devolver</span>
              <CampoDecimal
                valor={quantidades[item.indice] ?? 0}
                aoMudar={(n) => setQuantidades((antes) => ({ ...antes, [item.indice]: Math.min(item.quantidade, Math.max(0, n)) }))}
                casas={4}
                zeroVazio
                className="ks-field h-9"
              />
            </label>
          </li>
        ))}
      </ul>

      <label className="block space-y-1">
        <span className="text-sm font-semibold text-[var(--ks-color-text-primary)]">Por que está voltando</span>
        <input
          value={motivo}
          onChange={(e) => setMotivo(e.target.value.slice(0, 200))}
          placeholder="Ex.: produto com defeito na impressão"
          className="ks-field"
        />
      </label>

      {erro ? <Aviso tom="ruim">{erro}</Aviso> : null}

      <div className="flex flex-wrap items-center justify-between gap-3">
        <p className="text-sm text-[var(--ks-color-text-muted)]">
          Devolvendo <span className="ks-num font-bold text-[var(--ks-color-text-primary)]">{moeda(total)}</span>
          {nota?.numero ? <span className="text-[var(--ks-color-text-soft)]"> · nota de origem nº {nota.numero}</span> : null}
          {nota?.emitidaEm ? <span className="text-[var(--ks-color-text-soft)]"> de {dataCurta(nota.emitidaEm)}</span> : null}
        </p>
        <button type="button" onClick={() => void emitir()} disabled={!podeEmitir} className="ks-button ks-button-primary ks-button-sm">
          {enviando ? <Loader2 size={14} className="animate-spin" /> : <Undo2 size={14} />}
          Emitir devolução
        </button>
      </div>
    </div>
  );
}
