"use client";

import { useState } from "react";
import { Download, Printer, Receipt, RefreshCw, Search, Wallet } from "lucide-react";
import { api, useApi, useDebounced } from "@/lib/client";
import { Badge, Button, Card, DataTable, Field, Input, KeyValue, Modal, PageHeader, Pagination, Select, StatCard, Textarea, useToast, type Column } from "@/components/ui";
import { currentPeriod, downloadCsv, formatDate, money, qs, toCsv } from "@/lib/utils";

interface PaymentRow extends Record<string, unknown> {
  id: number;
  receiptNo: string;
  amount: string;
  discount: string;
  methodName: string | null;
  transactionId: string | null;
  paymentType: string;
  paymentDate: string;
  notes: string | null;
  customerId: number;
  customerName: string;
  customerCode: string;
  mobile: string;
  collectorName: string | null;
  invoiceNo: string | null;
}

export default function PaymentsPage() {
  const toast = useToast();
  const monthStart = `${currentPeriod()}-01`;
  const [filters, setFilters] = useState({ q: "", method: "", collector: "", from: monthStart, to: "" });
  const debounced = useDebounced(filters, 350);
  const [page, setPage] = useState(1);
  const query = qs({ ...debounced, page, pageSize: 15 });
  const { data, loading, reload } = useApi<{
    items: PaymentRow[];
    total: number;
    collected: number;
    page: number;
    pages: number;
    methods: { id: number; name: string }[];
    collectors: { id: number; name: string }[];
  }>(`/api/payments${query}`, [query]);
  const { data: customers } = useApi<{ items: { id: number; name: string; customerCode: string; dueAmount: string }[] }>("/api/customers?pageSize=100");

  const [modal, setModal] = useState(false);
  const [busy, setBusy] = useState(false);
  const [receipt, setReceipt] = useState<PaymentRow | null>(null);
  const [form, setForm] = useState({ customerId: "", billId: "", amount: "", methodId: "", transactionId: "", paymentType: "regular", paymentDate: new Date().toISOString().slice(0, 10), notes: "" });

  const columns: Column<PaymentRow>[] = [
    { key: "receiptNo", label: "Receipt", render: (r) => <button onClick={() => setReceipt(r)} className="font-mono text-xs text-brand-400 hover:underline">{r.receiptNo}</button> },
    {
      key: "customerName",
      label: "Customer",
      render: (r) => (
        <div className="min-w-0">
          <p className="truncate font-medium text-slate-100">{r.customerName}</p>
          <p className="text-[11px] text-slate-500">{r.customerCode} · {r.mobile}</p>
        </div>
      ),
    },
    { key: "amount", label: "Amount", render: (r) => <span className="font-semibold text-emerald-300">{money(r.amount)}</span> },
    { key: "methodName", label: "Method", hideOnMobile: true, render: (r) => <Badge value="unknown" label={String(r.methodName ?? "—")} /> },
    { key: "transactionId", label: "Trx ID", hideOnMobile: true, render: (r) => <span className="font-mono text-[11px] text-slate-500">{r.transactionId ?? "—"}</span> },
    { key: "paymentType", label: "Type", hideOnMobile: true, render: (r) => <Badge value={r.paymentType === "refund" ? "expired" : "active"} label={r.paymentType} /> },
    { key: "invoiceNo", label: "Invoice", hideOnMobile: true, render: (r) => <span className="font-mono text-[11px] text-slate-400">{r.invoiceNo ?? "—"}</span> },
    { key: "collectorName", label: "Collector", hideOnMobile: true, render: (r) => String(r.collectorName ?? "—") },
    { key: "paymentDate", label: "Date", render: (r) => formatDate(r.paymentDate) },
    {
      key: "actions",
      label: "",
      render: (r) => (
        <div className="flex gap-1">
          <Button size="sm" variant="ghost" icon={<Printer className="h-3.5 w-3.5" />} onClick={() => setReceipt(r)} />
          <Button
            size="sm"
            variant="ghost"
            onClick={async () => {
              if (!confirm(`Void receipt ${r.receiptNo}?`)) return;
              try {
                await api(`/api/payments/${r.id}`, { method: "POST" });
                toast.push("Payment voided", "success");
                void reload();
              } catch (err) {
                toast.push(err instanceof Error ? err.message : "Void failed", "error");
              }
            }}
          >
            Void
          </Button>
        </div>
      ),
    },
  ];

  return (
    <>
      <PageHeader
        title="Payment management"
        subtitle="Cash, mobile banking, bank and online collections"
        icon={<Receipt className="h-5 w-5" />}
        actions={
          <>
            <Button variant="secondary" size="sm" icon={<RefreshCw className="h-4 w-4" />} onClick={() => void reload()}>
              Refresh
            </Button>
            <Button
              variant="secondary"
              size="sm"
              icon={<Download className="h-4 w-4" />}
              onClick={async () => {
                const res = await api<{ items: PaymentRow[] }>(`/api/payments${qs({ ...debounced, pageSize: 100 })}`);
                downloadCsv(`payments-${Date.now()}.csv`, toCsv(res.items as unknown as Record<string, unknown>[]));
                toast.push("Payment report exported", "success");
              }}
            >
              Export
            </Button>
            <Button
              size="sm"
              icon={<Wallet className="h-4 w-4" />}
              onClick={() => {
                setForm({ customerId: "", billId: "", amount: "", methodId: String(data?.methods[0]?.id ?? 1), transactionId: "", paymentType: "regular", paymentDate: new Date().toISOString().slice(0, 10), notes: "" });
                setModal(true);
              }}
            >
              Receive payment
            </Button>
          </>
        }
      />

      <div className="mb-4 grid grid-cols-2 gap-3 lg:grid-cols-4">
        <StatCard label="Receipts" value={data?.total ?? 0} icon={<Receipt className="h-5 w-5" />} tone="brand" />
        <StatCard label="Collected" value={money(data?.collected)} icon={<Wallet className="h-5 w-5" />} tone="green" />
        <StatCard label="Cash share" value={money((data?.items ?? []).filter((p) => p.methodName === "Cash").reduce((a, p) => a + Number(p.amount), 0))} icon={<Wallet className="h-5 w-5" />} tone="cyan" />
        <StatCard label="Mobile banking" value={money((data?.items ?? []).filter((p) => p.methodName !== "Cash").reduce((a, p) => a + Number(p.amount), 0))} icon={<Wallet className="h-5 w-5" />} tone="violet" />
      </div>

      <Card className="mb-4 p-3">
        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-5">
          <div className="relative lg:col-span-2">
            <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-500" />
            <Input className="pl-9" placeholder="Search receipt, customer, trx id…" value={filters.q} onChange={(e) => { setPage(1); setFilters((f) => ({ ...f, q: e.target.value })); }} />
          </div>
          <Select value={filters.method} onChange={(e) => { setPage(1); setFilters((f) => ({ ...f, method: e.target.value })); }}>
            <option value="">All methods</option>
            {(data?.methods ?? []).map((m) => (
              <option key={m.id} value={m.name}>
                {m.name}
              </option>
            ))}
          </Select>
          <Select value={filters.collector} onChange={(e) => { setPage(1); setFilters((f) => ({ ...f, collector: e.target.value })); }}>
            <option value="">All collectors</option>
            {(data?.collectors ?? []).map((c) => (
              <option key={c.id} value={c.id}>
                {c.name}
              </option>
            ))}
          </Select>
          <div className="flex gap-2">
            <Input type="date" value={filters.from} onChange={(e) => { setPage(1); setFilters((f) => ({ ...f, from: e.target.value })); }} />
            <Input type="date" value={filters.to} onChange={(e) => { setPage(1); setFilters((f) => ({ ...f, to: e.target.value })); }} />
          </div>
        </div>
      </Card>

      <Card className="p-2">
        <DataTable columns={columns} rows={data?.items ?? []} loading={loading} rowKey={(r) => r.id} empty="No payments in this range" />
        <Pagination page={data?.page ?? 1} pages={data?.pages ?? 1} total={data?.total ?? 0} onChange={setPage} />
      </Card>

      <Modal
        open={modal}
        onClose={() => setModal(false)}
        title="Receive payment"
        subtitle="Payment allocates to the oldest open bill, extends expiry and re-enables internet"
        size="lg"
        footer={
          <>
            <Button variant="secondary" onClick={() => setModal(false)}>
              Cancel
            </Button>
            <Button
              loading={busy}
              onClick={async () => {
                setBusy(true);
                try {
                  await api("/api/payments", {
                    method: "POST",
                    json: {
                      customerId: Number(form.customerId),
                      amount: Number(form.amount),
                      methodId: Number(form.methodId),
                      transactionId: form.transactionId || null,
                      paymentType: form.paymentType,
                      paymentDate: form.paymentDate,
                      notes: form.notes || null,
                    },
                  });
                  toast.push("Payment recorded", "success");
                  setModal(false);
                  void reload();
                } catch (err) {
                  toast.push(err instanceof Error ? err.message : "Payment failed", "error");
                } finally {
                  setBusy(false);
                }
              }}
            >
              Save payment
            </Button>
          </>
        }
      >
        <div className="grid gap-4 sm:grid-cols-2">
          <Field label="Customer">
            <Select
              value={form.customerId}
              onChange={(e) => {
                const c = customers?.items.find((x) => String(x.id) === e.target.value);
                setForm({ ...form, customerId: e.target.value, amount: form.amount || String(c?.dueAmount ?? "") });
              }}
            >
              <option value="">Select customer</option>
              {(customers?.items ?? []).map((c) => (
                <option key={c.id} value={c.id}>
                  {c.name} — {c.customerCode} (due {money(c.dueAmount)})
                </option>
              ))}
            </Select>
          </Field>
          <Field label="Amount">
            <Input type="number" value={form.amount} onChange={(e) => setForm({ ...form, amount: e.target.value })} />
          </Field>
          <Field label="Method">
            <Select value={form.methodId} onChange={(e) => setForm({ ...form, methodId: e.target.value })}>
              {(data?.methods ?? []).map((m) => (
                <option key={m.id} value={m.id}>
                  {m.name}
                </option>
              ))}
            </Select>
          </Field>
          <Field label="Payment type">
            <Select value={form.paymentType} onChange={(e) => setForm({ ...form, paymentType: e.target.value })}>
              {["regular", "due", "partial", "advance", "adjustment", "refund"].map((t) => (
                <option key={t} value={t}>
                  {t}
                </option>
              ))}
            </Select>
          </Field>
          <Field label="Payment date">
            <Input type="date" value={form.paymentDate} onChange={(e) => setForm({ ...form, paymentDate: e.target.value })} />
          </Field>
          <Field label="Transaction ID">
            <Input value={form.transactionId} onChange={(e) => setForm({ ...form, transactionId: e.target.value })} />
          </Field>
          <Field label="Notes" className="sm:col-span-2">
            <Textarea value={form.notes} onChange={(e) => setForm({ ...form, notes: e.target.value })} />
          </Field>
        </div>
      </Modal>

      <Modal
        open={Boolean(receipt)}
        onClose={() => setReceipt(null)}
        title={`Receipt ${receipt?.receiptNo ?? ""}`}
        subtitle="Printable payment receipt"
        footer={
          <>
            <Button variant="secondary" onClick={() => setReceipt(null)}>
              Close
            </Button>
            <Button icon={<Printer className="h-4 w-4" />} onClick={() => window.print()}>
              Print
            </Button>
          </>
        }
      >
        <KeyValue
          items={[
            { label: "Customer", value: receipt?.customerName },
            { label: "Customer code", value: receipt?.customerCode },
            { label: "Amount", value: money(receipt?.amount) },
            { label: "Discount", value: money(receipt?.discount) },
            { label: "Method", value: receipt?.methodName ?? "—" },
            { label: "Transaction ID", value: receipt?.transactionId ?? "—" },
            { label: "Invoice", value: receipt?.invoiceNo ?? "—" },
            { label: "Collected by", value: receipt?.collectorName ?? "—" },
            { label: "Date", value: formatDate(receipt?.paymentDate) },
            { label: "Notes", value: receipt?.notes ?? "—" },
          ]}
        />
      </Modal>
    </>
  );
}
