"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import type { FormEvent } from "react";
import { useSearchParams } from "next/navigation";
import { AnimatePresence, motion } from "framer-motion";
import {
  AlertTriangle,
  CheckCircle2,
  Pencil,
  Plus,
  RefreshCcw,
  RotateCcw,
  Search,
  Trash2,
  TriangleAlert,
  X,
  Tag,
  ShoppingCart,
} from "lucide-react";
import { Building2, Zap, Droplet, Phone, Users, FileText, Wrench, Banknote, Truck } from "lucide-react";
import type { LucideIcon } from "lucide-react";
import { PageHeader } from "@/components/ui/page-header";
import { CustosFixosTab } from "./custos-fixos-tab";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { usePermissoes } from "@/lib/permissoes-do-usuario";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { CustomSelect } from "@/components/ui/custom-select";
import { formatMoney } from "@/lib/utils";
import { PixIcon, CashIcon, CreditCardIcon, DebitCardIcon, TransferIcon } from "@/components/icons/payment-icons";
import { filterAccountsByLiquidationMethod, normalizeLiquidationMethod } from "@/lib/liquidation-accounts";
import { Valor } from "@/components/ui/valor";
/* O dinheiro desta tela passa pelo <Valor>: quem nao tem a permissao de ver
   valores continua abrindo a tela e trabalhando, com os numeros borrados. */
const dinheiro = (v: number) => <Valor>{formatMoney(v)}</Valor>;

type PayableStatus = "PENDING" | "PAID" | "OVERDUE" | "CANCELED";

type AccountsPayable = {
  id: string;
  description: string;
  amount: number;
  due_date: string;
  payment_date: string | null;
  status: PayableStatus;
  bank_account_id: string;
  bank_account_name?: string | null;
  bank_name?: string | null;
  category_id: string | null;
  supplier_id?: string | null;
  supplier_name?: string | null;
  purchase_order_id?: string | null;
  is_recurring: boolean;
  recurrence_rule?: string | null;
  notes?: string | null;
  payment_method?: string | null;
};

type ActionState = {
  id: string;
  type: "pay" | "cancel" | "undo" | "delete" | null;
};

type BankAccountOption = {
  bank_account_id: string;
  name: string | null;
  bank_name: string | null;
  active?: boolean | null;
  type?: string | null;
};

type SupplierOption = {
  id: string;
  name: string;
};

type PayableFormState = {
  description: string;
  amount: string;
  due_date: string;
  bank_account_id: string;
  category_id: string;
  supplier_id: string;
  notes: string;
  is_recurring: boolean;
  recurrence_rule: string;
  /* Usados so no caminho "registrar e liquidar". No caminho de so registrar
     ficam vazios e a conta nasce pendente, como sempre foi. */
  payment_method: string;
  payment_date: string;
};

type PayModalState = {
  payment_date: string;
  bank_account_id: string;
  notes: string;
  amount: string;
  payment_method: string;
};


const statusLabels: Record<PayableStatus, string> = {
  PENDING: "Pendente",
  PAID: "Pago",
  OVERDUE: "Vencido",
  CANCELED: "Cancelado",
};

const statusStyles: Record<PayableStatus, string> = {
  PENDING: "bg-amber-50 text-amber-700 border-amber-200",
  PAID: "bg-emerald-50 text-emerald-700 border-emerald-200",
  OVERDUE: "bg-rose-50 text-rose-700 border-rose-200",
  CANCELED: "bg-slate-100 text-slate-600 border-slate-200",
};

function formatDate(value: string) {
  return new Date(value).toLocaleDateString("pt-BR", { timeZone: "UTC" });
}

function normalizeAmount(value: string) {
  const normalized = value.replace(/\./g, "").replace(",", ".");
  const parsed = Number(normalized);
  return Number.isFinite(parsed) ? parsed : NaN;
}

function todayIsoDate() {
  return new Date().toISOString().slice(0, 10);
}

function bankLabel(account: BankAccountOption) {
  const name = (account.name ?? "").trim() || "Conta";
  const bankName = account.bank_name ? ` · ${account.bank_name}` : "";
  const inactive = account.active === false ? " (inativa)" : "";
  return `${name}${bankName}${inactive}`;
}

const PixSelectIcon = ({ size = 16, className }: { size?: number; className?: string }) => {
  return <PixIcon size={size} className={className} />;
};
const CashSelectIcon = ({ size = 16, className }: { size?: number; className?: string }) => {
  return <CashIcon size={size} className={className} />;
};
const CreditCardSelectIcon = ({ size = 16, className }: { size?: number; className?: string }) => {
  return <CreditCardIcon size={size} className={className} />;
};
const DebitCardSelectIcon = ({ size = 16, className }: { size?: number; className?: string }) => {
  return <DebitCardIcon size={size} className={className} />;
};
const TransferSelectIcon = ({ size = 16, className }: { size?: number; className?: string }) => {
  return <TransferIcon size={size} className={className} />;
};

function formatCurrencyMaskBRL(input: string) {
  const digits = input.replace(/\D/g, "");
  if (!digits) return "";
  const cleanDigits = digits.replace(/^0+/, "");
  const padded = cleanDigits.padStart(3, "0");
  const integer = padded.slice(0, -2);
  const cents = padded.slice(-2);
  const intWithDots = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ".");
  return `${intWithDots},${cents}`;
}

const paymentMethodOptions = [
  { value: "pix", label: "Pix", icon: PixSelectIcon },
  { value: "cash", label: "Dinheiro", icon: CashSelectIcon },
  { value: "credit_card", label: "Cartão de Crédito", icon: CreditCardSelectIcon },
  { value: "debit_card", label: "Cartão de Débito", icon: DebitCardSelectIcon },
  { value: "transfer", label: "Transferência", icon: TransferSelectIcon },
];


const iconMap: Record<string, LucideIcon> = {
  Building2, Zap, Droplet, Phone, Users, FileText, Wrench, Banknote, Truck, Tag, ShoppingCart
};

function getCategoryIcon(iconName: string) {
  return iconMap[iconName] || FileText;
}

const availableIcons = Object.keys(iconMap);

