"use client";

import { useCallback, useEffect, useRef, useState, FormEvent } from "react";
import Link from "next/link";
import {
  PageHeader, PageLoader, EmptyState, Modal, Badge, TableShell,
  fmtKes, inputCls, btnPrimary, btnGhost, Field, Spinner,
} from "@/components/ui";

interface Payment {
  id: number; invoiceId: number; invoiceNo: string; clientName: string;
  amount: number; method: string; reference: string; paidAt: string;
}

interface MpesaTx {
  id: number; invoiceId: number | null; invoiceNo: string | null; phone: string; amount: number;
  accountRef: string; mpesaReceipt: string; status: string; resultDesc: string; simulated: boolean; createdAt: string;
}

interface InvoiceOpt { id: number; invoiceNo: string; clientName: string; total: number; amountPaid: number; status: string }

export default function PaymentsPage() {
  const [tab, setTab] = useState<"payments" | "mpesa">("payments");
  const [payments, setPayments] = useState<Payment[] | null>(null);
  const [mpesa, setMpesa] = useState<MpesaTx[] | null>(null);
  const [invoices, setInvoices] = useState<InvoiceOpt[]>([]);
  const [open, setOpen] = useState(false);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState("");
  const [msg, setMsg] = useState("");
  const [form, setForm] = useState({ phone: "", amount: 0, invoiceId: "" });
  const pollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  const loadAll = useCallback(() => {
    fetch("/api/payments").then((r) => r.json()).then(setPayments);
    fetch("/api/mpesa/transactions").then((r) => r.json()).then(setMpesa);
    fetch("/api/invoices").then((r) => r.json()).then((d) =>
      setInvoices(d.filter((i: InvoiceOpt) => i.status !== "paid" && i.status !== "draft")),
    );
  }, []);

  useEffect(() => { loadAll(); }, [loadAll]);
  useEffect(() => () => { if (pollRef.current) clearInterval(pollRef.current); }, []);

  const hasPending = (mpesa ?? []).some((t) => t.status === "pending");
  useEffect(() => {
    if (!hasPending) return;
    const t = setInterval(() => {
      fetch("/api/mpesa/transactions").then((r) => r.json()).then(setMpesa);
      fetch("/api/payments").then((r) => r.json()).then(setPayments);
    }, 3000);
    return () => clearInterval(t);
  }, [hasPending]);

  const sendStk = async (e: FormEvent) => {
    e.preventDefault();
    setBusy(true);
    setError("");
    setMsg("");
    try {
      const res = await fetch("/api/mpesa/stk", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          phone: form.phone,
          amount: form.amount,
          invoiceId: form.invoiceId ? Number(form.invoiceId) : undefined,
        }),
      });
      const d = await res.json();
      if (!res.ok) throw new Error(d.error || "STK push failed");
      setMsg(
        d.transaction.simulated
          ? "STK push sent in simulation mode — it will auto-confirm shortly."
          : "STK push sent — customer should enter M-Pesa PIN on their phone.",
      );
      setMpesa((prev) => [d.transaction, ...(prev ?? [])]);
      setBusy(false);
      setTab("mpesa");
      setTimeout(() => setOpen(false), 1500);
    } catch (err) {
      setError((err as Error).message);
      setBusy(false);
    }
  };

  return (
    <div>
      <PageHeader
        title="Payments & M-Pesa"
        subtitle="All received payments and M-Pesa STK push requests"
        action={<button onClick={() => { setError(""); setMsg(""); setOpen(true); }} className={`${btnPrimary} bg-emerald-600 hover:bg-emerald-700`}>📱 New STK push</button>}
      />

      <div className="mb-4 flex gap-2">
        <button
          onClick={() => setTab("payments")}
          className={`rounded-full px-4 py-1.5 text-sm font-medium transition ${tab === "payments" ? "bg-blue-700 text-white" : "bg-white text-slate-600 ring-1 ring-slate-200"}`}
        >
          Payments {payments ? `(${payments.length})` : ""}
        </button>
        <button
          onClick={() => setTab("mpesa")}
          className={`rounded-full px-4 py-1.5 text-sm font-medium transition ${tab === "mpesa" ? "bg-blue-700 text-white" : "bg-white text-slate-600 ring-1 ring-slate-200"}`}
        >
          M-Pesa log {mpesa ? `(${mpesa.length})` : ""}
        </button>
      </div>

      {tab === "payments" ? (
        !payments ? (
          <PageLoader label="Loading payments…" />
        ) : payments.length === 0 ? (
          <EmptyState icon="💰" title="No payments yet" description="Payments recorded on invoices or collected via M-Pesa will show up here." />
        ) : (
          <TableShell head={["Date", "Invoice", "Client", "Method", "Reference", "Amount"]}>
            {payments.map((p) => (
              <tr key={p.id} className="hover:bg-slate-50">
                <td className="whitespace-nowrap px-4 py-3 text-slate-500">{new Date(p.paidAt).toLocaleDateString("en-KE")}</td>
                <td className="px-4 py-3">
                  <Link href={`/dashboard/invoices/${p.invoiceId}`} className="font-medium text-blue-700 hover:underline">{p.invoiceNo}</Link>
                </td>
                <td className="max-w-[160px] truncate px-4 py-3 text-slate-600">{p.clientName}</td>
                <td className="px-4 py-3"><Badge value={p.method} /></td>
                <td className="px-4 py-3 font-mono text-xs text-slate-500">{p.reference}</td>
                <td className="whitespace-nowrap px-4 py-3 font-semibold text-emerald-700">{fmtKes(p.amount)}</td>
              </tr>
            ))}
          </TableShell>
        )
      ) : !mpesa ? (
        <PageLoader label="Loading M-Pesa transactions…" />
      ) : mpesa.length === 0 ? (
        <EmptyState
          icon="📱"
          title="No M-Pesa transactions"
          description="Send an STK push to a customer's phone to collect payment instantly."
          action={<button onClick={() => setOpen(true)} className={`${btnPrimary} bg-emerald-600 hover:bg-emerald-700`}>📱 New STK push</button>}
        />
      ) : (
        <TableShell head={["Date", "Phone", "Invoice", "Receipt", "Amount", "Status"]}>
          {mpesa.map((t) => (
            <tr key={t.id} className="hover:bg-slate-50">
              <td className="whitespace-nowrap px-4 py-3 text-slate-500">{new Date(t.createdAt).toLocaleString("en-KE", { dateStyle: "medium", timeStyle: "short" })}</td>
              <td className="whitespace-nowrap px-4 py-3 text-slate-700">{t.phone}</td>
              <td className="px-4 py-3">
                {t.invoiceId ? (
                  <Link href={`/dashboard/invoices/${t.invoiceId}`} className="font-medium text-blue-700 hover:underline">{t.invoiceNo ?? t.accountRef}</Link>
                ) : (
                  <span className="text-slate-400">{t.accountRef || "—"}</span>
                )}
              </td>
              <td className="px-4 py-3 font-mono text-xs text-slate-600">{t.mpesaReceipt || "—"}</td>
              <td className="whitespace-nowrap px-4 py-3 font-medium">{fmtKes(t.amount)}</td>
              <td className="px-4 py-3">
                <span className="flex items-center gap-2">
                  <Badge value={t.status} />
                  {t.status === "pending" && <Spinner className="h-3.5 w-3.5" />}
                </span>
              </td>
            </tr>
          ))}
        </TableShell>
      )}

      <Modal open={open} onClose={() => setOpen(false)} title="Send M-Pesa STK push">
        <form onSubmit={sendStk}>
          {error && <div className="mb-4 rounded-lg bg-rose-50 px-3 py-2 text-sm text-rose-700">{error}</div>}
          {msg && <div className="mb-4 rounded-lg bg-emerald-50 px-3 py-2 text-sm text-emerald-700">{msg}</div>}
          <div className="space-y-4">
            <Field label="Customer phone (Safaricom) *">
              <input className={inputCls} required placeholder="0722123456" value={form.phone} onChange={(e) => setForm({ ...form, phone: e.target.value })} />
            </Field>
            <Field label="Amount (KES) *">
              <input type="number" min={1} className={inputCls} required value={form.amount || ""} onChange={(e) => setForm({ ...form, amount: Number(e.target.value) })} />
            </Field>
            <Field label="Link to invoice (optional)">
              <select
                className={inputCls}
                value={form.invoiceId}
                onChange={(e) => {
                  const inv = invoices.find((i) => i.id === Number(e.target.value));
                  setForm({
                    ...form,
                    invoiceId: e.target.value,
                    amount: inv ? Math.max(0, inv.total - inv.amountPaid) : form.amount,
                  });
                }}
              >
                <option value="">No invoice — general collection</option>
                {invoices.map((i) => (
                  <option key={i.id} value={i.id}>
                    {i.invoiceNo} — {i.clientName} (bal {fmtKes(Math.max(0, i.total - i.amountPaid))})
                  </option>
                ))}
              </select>
            </Field>
            <p className="rounded-lg bg-slate-50 px-3 py-2 text-xs text-slate-500">
              💡 Without Daraja API credentials (MPESA_CONSUMER_KEY etc.) the system runs in{" "}
              <span className="font-semibold">simulation mode</span> and transactions auto-confirm.
            </p>
          </div>
          <div className="mt-6 flex justify-end gap-2">
            <button type="button" onClick={() => setOpen(false)} className={btnGhost}>Cancel</button>
            <button type="submit" disabled={busy} className={`${btnPrimary} bg-emerald-600 hover:bg-emerald-700`}>
              {busy && <Spinner className="h-4 w-4 text-white" />}
              {busy ? "Sending…" : "Send STK push"}
            </button>
          </div>
        </form>
      </Modal>
    </div>
  );
}
