"use client";

import { useEffect, useMemo, useState } from "react";
import { X } from "lucide-react";
import { registerPayment } from "@/app/actions/financial";
import { formatMoney } from "@/lib/utils";
import { filterAccountsByLiquidationMethod, normalizeLiquidationMethod } from "@/lib/liquidation-accounts";

interface PaymentModalProps {
  isOpen: boolean;
  onClose: () => void;
  orderId: string;
  maxAmount: number;
  onSuccess: () => void;
  /* Preenchimento inicial, quando o pagamento nasce de uma parcela do
     combinado na proposta. */
  initial?: { amount?: number; method?: string; notes?: string } | null;
}

const paymentMethods = [
  { value: "pix", label: "Pix" },
  { value: "cash", label: "Dinheiro" },
  { value: "credit_card", label: "Cartão de Crédito" },
  { value: "debit_card", label: "Cartão de Débito" },
  { value: "transfer", label: "Transferência" },
];

export function PaymentModal({ isOpen, onClose, orderId, maxAmount, onSuccess, initial }: PaymentModalProps) {
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [amountInput, setAmountInput] = useState("");
  const [selectedPaymentMethod, setSelectedPaymentMethod] = useState("");
  const [bankAccounts, setBankAccounts] = useState<
    { bank_account_id: string; name: string; active?: boolean | null; type?: string | null; bank_name?: string | null }[]
  >([]);
  const [banksLoading, setBanksLoading] = useState(false);
  const [banksError, setBanksError] = useState("");

  const maxAllowedAmount = useMemo(() => Math.round((Number(maxAmount) + Number.EPSILON) * 100) / 100, [maxAmount]);
  const parsedAmount = useMemo(() => {
    if (!amountInput.trim()) return 0;
    const normalized = amountInput.replace(/\./g, "").replace(",", ".");
    const value = Number.parseFloat(normalized);
    return Number.isFinite(value) ? value : 0;
  }, [amountInput]);

  function handleAmountChange(rawValue: string) {
    const digits = rawValue.replace(/\D/g, "");
    if (!digits) {
      setAmountInput("");
      return;
    }
    const cents = Number.parseInt(digits, 10);
    const value = cents / 100;
    const formatted = value.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    setAmountInput(formatted);
  }

  function setQuickAmount(value: number) {
    const safeValue = Math.max(0, Math.min(maxAllowedAmount, Math.round((value + Number.EPSILON) * 100) / 100));
    const formatted = safeValue.toLocaleString("pt-BR", {
      minimumFractionDigits: 2,
      maximumFractionDigits: 2,
    });
    setAmountInput(formatted);
    if (error) setError("");
  }

  const activeAccounts = useMemo(
    () => bankAccounts.filter((account) => account.active !== false),
    [bankAccounts]
  );
  const compatibleAccounts = useMemo(
    () => filterAccountsByLiquidationMethod(activeAccounts, normalizeLiquidationMethod(selectedPaymentMethod)),
    [activeAccounts, selectedPaymentMethod]
  );
  const accountLabel = selectedPaymentMethod === "cash" ? "Caixa físico" : "Conta bancária";

  useEffect(() => {
    if (!isOpen) return;
    let active = true;
    setBanksLoading(true);
    setBanksError("");
    setSelectedPaymentMethod(initial?.method ?? "");
    setAmountInput(
      initial?.amount && initial.amount > 0
        ? initial.amount.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
        : ""
    );

    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;
    };
  }, [isOpen, initial]);

  if (!isOpen) return null;

  async function handleSubmit(formData: FormData) {
    setLoading(true);
    setError("");
    const amount = parsedAmount;

    if (!Number.isFinite(amount) || amount <= 0) {
      setError("Informe um valor válido para o pagamento.");
      setLoading(false);
      return;
    }

    if (amount > maxAllowedAmount + 0.0001) {
      setError(`O valor deve ser menor ou igual a ${maxAllowedAmount.toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`);
      setLoading(false);
      return;
    }

    formData.set("amount", amount.toFixed(2));

    try {
      const result = await registerPayment(formData);
      if (result.error) {
        setError(result.error);
      } else {
        onClose();
        onSuccess();
      }
    } catch {
      setError("Erro inesperado ao registrar pagamento.");
    } finally {
      setLoading(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4">
      <div className="bg-white rounded-2xl shadow-xl w-full max-w-md overflow-hidden animate-in fade-in zoom-in-95 duration-200">
        <div className="flex items-center justify-between p-4 border-b border-zinc-100">
          <h3 className="font-semibold text-lg text-zinc-900">Registrar Pagamento</h3>
          <button onClick={onClose} className="p-1 hover:bg-zinc-100 rounded-full transition-colors">
            <X className="w-5 h-5 text-zinc-500" />
          </button>
        </div>

        <form action={handleSubmit} className="p-6 flex flex-col gap-4">
          <input type="hidden" name="orderId" value={orderId} />
          <input type="hidden" name="tzOffsetMinutes" value={new Date().getTimezoneOffset()} />
          
          <div className="flex flex-col gap-1.5">
            <label htmlFor="amount" className="text-sm font-medium text-zinc-700">
              Valor (Máx: {formatMoney(maxAllowedAmount)})
            </label>
            <div className="relative">
              <span className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-500 font-medium">R$</span>
              <div className="absolute right-2 top-1/2 z-10 flex -translate-y-1/2 items-center gap-1">
                <button
                  type="button"
                  onClick={() => setQuickAmount(maxAllowedAmount / 2)}
                  className="inline-flex h-6 items-center justify-center rounded-md bg-amber-50 px-2 text-[10px] font-bold uppercase tracking-wide text-amber-700 transition-colors hover:bg-amber-100"
                >
                  50%
                </button>
                <button
                  type="button"
                  onClick={() => setQuickAmount(maxAllowedAmount)}
                  className="inline-flex h-6 items-center justify-center rounded-md bg-emerald-50 px-2 text-[10px] font-bold uppercase tracking-wide text-emerald-700 transition-colors hover:bg-emerald-100"
                >
                  Total
                </button>
              </div>
              <input
                type="text"
                id="amount"
                inputMode="numeric"
                autoComplete="off"
                required
                value={amountInput}
                onChange={(event) => {
                  handleAmountChange(event.target.value);
                  if (error) setError("");
                }}
                className="w-full rounded-xl border border-zinc-200 bg-zinc-50 py-2.5 pl-10 pr-28 focus:border-[var(--ks-color-primary)] focus:bg-white outline-none transition-all"
                placeholder="0,00"
              />
              <input type="hidden" name="amount" value={parsedAmount > 0 ? parsedAmount.toFixed(2) : ""} />
            </div>
          </div>

          <div className="flex flex-col gap-1.5">
            <label htmlFor="paymentMethod" className="text-sm font-medium text-zinc-700">
              Forma de Pagamento
            </label>
            <select
              id="paymentMethod"
              name="paymentMethod"
              required
              value={selectedPaymentMethod}
              onChange={(event) => {
                setSelectedPaymentMethod(event.target.value);
                if (error) setError("");
              }}
              className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 bg-zinc-50 focus:bg-white focus:border-[var(--ks-color-primary)] outline-none transition-all appearance-none"
            >
              <option value="">Selecione...</option>
              {paymentMethods.map((method) => (
                <option key={method.value} value={method.value}>
                  {method.label}
                </option>
              ))}
            </select>
          </div>

          <div className="flex flex-col gap-1.5">
            <label htmlFor="bankAccountId" className="text-sm font-medium text-zinc-700">
              {accountLabel}
            </label>
            <select
              id="bankAccountId"
              name="bankAccountId"
              required={compatibleAccounts.length > 0}
              className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 bg-zinc-50 focus:bg-white focus:border-[var(--ks-color-primary)] outline-none transition-all appearance-none"
            >
              <option value="">Selecione...</option>
              {compatibleAccounts.map((account) => (
                <option key={account.bank_account_id} value={account.bank_account_id}>
                  {account.name}
                </option>
              ))}
            </select>
            {banksLoading ? (
              <span className="text-xs text-zinc-500">Carregando contas...</span>
            ) : null}
            {!banksLoading && compatibleAccounts.length === 0 ? (
              <span className="text-xs text-zinc-500">
                {selectedPaymentMethod === "cash"
                  ? "Nenhum caixa físico ativo cadastrado."
                  : "Nenhuma conta bancária ativa cadastrada."}
              </span>
            ) : null}
            {banksError ? (
              <span className="text-xs text-red-600">{banksError}</span>
            ) : null}
          </div>

          <div className="flex flex-col gap-1.5">
            <label htmlFor="paymentDateTime" className="text-sm font-medium text-zinc-700">
              Data e Hora do Pagamento
            </label>
            <input
              type="datetime-local"
              id="paymentDateTime"
              name="paymentDateTime"
              required
              defaultValue={(() => {
                const now = new Date();
                const local = new Date(now.getTime() - now.getTimezoneOffset() * 60000);
                return local.toISOString().slice(0, 16);
              })()}
              className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 bg-zinc-50 focus:bg-white focus:border-[var(--ks-color-primary)] outline-none transition-all"
            />
          </div>

          <div className="flex flex-col gap-1.5">
            <label htmlFor="notes" className="text-sm font-medium text-zinc-700">
              Observação <span className="text-zinc-400 font-normal">(Opcional)</span>
            </label>
            <textarea
              id="notes"
              name="notes"
              rows={3}
              defaultValue={initial?.notes ?? ""}
              className="w-full px-4 py-2.5 rounded-xl border border-zinc-200 bg-zinc-50 focus:bg-white focus:border-[var(--ks-color-primary)] outline-none transition-all resize-none"
              placeholder="Ex: Entrada referente a..."
            />
          </div>

          {error && (
            <div className="p-3 rounded-lg bg-red-50 text-red-600 text-sm font-medium">
              {error}
            </div>
          )}

          <div className="pt-2">
            <button
              type="submit"
              disabled={loading}
              className="w-full py-3 rounded-full bg-[var(--ks-color-primary)] hover:bg-[var(--ks-color-primary-strong)] text-white font-medium shadow-lg shadow-[var(--ks-color-primary-soft-strong)] transition-all disabled:opacity-70 disabled:cursor-not-allowed"
            >
              {loading ? "Registrando..." : "Confirmar Pagamento"}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
}