function AccountsPayableRow({
  account,
  onPay,
  onUndo,
  onCancel,
  onEdit,
  onDelete,
  isPaying,
  isUndoing,
  isCanceling,
  isDeleting,
  feedback,
}: {
  account: AccountsPayable;
  onPay: (account: AccountsPayable) => void;
  onUndo: (id: string) => void;
  onCancel: (id: string) => void;
  onEdit: (account: AccountsPayable) => void;
  onDelete: (account: AccountsPayable) => void;
  isPaying: boolean;
  isUndoing: boolean;
  isCanceling: boolean;
  isDeleting: boolean;
  feedback: "paid" | "canceled" | null;
}) {
  const showPay = account.status === "PENDING" || account.status === "OVERDUE";
  const showCancel = account.status === "PENDING";
  const showUndo = account.status === "PAID";
  const isOverdue = account.status === "OVERDUE";

  return (
    <motion.div
      layout
      className="grid grid-cols-1 md:grid-cols-[2.4fr_1fr_1fr_1fr_1.2fr] gap-4 items-center p-4 rounded-2xl border border-zinc-100 bg-white shadow-sm"
    >
      <div className="space-y-1">
        <div className="flex items-center gap-2">
          <p className="text-sm font-semibold text-[var(--ks-color-text-primary)]">
            {account.description}
          </p>
          {account.is_recurring ? (
            <span className="text-xs text-[var(--ks-color-text-muted)]">🔁</span>
          ) : null}
        </div>
        <p className="text-xs text-[var(--ks-color-text-muted)]">
          Vencimento {formatDate(account.due_date)}
        </p>
        <p className="text-xs text-[var(--ks-color-text-muted)]">
          {(account.bank_account_name || account.bank_name) && (
            <>
              {(account.bank_account_name ?? "").trim() || "Conta"}{" "}
              {account.bank_name ? `· ${account.bank_name}` : ""}
            </>
          )}
          {!account.bank_account_name && !account.bank_name ? "Sem conta bancária" : null}
        </p>
        {account.supplier_name ? (
          <div className="flex flex-wrap items-center gap-2 pt-1">
            <span className="inline-flex items-center rounded-full border border-violet-200 bg-violet-50 px-2.5 py-1 text-[11px] font-semibold text-violet-700">
              Fornecedor: {account.supplier_name}
            </span>
            {account.purchase_order_id ? (
              <span className="inline-flex items-center rounded-full border border-sky-200 bg-sky-50 px-2.5 py-1 text-[11px] font-semibold text-sky-700">
                Vinculada a compra
              </span>
            ) : null}
          </div>
        ) : null}
        {account.payment_date ? (
          <p className="text-xs text-[var(--ks-color-text-muted)]">
            Pago em {formatDate(account.payment_date)}
          </p>
        ) : null}
      </div>

      <div>
        <p className="text-xs text-[var(--ks-color-text-muted)]">Valor</p>
        <p className="text-sm font-bold text-[var(--ks-color-text-primary)]">
          {dinheiro(account.amount)}
        </p>
      </div>

      <div>
        <p className="text-xs text-[var(--ks-color-text-muted)]">Vencimento</p>
        <p className={`text-sm font-semibold ${isOverdue ? "text-rose-600" : "text-[var(--ks-color-text-primary)]"}`}>
          {formatDate(account.due_date)}
        </p>
      </div>

      <div>
        <span className={`inline-flex items-center gap-2 text-xs font-semibold px-3 py-1 rounded-full border ${statusStyles[account.status]}`}>
          {account.status === "OVERDUE" ? <TriangleAlert className="w-3.5 h-3.5" /> : null}
          {statusLabels[account.status]}
        </span>
      </div>

      <div className="flex items-center justify-end gap-2">
        {showPay ? (
          <Button
            size="sm"
            icon={isPaying ? <RefreshCcw className="w-4 h-4 animate-spin" /> : <CheckCircle2 className="w-4 h-4" />}
            onClick={() => onPay(account)}
            disabled={isPaying || isCanceling || isUndoing || isDeleting}
            className={isPaying ? "opacity-80" : ""}
          >
            {isPaying ? "Processando" : "Pagar"}
          </Button>
        ) : null}
        {showUndo ? (
          <Button
            variant="ghost"
            size="sm"
            icon={isUndoing ? <RefreshCcw className="w-4 h-4 animate-spin" /> : <RotateCcw className="w-4 h-4" />}
            onClick={() => onUndo(account.id)}
            disabled={isPaying || isCanceling || isUndoing || isDeleting}
            className={isUndoing ? "opacity-80" : ""}
          >
            {isUndoing ? "Desfazendo" : "Desfazer"}
          </Button>
        ) : null}
        {showCancel ? (
          <Button
            variant="ghost"
            size="sm"
            icon={isCanceling ? <RefreshCcw className="w-4 h-4 animate-spin" /> : <RotateCcw className="w-4 h-4" />}
            onClick={() => onCancel(account.id)}
            disabled={isPaying || isCanceling || isUndoing || isDeleting}
            className={isCanceling ? "opacity-80" : ""}
          >
            {isCanceling ? "Cancelando" : "Cancelar"}
          </Button>
        ) : null}
        <div className="flex items-center gap-1">
          <button
            type="button"
            onClick={() => onEdit(account)}
            disabled={isPaying || isCanceling || isUndoing || isDeleting}
            className="p-2 text-[var(--ks-color-text-soft)] hover:text-[var(--ks-color-primary)] hover:bg-[rgba(244,245,255,0.9)] rounded-lg transition-colors disabled:opacity-50"
            title="Editar"
          >
            <Pencil className="w-4 h-4" />
          </button>
          <button
            type="button"
            onClick={() => onDelete(account)}
            disabled={isPaying || isCanceling || isUndoing || isDeleting}
            className="p-2 text-[var(--ks-color-text-soft)] hover:text-rose-600 hover:bg-rose-50 rounded-lg transition-colors disabled:opacity-50"
            title="Excluir"
          >
            {isDeleting ? <RefreshCcw className="w-4 h-4 animate-spin" /> : <Trash2 className="w-4 h-4" />}
          </button>
        </div>
        <AnimatePresence mode="wait">
          {feedback ? (
            <motion.span
              key={feedback}
              initial={{ opacity: 0, y: 6 }}
              animate={{ opacity: 1, y: 0 }}
              exit={{ opacity: 0, y: -6 }}
              className={`text-xs font-semibold px-2.5 py-1 rounded-full ${
                feedback === "paid"
                  ? "bg-emerald-50 text-emerald-700 border border-emerald-200"
                  : "bg-slate-100 text-slate-600 border border-slate-200"
              }`}
            >
              {feedback === "paid" ? "Pago!" : "Cancelado"}
            </motion.span>
          ) : null}
        </AnimatePresence>
      </div>
    </motion.div>
  );
}

export default function AccountsPayablePage() {
  const { pode } = usePermissoes();
  /* Cada coisa pergunta pela propria chave. Lancar conta, dar baixa e mexer
     nos custos fixos sao tres decisoes diferentes do dono — e eram uma so. */
  const podeLancar = pode("financial.payables.write");
  const podeVerCustosFixos = pode("financial.fixedcosts.read");
  const podeEditarCustosFixos = pode("financial.fixedcosts.write");

  const searchParams = useSearchParams();
  const supplierFilterIdFromUrl = searchParams.get("supplier_id")?.trim() ?? "";
  const supplierFilterName = searchParams.get("supplier")?.trim() ?? "";
  const [accounts, setAccounts] = useState<AccountsPayable[]>([]);
  const [loading, setLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState<string | null>(null);
  const [actionState, setActionState] = useState<ActionState>({ id: "", type: null });
  const [feedbackMap, setFeedbackMap] = useState<Record<string, "paid" | "canceled">>({});
  const [bankAccounts, setBankAccounts] = useState<BankAccountOption[]>([]);
  const [suppliers, setSuppliers] = useState<SupplierOption[]>([]);
  const [banksLoading, setBanksLoading] = useState(false);
  const [banksError, setBanksError] = useState<string | null>(null);
  const [statusFilter, setStatusFilter] = useState<PayableStatus | "all">("all");
  const [monthFilter, setMonthFilter] = useState("");
  const [bankFilter, setBankFilter] = useState("");
  const [categoryFilter, setCategoryFilter] = useState("");

  /* A aba: lancamentos (o dia a dia) ou custos-fixos (a estrutura mensal que
     alimenta o Ponto de Equilibrio e a hora da estrutura nos precos). ?tab=
     mantem o link compartilhavel. */
  const [aba, setAba] = useState<"lancamentos" | "custos-fixos">("lancamentos");
  useEffect(() => {
    if (typeof window === "undefined") return;
    if (new URLSearchParams(window.location.search).get("tab") === "custos-fixos") {
      setAba("custos-fixos");
    }
  }, []);
  const trocarAba = (nova: "lancamentos" | "custos-fixos") => {
    setAba(nova);
    if (typeof window !== "undefined") {
      const url = new URL(window.location.href);
      if (nova === "custos-fixos") url.searchParams.set("tab", "custos-fixos");
      else url.searchParams.delete("tab");
      window.history.replaceState({}, "", url.toString());
    }
  };
  const [supplierFilter, setSupplierFilter] = useState(supplierFilterIdFromUrl);
  const [categories, setCategories] = useState<Array<{ id: string; name: string; icon: string }>>([]);
  const [categoriesLoading, setCategoriesLoading] = useState(false);
  
  // Category Creation State
  const [isCategoryModalOpen, setIsCategoryModalOpen] = useState(false);
  const [newCategoryName, setNewCategoryName] = useState("");
  const [newCategoryIcon, setNewCategoryIcon] = useState("Tag");
  const [creatingCategory, setCreatingCategory] = useState(false);

  const [searchTerm, setSearchTerm] = useState("");
  const [isFormOpen, setIsFormOpen] = useState(false);
  /* Assistente do modal de nova conta.
     `modo` decide quais campos existem: quem so vai registrar nao escolhe
     forma de pagamento — nao sabe ainda como vai pagar — e por isso nao ha
     como cair numa combinacao incoerente de metodo x conta. */
  const [wizardModo, setWizardModo] = useState<"registrar" | "liquidar" | null>(null);
  const [wizardPasso, setWizardPasso] = useState(1);
  const [isPayOpen, setIsPayOpen] = useState(false);
  const [editingAccount, setEditingAccount] = useState<AccountsPayable | null>(null);
  const [payingAccount, setPayingAccount] = useState<AccountsPayable | null>(null);
  /* Confirmacao de exclusao com dialogo proprio. O `confirm()` nativo sumia
     em silencio quando o navegador bloqueia dialogos da pagina — o Chrome
     oferece isso depois de alguns seguidos — e o botao parecia sem acao. */
  const [deletingAccount, setDeletingAccount] = useState<AccountsPayable | null>(null);
  const [formError, setFormError] = useState<string | null>(null);
  const [payError, setPayError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [paying, setPaying] = useState(false);
  const [form, setForm] = useState<PayableFormState>(() => ({
    description: "",
    amount: "",
    due_date: todayIsoDate(),
    bank_account_id: "",
    category_id: "",
    supplier_id: supplierFilterIdFromUrl,
    notes: "",
    is_recurring: false,
    recurrence_rule: "",
    payment_method: "",
    payment_date: todayIsoDate(),
  }));
  const [payForm, setPayForm] = useState<PayModalState>(() => ({
    payment_date: todayIsoDate(),
    bank_account_id: "",
    notes: "",
    amount: "",
    payment_method: "cash",
  }));

  const purchaseOrderFilterId = searchParams.get("purchase_order_id")?.trim() ?? "";

  const loadAccounts = useCallback(async () => {
    setLoading(true);
    setErrorMessage(null);
    try {
      const params = new URLSearchParams();
      const selectedSupplierName = supplierFilter
        ? suppliers.find((supplier) => supplier.id === supplierFilter)?.name ?? ""
        : "";
      if (monthFilter) params.set("month", monthFilter);
      if (statusFilter !== "all") params.set("status", statusFilter);
      if (bankFilter) params.set("bank_account_id", bankFilter);
      if (categoryFilter) params.set("category_id", categoryFilter);
      if (supplierFilter) params.set("supplier_id", supplierFilter);
      if (selectedSupplierName) {
        params.set("supplier", selectedSupplierName);
      } else if (supplierFilterName && !supplierFilter) {
        params.set("supplier", supplierFilterName);
      }
      if (purchaseOrderFilterId) params.set("purchase_order_id", purchaseOrderFilterId);
      const query = params.toString();
      const response = await fetch(`/api/accounts-payable${query ? `?${query}` : ""}`);
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload?.error ?? "Falha ao carregar contas a pagar.");
      }
      setAccounts(payload?.accounts ?? []);
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "Falha ao carregar contas a pagar.");
    } finally {
      setLoading(false);
    }
  }, [bankFilter, categoryFilter, monthFilter, purchaseOrderFilterId, statusFilter, supplierFilter, supplierFilterName, suppliers]);

  useEffect(() => {
    if (!supplierFilterName) return;
    setSearchTerm((prev) => prev || supplierFilterName);
  }, [supplierFilterName]);

  useEffect(() => {
    loadAccounts();
  }, [loadAccounts]);

  useEffect(() => {
    let active = true;
    setBanksLoading(true);
    setBanksError(null);
    fetch("/api/bank-accounts")
      .then(async (response) => {
        const payload = await response.json();
        if (!response.ok) {
          throw new Error(payload?.error ?? "Falha ao carregar contas bancárias.");
        }
        return payload?.accounts ?? [];
      })
      .then((accounts) => {
        if (active) setBankAccounts(accounts);
      })
      .catch((fetchError) => {
        if (active) {
          setBanksError(
            fetchError instanceof Error ? fetchError.message : "Falha ao carregar contas bancárias."
          );
        }
      })
      .finally(() => {
        if (active) setBanksLoading(false);
      });

    return () => {
      active = false;
    };
  }, []);

  useEffect(() => {
    let active = true;
    setCategoriesLoading(true);
    fetch("/api/financial/categories")
      .then(async (response) => {
        const payload = await response.json();
        if (!response.ok) throw new Error(payload?.error ?? "Falha ao carregar categorias.");
        return payload?.categories ?? [];
      })
      .then((items) => {
        if (active) setCategories(items);
      })
      .catch(() => null)
      .finally(() => {
        if (active) setCategoriesLoading(false);
      });
    return () => {
      active = false;
    };
  }, []);

  useEffect(() => {
    let active = true;
    fetch("/api/suppliers")
      .then(async (response) => {
        const payload = await response.json();
        if (!response.ok) throw new Error(payload?.error ?? "Falha ao carregar fornecedores.");
        return payload?.suppliers ?? [];
      })
      .then((items) => {
        if (!active) return;
        setSuppliers(
          Array.isArray(items)
            ? items
                .map((item: { id?: string; name?: string }) => ({
                  id: String(item.id || ""),
                  name: String(item.name || ""),
                }))
                .filter((item) => item.id && item.name)
            : []
        );
      })
      .catch(() => {
        if (active) setSuppliers([]);
      });
    return () => {
      active = false;
    };
  }, []);


  const handleCreateCategory = async (e: FormEvent) => {
    e.preventDefault();
    if (!newCategoryName.trim()) return;
    setCreatingCategory(true);
    try {
      const res = await fetch("/api/financial/categories", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: newCategoryName, icon: newCategoryIcon })
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error);
      
      setCategories(prev => [...prev, data.category].sort((a, b) => a.name.localeCompare(b.name)));
      setForm(prev => ({ ...prev, category_id: data.category.id }));
      setIsCategoryModalOpen(false);
      setNewCategoryName("");
      setNewCategoryIcon("Tag");
    } catch (err) {
      alert(err instanceof Error ? err.message : "Erro ao criar categoria");
    } finally {
      setCreatingCategory(false);
    }
  };

  const openCreate = useCallback(() => {
    setEditingAccount(null);
    setForm({
      description: "",
      amount: "",
      due_date: todayIsoDate(),
      bank_account_id: "",
      category_id: "",
      supplier_id: supplierFilter,
      notes: "",
      is_recurring: false,
      recurrence_rule: "",
      payment_method: "",
      payment_date: todayIsoDate(),
    });
    setFormError(null);
    setWizardModo(null);
    setWizardPasso(1);
    setIsFormOpen(true);
  }, [supplierFilter]);

  const closeForm = useCallback(() => {
    setIsFormOpen(false);
    setEditingAccount(null);
    setFormError(null);
  }, []);

  const openEdit = useCallback((account: AccountsPayable) => {
    setEditingAccount(account);
    setForm({
      description: account.description ?? "",
      amount: formatCurrencyMaskBRL((account.amount ?? 0).toFixed(2)),
      due_date: account.due_date ?? todayIsoDate(),
      bank_account_id: account.bank_account_id ?? "",
      category_id: account.category_id ?? "",
      supplier_id: account.supplier_id ?? "",
      notes: account.notes ?? "",
      is_recurring: Boolean(account.is_recurring),
      recurrence_rule: account.recurrence_rule ?? "",
      payment_method: account.payment_method ?? "",
      payment_date: account.payment_date ?? todayIsoDate(),
    });
    setFormError(null);
    /* Editar nao passa pelo assistente: a conta ja existe, e oferecer
       "liquidar agora" aqui daria um segundo caminho para pagar algo que
       talvez ja esteja pago. */
    setWizardModo("registrar");
    setWizardPasso(2);
    setIsFormOpen(true);
  }, []);

  const openPay = useCallback((account: AccountsPayable) => {
    setPayingAccount(account);
    setPayForm({
      payment_date: todayIsoDate(),
      bank_account_id: account.bank_account_id ?? "",
      notes: account.notes ?? "",
      amount: formatCurrencyMaskBRL((account.amount ?? 0).toFixed(2)),
      payment_method: "cash",
    });
    setPayError(null);
    setIsPayOpen(true);
  }, []);

  const closePay = useCallback(() => {
    setIsPayOpen(false);
    setPayingAccount(null);
    setPayError(null);
  }, []);

  /* Valida o passo 2 antes de deixar avancar: descobrir que faltou o valor so
     no fim, depois de preencher o pagamento, e pior do que barrar aqui. */
  const avancarParaPagamento = useCallback(() => {
    const amount = normalizeAmount(form.amount);
    if (!form.description.trim()) return setFormError("Descrição é obrigatória.");
    if (!Number.isFinite(amount) || amount <= 0) return setFormError("Valor inválido.");
    if (!form.due_date) return setFormError("Data de vencimento inválida.");
    setFormError(null);
    setWizardPasso(3);
  }, [form.description, form.amount, form.due_date]);

  const handleSavePayable = useCallback(
    async (event: FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      setSaving(true);
      setFormError(null);
      try {
        const amount = normalizeAmount(form.amount);
        if (!form.description.trim()) {
          throw new Error("Descrição é obrigatória.");
        }
        if (!Number.isFinite(amount) || amount <= 0) {
          throw new Error("Valor inválido.");
        }
        if (!form.due_date) {
          throw new Error("Data de vencimento inválida.");
        }
        if (!form.bank_account_id) {
          throw new Error(
            wizardModo === "liquidar" && form.payment_method === "cash"
              ? "Selecione o caixa físico."
              : "Selecione a conta."
          );
        }

        const vaiLiquidar = wizardModo === "liquidar" && !editingAccount;
        if (vaiLiquidar && !form.payment_method) {
          throw new Error("Selecione a forma de pagamento.");
        }
        if (vaiLiquidar && !form.payment_date) {
          throw new Error("Informe a data do pagamento.");
        }

        const payload = {
          description: form.description.trim(),
          amount,
          due_date: form.due_date,
          bank_account_id: form.bank_account_id,
          category_id: form.category_id || null,
          supplier_id: form.supplier_id || null,
          notes: form.notes || null,
          is_recurring: form.is_recurring,
          recurrence_rule: form.recurrence_rule || null,
          payment_method: form.payment_method || null,
        };

        const response = await fetch("/api/accounts-payable", {
          method: editingAccount ? "PATCH" : "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(
            editingAccount ? { id: editingAccount.id, patch: payload } : payload
          ),
        });
        const data = await response.json();
        if (!response.ok) {
          throw new Error(data?.error ?? "Falha ao salvar conta.");
        }

        /* Liquidar reusa o PATCH "pay", o mesmo caminho do modal da listagem:
           e ele que valida a compatibilidade, lanca no fluxo de caixa sem
           duplicar e gera a proxima parcela da recorrencia. Repetir essa
           logica aqui seria criar uma segunda versao que uma hora divergiria. */
        if (vaiLiquidar) {
          const criada = data?.account;
          const criadaId = typeof criada?.id === "string" ? criada.id : "";
          if (!criadaId) {
            throw new Error("Conta criada, mas não foi possível identificá-la para liquidar.");
          }

          const baixa = await fetch("/api/accounts-payable", {
            method: "PATCH",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              id: criadaId,
              action: "pay",
              payload: {
                payment_date: form.payment_date,
                bank_account_id: form.bank_account_id,
                amount,
                payment_method: form.payment_method,
                notes: form.notes || null,
              },
            }),
          });
          const dadosBaixa = await baixa.json();
          if (!baixa.ok) {
            /* A conta existe: avisar com clareza evita o usuario cadastrar de
               novo e acabar com a despesa duplicada. */
            throw new Error(
              `Conta criada, mas não foi possível liquidar: ${
                dadosBaixa?.error ?? "erro desconhecido"
              }. Ela está na lista como pendente.`
            );
          }
        }

        setIsFormOpen(false);
        setEditingAccount(null);
        await loadAccounts();
      } catch (error) {
        setFormError(error instanceof Error ? error.message : "Falha ao salvar conta.");
      } finally {
        setSaving(false);
      }
    },
    [editingAccount, form, loadAccounts, wizardModo]
  );

  const handleSubmitPayment = useCallback(
    async (event: FormEvent<HTMLFormElement>) => {
      event.preventDefault();
      if (!payingAccount) return;
      setPaying(true);
      setPayError(null);
      setActionState({ id: payingAccount.id, type: "pay" });
      try {
        const amount = normalizeAmount(payForm.amount);
        const payload = {
          payment_date: payForm.payment_date || todayIsoDate(),
          bank_account_id: payForm.bank_account_id,
          notes: payForm.notes || null,
          amount: Number.isFinite(amount) && amount > 0 ? amount : undefined,
          payment_method: payForm.payment_method || null,
        };
        const response = await fetch("/api/accounts-payable", {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ id: payingAccount.id, action: "pay", payload }),
        });
        const data = await response.json();
        if (!response.ok) {
          throw new Error(data?.error ?? "Falha ao pagar conta.");
        }
        setAccounts((prev) =>
          prev.map((account) =>
            account.id === payingAccount.id
              ? {
                  ...account,
                  status: "PAID",
                  payment_date: data?.account?.payment_date ?? payForm.payment_date,
                  bank_account_id: data?.account?.bank_account_id ?? account.bank_account_id,
                  amount: data?.account?.amount ?? account.amount,
                }
              : account
          )
        );
        setFeedbackMap((prev) => ({ ...prev, [payingAccount.id]: "paid" }));
        setIsPayOpen(false);
        setPayingAccount(null);
      } catch (error) {
        setPayError(error instanceof Error ? error.message : "Falha ao pagar conta.");
      } finally {
        setPaying(false);
        setActionState({ id: "", type: null });
      }
    },
    [payForm, payingAccount]
  );

  const handleCancel = useCallback(async (id: string) => {
    setActionState({ id, type: "cancel" });
    setFeedbackMap((prev) => {
      const next = { ...prev };
      delete next[id];
      return next;
    });
    try {
      const response = await fetch(`/api/accounts-payable/${id}/cancel`, { method: "POST" });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload?.error ?? "Falha ao cancelar conta.");
      }
      setAccounts((prev) =>
        prev.map((account) =>
          account.id === id ? { ...account, status: "CANCELED", payment_date: null } : account
        )
      );
      setFeedbackMap((prev) => ({ ...prev, [id]: "canceled" }));
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "Falha ao cancelar conta.");
    } finally {
      setActionState({ id: "", type: null });
    }
  }, []);

  const handleUndo = useCallback(async (id: string) => {
    setActionState({ id, type: "undo" });
    setFeedbackMap((prev) => {
      const next = { ...prev };
      delete next[id];
      return next;
    });
    try {
      const response = await fetch("/api/accounts-payable", {
        method: "PATCH",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id, action: "undo_pay" }),
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload?.error ?? "Falha ao desfazer pagamento.");
      }
      setAccounts((prev) =>
        prev.map((account) =>
          account.id === id ? { ...account, status: "PENDING", payment_date: null } : account
        )
      );
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "Falha ao desfazer pagamento.");
    } finally {
      setActionState({ id: "", type: null });
    }
  }, []);

  const handleDelete = useCallback((account: AccountsPayable) => {
    setErrorMessage(null);
    setDeletingAccount(account);
  }, []);

  const confirmarExclusao = useCallback(async () => {
    const account = deletingAccount;
    if (!account) return;
    setActionState({ id: account.id, type: "delete" });
    try {
      const response = await fetch("/api/accounts-payable", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ id: account.id }),
      });
      const payload = await response.json();
      if (!response.ok) {
        throw new Error(payload?.error ?? "Falha ao excluir conta.");
      }
      setAccounts((prev) => prev.filter((item) => item.id !== account.id));
      setDeletingAccount(null);
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : "Falha ao excluir conta.");
    } finally {
      setActionState({ id: "", type: null });
    }
  }, [deletingAccount]);

  const activeBankAccounts = useMemo(
    () => bankAccounts.filter((account) => account.active !== false),
    [bankAccounts]
  );
  const payCompatibleBankAccounts = useMemo(
    () => filterAccountsByLiquidationMethod(activeBankAccounts, normalizeLiquidationMethod(payForm.payment_method)),
    [activeBankAccounts, payForm.payment_method]
  );
  const payAccountLabel = payForm.payment_method === "cash" ? "Caixa físico" : "Conta bancária";

  /* O formulario tem estado proprio de propósito. Antes ele lia
     `payForm.payment_method`, que nasce como "cash" no modal de pagar: o campo
     de conta ficava travado em caixa fisico e escondia as contas bancarias — e
     mudava sozinho se voce tivesse mexido no outro modal antes. */
  const formCompatibleAccounts = useMemo(() => {
    if (wizardModo !== "liquidar") return activeBankAccounts;
    return filterAccountsByLiquidationMethod(
      activeBankAccounts,
      normalizeLiquidationMethod(form.payment_method)
    );
  }, [activeBankAccounts, wizardModo, form.payment_method]);

  const formAccountLabel =
    wizardModo === "liquidar"
      ? form.payment_method === "cash"
        ? "Caixa físico"
        : "Conta bancária"
      : "De onde deve sair (previsão)";

  const categoryOptions = useMemo(
    () => [
      { value: "new", label: "+ Nova Categoria", icon: Plus },
      { value: "", label: "Sem categoria" },
      ...categories
        .slice()
        .sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "", "pt-BR"))
        .map((cat) => ({
          value: cat.id,
          label: cat.name,
          icon: getCategoryIcon(cat.icon),
        })),
    ],
    [categories]
  );

  const filteredAccounts = useMemo(() => {
    const term = searchTerm.trim().toLowerCase();
    if (!term) return accounts;
    return accounts.filter((account) => {
      const description = account.description?.toLowerCase() ?? "";
      const bankName = account.bank_name?.toLowerCase() ?? "";
      const bankAccountName = account.bank_account_name?.toLowerCase() ?? "";
      const supplierName = account.supplier_name?.toLowerCase() ?? "";
      return (
        description.includes(term) ||
        bankName.includes(term) ||
        bankAccountName.includes(term) ||
        supplierName.includes(term)
      );
    });
  }, [accounts, searchTerm]);

  const pendingCount = useMemo(
    () =>
      filteredAccounts.filter(
        (account) => account.status === "PENDING" || account.status === "OVERDUE"
      ).length,
    [filteredAccounts]
  );

  const content = useMemo(() => {
    if (loading) {
      return (
        <div className="space-y-3">
          {Array.from({ length: 6 }).map((_, index) => (
            <div key={index} className="ks-surface p-4 rounded-2xl animate-pulse">
              <div className="h-4 bg-gray-200 rounded w-2/3 mb-3" />
              <div className="h-3 bg-gray-200 rounded w-1/3" />
            </div>
          ))}
        </div>
      );
    }

    if (errorMessage) {
      return (
        <div className="ks-surface p-8 rounded-2xl text-center">
          <p className="text-[var(--ks-color-text-primary)] font-semibold">
            Não foi possível carregar as contas a pagar.
          </p>
          <p className="text-sm text-[var(--ks-color-text-muted)] mt-2">{errorMessage}</p>
          <div className="mt-4 flex justify-center">
            <Button size="sm" onClick={loadAccounts}>
              Tentar novamente
            </Button>
          </div>
        </div>
      );
    }

    if (accounts.length === 0) {
      return (
        <div className="ks-surface p-8 rounded-2xl text-center">
          <p className="text-[var(--ks-color-text-primary)] font-semibold">Nenhuma conta a pagar encontrada.</p>
          <p className="text-sm text-[var(--ks-color-text-muted)] mt-2">
            Registre suas despesas para acompanhar vencimentos e pagamentos.
          </p>
        </div>
      );
    }

    if (filteredAccounts.length === 0) {
      return (
        <div className="ks-surface p-8 rounded-2xl text-center">
          <p className="text-[var(--ks-color-text-primary)] font-semibold">
            Nenhuma conta encontrada com os filtros atuais.
          </p>
          <p className="text-sm text-[var(--ks-color-text-muted)] mt-2">
            Ajuste os filtros para visualizar outras contas a pagar.
          </p>
        </div>
      );
    }

    return (
      <motion.div layout className="space-y-3">
        {filteredAccounts.map((account) => (
          <AccountsPayableRow
            key={account.id}
            account={account}
            onPay={openPay}
            onUndo={handleUndo}
            onCancel={handleCancel}
            onEdit={openEdit}
            onDelete={handleDelete}
            isPaying={actionState.id === account.id && actionState.type === "pay"}
            isUndoing={actionState.id === account.id && actionState.type === "undo"}
            isCanceling={actionState.id === account.id && actionState.type === "cancel"}
            isDeleting={actionState.id === account.id && actionState.type === "delete"}
            feedback={feedbackMap[account.id] ?? null}
          />
        ))}
      </motion.div>
    );
  }, [
    accounts,
    actionState,
    errorMessage,
    feedbackMap,
    filteredAccounts,
    handleCancel,
    handleDelete,
    handleUndo,
    loadAccounts,
    loading,
    openEdit,
    openPay,
  ]);

  return (
    <div className="space-y-6">
      <div className="flex items-start justify-between gap-4">
        <PageHeader
          title="Contas a Pagar"
          subtitle="Leitura rápida por status, vencimento e ações essenciais"
          actions={
            !podeLancar || aba !== "lancamentos" ? null : (
            <Button icon={<Plus className="w-4 h-4" />} onClick={openCreate}>
              Nova conta
            </Button>
            )
          }
        />
        <div className="flex items-center gap-2 text-sm text-[var(--ks-color-text-muted)]">
          {aba === "lancamentos" && (
            <span className="px-3 py-1 rounded-full bg-amber-50 text-amber-700 border border-amber-200 font-semibold">
              {pendingCount} pendentes
            </span>
          )}
        </div>
      </div>

      <Tabs value={aba} onValueChange={(v) => trocarAba(v as "lancamentos" | "custos-fixos")} className="w-full">
        <TabsList className="grid w-full grid-cols-2 max-w-[360px]">
          <TabsTrigger value="lancamentos">Lançamentos</TabsTrigger>
          {/* Os custos fixos moram nesta tela por historia, mas sao outro
              assunto: eles formam a hora da estrutura e mexem no preco de
              todo produto. Quem nao tem a chave deles nao ve a aba. */}
          {podeVerCustosFixos ? <TabsTrigger value="custos-fixos">Custos fixos</TabsTrigger> : null}
        </TabsList>
      </Tabs>

      {aba === "custos-fixos" ? (
        <CustosFixosTab podeEditar={podeEditarCustosFixos} />
      ) : (<>

      <div className="ks-surface p-4 space-y-3">
        <div className="grid grid-cols-1 md:grid-cols-5 gap-3">
          <Input
            placeholder="Buscar por descrição ou banco"
            value={searchTerm}
            onChange={(event) => setSearchTerm(event.target.value)}
            icon={<Search className="w-4 h-4" />}
          />
          <CustomSelect
            options={[
              { value: "all", label: "Todos os status" },
              { value: "PENDING", label: "Pendente" },
              { value: "OVERDUE", label: "Vencido" },
              { value: "PAID", label: "Pago" },
              { value: "CANCELED", label: "Cancelado" },
            ]}
            value={statusFilter}
            onChange={(value) => setStatusFilter(value as PayableStatus | "all")}
          />
          <Input
            type="month"
            value={monthFilter}
            onChange={(event) => setMonthFilter(event.target.value)}
          />
          <CustomSelect
            options={[
              { value: "", label: "Todas as contas" },
              ...bankAccounts
                .filter((acc) => acc.bank_account_id)
                .map((account) => ({
                  value: account.bank_account_id,
                  label: bankLabel(account),
                })),
            ]}
            value={bankFilter}
            onChange={setBankFilter}
            disabled={banksLoading}
          />
          <CustomSelect
            options={[
              { value: "", label: "Todas as categorias" },
              ...categoryOptions.filter((opt) => opt.value !== "new" && opt.value !== ""),
            ]}
            value={categoryFilter}
            onChange={setCategoryFilter}
            disabled={categoriesLoading}
          />
          <CustomSelect
            options={[
              { value: "", label: "Todos os fornecedores" },
              ...suppliers.map((supplier) => ({ value: supplier.id, label: supplier.name })),
            ]}
            value={supplierFilter}
            onChange={setSupplierFilter}
          />
        </div>
        {supplierFilter ? (
          <div className="mt-3 flex items-center gap-2 text-xs text-[var(--ks-color-text-muted)]">
            <span className="inline-flex items-center rounded-full border border-violet-200 bg-violet-50 px-3 py-1 font-semibold text-violet-700">
              Filtrando por fornecedor: {suppliers.find((supplier) => supplier.id === supplierFilter)?.name || supplierFilterName || "Fornecedor selecionado"}
            </span>
          </div>
        ) : null}
        {banksError ? (
          <div className="flex items-center gap-2 text-xs text-rose-700">
            <TriangleAlert className="w-4 h-4" />
            {banksError}
          </div>
        ) : null}
      </div>

      <div className="space-y-4">
        <div className="hidden md:grid grid-cols-[2.4fr_1fr_1fr_1fr_1.2fr] gap-4 px-4 text-xs uppercase tracking-[0.2em] text-[var(--ks-color-text-muted)]">
          <span>Descrição</span>
          <span>Valor</span>
          <span>Vencimento</span>
          <span>Status</span>
          <span className="text-right">Ações</span>
        </div>
        {content}
      </div>

      <AnimatePresence>
        {isFormOpen ? (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[120] flex items-start justify-center bg-black/40 backdrop-blur-sm px-4 py-10 overflow-y-auto"
            onClick={closeForm}
          >
            <motion.div
              initial={{ opacity: 0, y: 10, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: 10, scale: 0.98 }}
              transition={{ duration: 0.12 }}
              className="w-full max-w-2xl bg-[var(--ks-color-bg-elevated)] rounded-[var(--ks-radius-lg)] shadow-[var(--ks-shadow-soft)] overflow-hidden border border-[var(--ks-color-border-subtle)] flex flex-col"
              onClick={(event) => event.stopPropagation()}
            >
              <div className="flex items-center justify-between p-6 border-b border-[var(--ks-color-border-subtle)]">
                <div>
                  <p className="text-xs uppercase tracking-[0.2em] text-[var(--ks-color-text-soft)]">
                    Contas a pagar
                  </p>
                  <h2 className="text-lg font-semibold text-[var(--ks-color-text-primary)]">
                    {editingAccount
                      ? "Editar conta"
                      : wizardPasso === 1
                        ? "Nova conta"
                        : wizardModo === "liquidar"
                          ? wizardPasso === 2
                            ? "Dados da conta"
                            : "Como foi paga"
                          : "Dados da conta"}
                  </h2>
                  {!editingAccount && wizardPasso > 1 ? (
                    <p className="mt-0.5 text-xs text-[var(--ks-color-text-soft)]">
                      Passo {wizardPasso} de {wizardModo === "liquidar" ? 3 : 2}
                    </p>
                  ) : null}
                </div>
                <button
                  type="button"
                  onClick={closeForm}
                  className="rounded-full p-2 text-[var(--ks-color-text-soft)] hover:text-[var(--ks-color-text-primary)] hover:bg-[rgba(244,247,254,0.9)] transition-colors"
                  disabled={saving}
                >
                  <X className="w-4 h-4" />
                </button>
              </div>

              <form onSubmit={handleSavePayable} className="p-6 space-y-6">
                {formError ? (
                  <div className="px-3 py-2.5 rounded-xl text-sm bg-red-50 text-red-700 border border-red-100">
                    {formError}
                  </div>
                ) : null}

                {/* ---------- PASSO 1: o caminho ----------
                    Perguntar antes evita pedir forma de pagamento para quem
                    ainda nao sabe como vai pagar. */}
                {wizardPasso === 1 && !editingAccount ? (
                  <div className="space-y-3">
                    {[
                      {
                        modo: "registrar" as const,
                        icone: FileText,
                        titulo: "Registrar conta a pagar",
                        texto: "Lança agora e você paga depois. Entra na lista como pendente.",
                      },
                      {
                        modo: "liquidar" as const,
                        icone: CheckCircle2,
                        titulo: "Registrar e liquidar",
                        texto: "A conta já foi paga. Dá baixa na hora e lança no fluxo de caixa.",
                      },
                    ].map((opcao) => (
                      <button
                        key={opcao.modo}
                        type="button"
                        onClick={() => {
                          setWizardModo(opcao.modo);
                          setWizardPasso(2);
                          setFormError(null);
                          /* Trocar de caminho muda quais contas sao validas:
                             manter a selecao anterior deixaria escolha
                             incompativel presa no formulario. */
                          setForm((prev) => ({ ...prev, bank_account_id: "", payment_method: "" }));
                        }}
                        className="w-full text-left flex items-start gap-3 p-4 rounded-xl border border-[var(--ks-color-border-subtle)] bg-white transition hover:border-[var(--ks-color-primary)] hover:bg-[rgba(244,245,255,0.6)] active:scale-[0.99]"
                      >
                        <span className="mt-0.5 flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[rgba(244,245,255,0.9)] text-[var(--ks-color-primary-strong)]">
                          <opcao.icone className="w-4 h-4" />
                        </span>
                        <span className="min-w-0">
                          <span className="block text-sm font-semibold text-[var(--ks-color-text-primary)]">
                            {opcao.titulo}
                          </span>
                          <span className="mt-0.5 block text-xs leading-relaxed text-[var(--ks-color-text-soft)]">
                            {opcao.texto}
                          </span>
                        </span>
                      </button>
                    ))}
                  </div>
                ) : null}

                {/* ---------- PASSO 2: dados da conta ---------- */}
                <div className={wizardPasso === 2 || editingAccount ? "space-y-6" : "hidden"}>
                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <Input
                    id="payable-description"
                    label="Descrição"
                    value={form.description}
                    onChange={(event) => setForm((prev) => ({ ...prev, description: event.target.value }))}
                    placeholder="Ex: Aluguel, fornecedor..."
                  />
                  <Input
                    id="payable-amount"
                    label="Valor"
                    value={form.amount}
                    onChange={(event) =>
                      setForm((prev) => ({ ...prev, amount: formatCurrencyMaskBRL(event.target.value) }))
                    }
                    placeholder="0,00"
                  />
                  <Input
                    id="payable-due-date"
                    label="Vencimento"
                    type="date"
                    value={form.due_date}
                    onChange={(event) => setForm((prev) => ({ ...prev, due_date: event.target.value }))}
                  />
                  {/* No caminho de liquidar a conta e escolhida no passo 3,
                      junto da forma de pagamento — aqui ela so apareceria
                      duplicada. Quem esta apenas registrando escolhe a conta
                      prevista, sem filtro por metodo: ele ainda nao existe. */}
                  {wizardModo === "liquidar" && !editingAccount ? null : (
                    <div className="space-y-1">
                      <label className="ks-input-label">{formAccountLabel}</label>
                      <CustomSelect
                        options={[
                          { value: "", label: "Selecione..." },
                          ...formCompatibleAccounts
                            .filter((acc) => acc.bank_account_id)
                            .map((account) => ({
                              value: account.bank_account_id,
                              label: bankLabel(account),
                            })),
                        ]}
                        value={form.bank_account_id}
                        onChange={(value) => setForm((prev) => ({ ...prev, bank_account_id: value }))}
                        disabled={banksLoading}
                        portal={false}
                      />
                    </div>
                  )}
                  <div className="space-y-1">
                    <label className="ks-input-label">Fornecedor</label>
                    <CustomSelect
                      options={[
                        { value: "", label: "Sem fornecedor" },
                        ...suppliers.map((supplier) => ({
                          value: supplier.id,
                          label: supplier.name,
                        })),
                      ]}
                      value={form.supplier_id}
                      onChange={(value) => setForm((prev) => ({ ...prev, supplier_id: value }))}
                      portal={false}
                    />
                  </div>
                  <div className="space-y-1 md:col-span-2">
                    <label className="ks-input-label">Categoria</label>
                    <div className="flex gap-2">
                      <div className="flex-1">
                        <CustomSelect
                          options={categoryOptions}
                          value={form.category_id}
                          onChange={(value) => {
                            if (value === "new") {
                              setIsCategoryModalOpen(true);
                              return;
                            }
                            setForm((prev) => ({ ...prev, category_id: value }));
                          }}
                          portal={false}
                        />
                      </div>
                      <Button 
                        type="button" 
                        variant="ghost" 
                        className="px-3" 
                        onClick={() => setIsCategoryModalOpen(true)}
                        title="Nova Categoria"
                      >
                        <Plus className="w-4 h-4" />
                      </Button>
                    </div>
                  </div>
                </div>

                <div className="space-y-2">
                  <label className="ks-input-label">Notas</label>
                  <textarea
                    value={form.notes}
                    onChange={(event) => setForm((prev) => ({ ...prev, notes: event.target.value }))}
                    className="w-full px-3 py-2.5 rounded-xl border border-[var(--ks-color-border-subtle)] focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/20 focus:border-[var(--ks-color-primary)] min-h-[110px] bg-white"
                    placeholder="Informações adicionais"
                  />
                </div>

                <div className="space-y-3">
                  <div className="flex items-center justify-between p-4 rounded-xl border border-[var(--ks-color-border-subtle)] bg-[rgba(244,245,255,0.6)]">
                    <div>
                      <p className="text-sm font-medium text-[var(--ks-color-text-primary)]">
                        Recorrente
                      </p>
                      <p className="text-xs text-[var(--ks-color-text-soft)]">
                        Use para despesas que se repetem mensalmente
                      </p>
                    </div>
                    <Switch
                      checked={form.is_recurring}
                      onCheckedChange={(value) =>
                        setForm((prev) => ({ ...prev, is_recurring: value }))
                      }
                    />
                  </div>
                  {form.is_recurring ? (
                    <Input
                      id="payable-recurrence"
                      label="Regra de recorrência"
                      value={form.recurrence_rule}
                      onChange={(event) =>
                        setForm((prev) => ({ ...prev, recurrence_rule: event.target.value }))
                      }
                      placeholder="Ex: Mensal"
                    />
                  ) : null}
                </div>

                </div>

                {/* ---------- PASSO 3: como foi paga (so no caminho liquidar) ---------- */}
                {wizardPasso === 3 && wizardModo === "liquidar" && !editingAccount ? (
                  <div className="space-y-4">
                    <div className="space-y-1">
                      <label className="ks-input-label">Forma de pagamento</label>
                      <CustomSelect
                        options={[{ value: "", label: "Selecione..." }, ...paymentMethodOptions]}
                        value={form.payment_method}
                        onChange={(value) =>
                          /* Trocar a forma invalida a conta escolhida: dinheiro
                             so liquida em caixa, o resto so em banco. */
                          setForm((prev) => ({ ...prev, payment_method: value, bank_account_id: "" }))
                        }
                        portal={false}
                      />
                    </div>

                    <div className="space-y-1">
                      <label className="ks-input-label">{formAccountLabel}</label>
                      <CustomSelect
                        options={[
                          { value: "", label: "Selecione..." },
                          ...formCompatibleAccounts
                            .filter((acc) => acc.bank_account_id)
                            .map((account) => ({
                              value: account.bank_account_id,
                              label: bankLabel(account),
                            })),
                        ]}
                        value={form.bank_account_id}
                        onChange={(value) => setForm((prev) => ({ ...prev, bank_account_id: value }))}
                        disabled={banksLoading || !form.payment_method}
                        portal={false}
                      />
                      {!form.payment_method ? (
                        <p className="text-xs text-[var(--ks-color-text-soft)]">
                          Escolha a forma de pagamento para ver as contas compatíveis.
                        </p>
                      ) : null}
                    </div>

                    <Input
                      id="payable-payment-date"
                      label="Data do pagamento"
                      type="date"
                      value={form.payment_date}
                      onChange={(event) =>
                        setForm((prev) => ({ ...prev, payment_date: event.target.value }))
                      }
                    />

                    {form.is_recurring ? (
                      <div className="flex items-start gap-2.5 rounded-xl border border-amber-200 bg-amber-50 px-3 py-2.5">
                        <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-amber-600" />
                        <p className="text-xs leading-relaxed text-amber-900">
                          Esta conta é recorrente: ao liquidar, a próxima parcela é criada
                          automaticamente na lista.
                        </p>
                      </div>
                    ) : null}
                  </div>
                ) : null}

                {/* ---------- Rodape ---------- */}
                {wizardPasso > 1 || editingAccount ? (
                  <div className="flex items-center justify-between gap-3 pt-2">
                    <div>
                      {!editingAccount ? (
                        <Button
                          type="button"
                          variant="ghost"
                          onClick={() => {
                            setFormError(null);
                            setWizardPasso((passo) => Math.max(1, passo - 1));
                          }}
                          disabled={saving}
                        >
                          Voltar
                        </Button>
                      ) : null}
                    </div>

                    <div className="flex items-center gap-3">
                      <Button type="button" variant="ghost" onClick={closeForm} disabled={saving}>
                        Cancelar
                      </Button>

                      {/* No caminho de liquidar, o passo 2 apenas avanca — o
                          envio so acontece depois dos dados do pagamento. */}
                      {wizardModo === "liquidar" && wizardPasso === 2 && !editingAccount ? (
                        <Button type="button" onClick={avancarParaPagamento} disabled={saving}>
                          Continuar
                        </Button>
                      ) : (
                        <Button type="submit" disabled={saving}>
                          {saving
                            ? "Salvando..."
                            : wizardModo === "liquidar" && !editingAccount
                              ? "Salvar e liquidar"
                              : "Salvar"}
                        </Button>
                      )}
                    </div>
                  </div>
                ) : null}
              </form>
            </motion.div>
          </motion.div>
        ) : null}
      </AnimatePresence>

      <AnimatePresence>
        {isPayOpen ? (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[120] flex items-start justify-center bg-black/40 backdrop-blur-sm px-4 py-10 overflow-y-auto"
            onClick={closePay}
          >
            <motion.div
              initial={{ opacity: 0, y: 10, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: 10, scale: 0.98 }}
              transition={{ duration: 0.12 }}
              className="w-full max-w-xl bg-[var(--ks-color-bg-elevated)] rounded-[var(--ks-radius-lg)] shadow-[var(--ks-shadow-soft)] overflow-hidden border border-[var(--ks-color-border-subtle)] flex flex-col"
              onClick={(event) => event.stopPropagation()}
            >
              <div className="flex items-center justify-between p-6 border-b border-[var(--ks-color-border-subtle)]">
                <div>
                  <p className="text-xs uppercase tracking-[0.2em] text-[var(--ks-color-text-soft)]">
                    Pagamento
                  </p>
                  <h2 className="text-lg font-semibold text-[var(--ks-color-text-primary)]">
                    Confirmar pagamento
                  </h2>
                </div>
                <button
                  type="button"
                  onClick={closePay}
                  className="rounded-full p-2 text-[var(--ks-color-text-soft)] hover:text-[var(--ks-color-text-primary)] hover:bg-[rgba(244,247,254,0.9)] transition-colors"
                  disabled={paying}
                >
                  <X className="w-4 h-4" />
                </button>
              </div>

              <form onSubmit={handleSubmitPayment} className="p-6 space-y-6">
                {payError ? (
                  <div className="px-3 py-2.5 rounded-xl text-sm bg-red-50 text-red-700 border border-red-100">
                    {payError}
                  </div>
                ) : null}

                <div className="space-y-3">
                  <div className="text-sm text-[var(--ks-color-text-muted)]">
                    {payingAccount?.description}
                  </div>
                  <div className="text-xl font-semibold text-[var(--ks-color-text-primary)]">
                    {payingAccount ? formatMoney(payingAccount.amount) : ""}
                  </div>
                </div>

                <div className="grid grid-cols-1 gap-4">
                  <Input
                    id="payable-payment-date"
                    label="Data do pagamento"
                    type="date"
                    value={payForm.payment_date}
                    onChange={(event) =>
                      setPayForm((prev) => ({ ...prev, payment_date: event.target.value }))
                    }
                  />
                  <Input
                    id="payable-payment-amount"
                    label="Valor pago"
                    value={payForm.amount}
                    onChange={(event) =>
                      setPayForm((prev) => ({ ...prev, amount: formatCurrencyMaskBRL(event.target.value) }))
                    }
                    placeholder="0,00"
                  />
                  <div className="space-y-1">
                    <label className="ks-input-label">Forma de pagamento</label>
                    <CustomSelect
                      options={[{ value: "", label: "Selecione..." }, ...paymentMethodOptions]}
                      value={payForm.payment_method}
                      onChange={(value) =>
                        setPayForm((prev) => ({ ...prev, payment_method: value, bank_account_id: "" }))
                      }
                    />
                  </div>
                  {/* `payAccountLabel` e `payCompatibleBankAccounts` existiam e
                      eram consumidos so pelo formulario de criar — este modal,
                      para quem foram feitos, listava todas as contas com rotulo
                      fixo. Dava para escolher Dinheiro + conta bancaria e so
                      descobrir o erro ao enviar, porque o servidor recusa. */}
                  <div className="space-y-1">
                    <label className="ks-input-label">{payAccountLabel}</label>
                    <CustomSelect
                      options={[
                        { value: "", label: "Selecione..." },
                        ...payCompatibleBankAccounts
                          .filter((acc) => acc.bank_account_id)
                          .map((account) => ({
                            value: account.bank_account_id,
                            label: bankLabel(account),
                          })),
                      ]}
                      value={payForm.bank_account_id}
                      onChange={(value) =>
                        setPayForm((prev) => ({ ...prev, bank_account_id: value }))
                      }
                      disabled={banksLoading}
                    />
                  </div>
                  <div className="space-y-2">
                    <label className="ks-input-label">Notas</label>
                    <textarea
                      value={payForm.notes}
                      onChange={(event) => setPayForm((prev) => ({ ...prev, notes: event.target.value }))}
                      className="w-full px-3 py-2.5 rounded-xl border border-[var(--ks-color-border-subtle)] focus:outline-none focus:ring-2 focus:ring-[var(--ks-color-primary)]/20 focus:border-[var(--ks-color-primary)] min-h-[110px] bg-white"
                      placeholder="Observações do pagamento"
                    />
                  </div>
                </div>

                <div className="flex items-center justify-end gap-3 pt-2">
                  <Button type="button" variant="ghost" onClick={closePay} disabled={paying}>
                    Cancelar
                  </Button>
                  <Button type="submit" disabled={paying}>
                    {paying ? "Processando..." : "Confirmar"}
                  </Button>
                </div>
              </form>
            </motion.div>
          </motion.div>
        ) : null}
      </AnimatePresence>
      <AnimatePresence>
        {isCategoryModalOpen ? (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[130] flex items-center justify-center bg-black/40 backdrop-blur-sm px-4"
            onClick={() => setIsCategoryModalOpen(false)}
          >
            <motion.div
              initial={{ opacity: 0, scale: 0.95 }}
              animate={{ opacity: 1, scale: 1 }}
              exit={{ opacity: 0, scale: 0.95 }}
              className="w-full max-w-sm bg-white rounded-xl shadow-lg overflow-hidden border border-zinc-200"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="flex items-center justify-between p-4 border-b border-zinc-100">
                <h3 className="font-semibold text-zinc-900">Nova Categoria</h3>
                <button type="button" onClick={() => setIsCategoryModalOpen(false)} className="text-zinc-400 hover:text-zinc-600">
                  <X className="w-4 h-4" />
                </button>
              </div>
              <form onSubmit={handleCreateCategory} className="p-4 space-y-4">
                <Input
                  label="Nome da categoria"
                  value={newCategoryName}
                  onChange={(e) => setNewCategoryName(e.target.value)}
                  placeholder="Ex: Marketing"
                />
                <div className="space-y-1">
                  <label className="ks-input-label">Ícone</label>
                  <div className="grid grid-cols-6 gap-2 max-h-40 overflow-y-auto p-1">
                    {availableIcons.map((iconName) => {
                      const Icon = getCategoryIcon(iconName);
                      return (
                        <button
                          key={iconName}
                          type="button"
                          onClick={() => setNewCategoryIcon(iconName)}
                          className={`p-2 rounded-lg flex items-center justify-center transition-colors ${
                            newCategoryIcon === iconName
                              ? "bg-[var(--ks-color-primary)] text-white"
                              : "bg-zinc-50 text-zinc-500 hover:bg-zinc-100"
                          }`}
                        >
                          <Icon className="w-4 h-4" />
                        </button>
                      );
                    })}
                  </div>
                </div>
                <div className="flex justify-end gap-2 pt-2">
                   <Button type="button" variant="ghost" onClick={() => setIsCategoryModalOpen(false)}>
                     Cancelar
                   </Button>
                   <Button type="submit" disabled={creatingCategory || !newCategoryName.trim()}>
                     {creatingCategory ? "Criando..." : "Criar Categoria"}
                   </Button>
                </div>
              </form>
            </motion.div>
          </motion.div>
        ) : null}
      </AnimatePresence>

      {/* ---------------------------- CONFIRMAR EXCLUSAO ---------------------------- */}
      <AnimatePresence>
        {deletingAccount ? (
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-[130] flex items-center justify-center bg-black/40 backdrop-blur-sm px-4"
            onClick={() => setDeletingAccount(null)}
          >
            <motion.div
              initial={{ opacity: 0, y: 10, scale: 0.98 }}
              animate={{ opacity: 1, y: 0, scale: 1 }}
              exit={{ opacity: 0, y: 10, scale: 0.98 }}
              transition={{ duration: 0.12 }}
              className="w-full max-w-md bg-[var(--ks-color-bg-elevated)] rounded-[var(--ks-radius-lg)] shadow-[var(--ks-shadow-soft)] border border-[var(--ks-color-border-subtle)] p-6"
              onClick={(event) => event.stopPropagation()}
            >
              <div className="flex items-start gap-3">
                <span className="mt-0.5 flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-rose-50 text-rose-600">
                  <Trash2 className="h-5 w-5" />
                </span>
                <div className="min-w-0">
                  <h2 className="text-lg font-semibold text-[var(--ks-color-text-primary)]">
                    Excluir conta a pagar
                  </h2>
                  <p className="mt-1.5 text-sm leading-relaxed text-[var(--ks-color-text-soft)]">
                    &quot;{deletingAccount.description}&quot; será removida da lista. Esta ação não
                    pode ser desfeita.
                  </p>
                  {deletingAccount.status === "PAID" ? (
                    <div className="mt-3 flex items-start gap-2 rounded-xl border border-amber-200 bg-amber-50 px-3 py-2.5">
                      <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0 text-amber-600" />
                      <p className="text-xs leading-relaxed text-amber-900">
                        Esta conta está paga. O pagamento será estornado no fluxo de caixa com
                        um lançamento de ajuste, mantendo o histórico.
                      </p>
                    </div>
                  ) : null}
                </div>
              </div>

              <div className="mt-6 flex items-center justify-end gap-3">
                <Button
                  type="button"
                  variant="ghost"
                  onClick={() => setDeletingAccount(null)}
                  disabled={actionState.type === "delete"}
                >
                  Cancelar
                </Button>
                <Button
                  type="button"
                  variant="destructive"
                  onClick={confirmarExclusao}
                  disabled={actionState.type === "delete"}
                >
                  {actionState.type === "delete" ? "Excluindo..." : "Excluir"}
                </Button>
              </div>
            </motion.div>
          </motion.div>
        ) : null}
      </AnimatePresence>
      </>)}
    </div>
  );
}
