"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { Wallet, BadgeCheck, Inbox, CheckCircle2, Download } from "lucide-react";
import { api } from "@/lib/api";
import { PageHeader, StatCard, Card, Button, Badge, Skeleton } from "@/components/ui";
import { DataTable, type Column } from "@/components/data-table";
import { useConfirm } from "@/components/modal";
import { useToast } from "@/components/toast";

type Owed = { id: string; name: string; email: string; balance: number };
type HistoryRow = { id: string; affiliate: string; amount: number; method: string; reference: string | null; date: string };
type Payouts = {
  minPayout: number;
  owed: Owed[];
  requests: { id: string; affiliate: string; amount: number; date: string }[];
  totalPaid: number;
  methodBreakdown: { method: string; count: number; amount: number }[];
  history: HistoryRow[];
};

const inr = (n: number) => "₹" + n.toLocaleString("en-IN");
const methodLabel = (m: string) => (m === "STORE_CREDIT" ? "Store credit" : m === "PAYPAL" ? "PayPal" : "Manual");
const methodTone = (m: string): "brand" | "info" | "neutral" => (m === "STORE_CREDIT" ? "brand" : m === "PAYPAL" ? "info" : "neutral");

export default function PayoutsPage() {
  const toast = useToast();
  const confirm = useConfirm();
  const [data, setData] = useState<Payouts | null>(null);

  const load = useCallback(async () => setData(await api.get("/admin/payouts")), []);
  useEffect(() => {
    load();
  }, [load]);

  const markPaid = async (row: Owed) => {
    if (!(await confirm({ title: `Pay ${row.name}?`, message: `Mark ${inr(row.balance)} as paid. This clears their balance.`, confirmText: "Mark paid" }))) return;
    try {
      await api.post(`/admin/affiliates/${row.id}/mark-paid`);
      toast.success(`Paid ${inr(row.balance)} to ${row.name}.`);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  const payAllEligible = async () => {
    if (!data) return;
    const list = data.owed.filter((a) => a.balance >= data.minPayout);
    if (list.length === 0) return;
    if (!(await confirm({ title: `Pay all ${list.length} eligible?`, message: `Mark ${inr(list.reduce((s, a) => s + a.balance, 0))} paid across ${list.length} affiliates.`, confirmText: "Pay all" }))) return;
    let ok = 0;
    for (const a of list) {
      try {
        await api.post(`/admin/affiliates/${a.id}/mark-paid`);
        ok++;
      } catch {
        /* keep going */
      }
    }
    toast.success(`Paid ${ok} of ${list.length} affiliates.`);
    load();
  };

  const downloadInvoice = async (payoutId: string) => {
    try {
      const inv = await api.get(`/admin/payouts/${payoutId}/invoice`);
      const html = `<!doctype html><html><head><meta charset="utf-8"><title>${inv.invoiceNumber}</title>
<style>body{font-family:system-ui,-apple-system,sans-serif;padding:40px;color:#0f172a;max-width:640px;margin:auto}h1{color:#1A3C6E;margin:0}table{width:100%;border-collapse:collapse;margin-top:20px}td{padding:10px 0;border-bottom:1px solid #eee}.r{text-align:right}.big{font-size:22px;font-weight:700}</style></head>
<body><h1>${inv.program}</h1><p style="color:#64748b">Payout invoice · <b>${inv.invoiceNumber}</b> · ${inv.date}</p>
<table>
<tr><td>Affiliate</td><td class="r">${inv.affiliate} (${inv.email})</td></tr>
<tr><td>Method</td><td class="r">${inv.method}${inv.reference ? " · " + inv.reference : ""}</td></tr>
<tr><td>Status</td><td class="r">${inv.status}</td></tr>
<tr><td class="big">Amount paid</td><td class="r big">₹${Number(inv.amount).toLocaleString("en-IN")}</td></tr>
</table>
<p style="margin-top:36px;color:#94a3b8;font-size:12px">Generated by Partner Nook · ${inv.shop}</p></body></html>`;
      const blob = new Blob([html], { type: "text/html" });
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `${inv.invoiceNumber}.html`;
      a.click();
      URL.revokeObjectURL(url);
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  const totalOwed = useMemo(() => data?.owed.reduce((s, a) => s + a.balance, 0) ?? 0, [data]);
  const eligible = useMemo(() => data?.owed.filter((a) => a.balance >= (data?.minPayout ?? 0)).length ?? 0, [data]);

  const owedColumns: Column<Owed>[] = [
    {
      key: "name",
      header: "Affiliate",
      sortable: true,
      accessor: (r) => r.name,
      render: (r) => (
        <div>
          <div className="font-medium text-gray-900">{r.name}</div>
          <div className="text-xs text-gray-400">{r.email}</div>
        </div>
      ),
    },
    { key: "balance", header: "Balance", sortable: true, align: "right", accessor: (r) => r.balance, render: (r) => <span className="font-medium">{inr(r.balance)}</span> },
    {
      key: "eligible",
      header: "Eligible",
      align: "center",
      accessor: (r) => (r.balance >= (data?.minPayout ?? 0) ? 1 : 0),
      render: (r) => (r.balance >= (data?.minPayout ?? 0) ? <Badge tone="success">Eligible</Badge> : <Badge tone="neutral">Below min</Badge>),
    },
    {
      key: "actions",
      header: "",
      align: "right",
      render: (r) => (
        <Button size="sm" variant="success" disabled={r.balance < (data?.minPayout ?? 0)} onClick={() => markPaid(r)}>
          Mark paid
        </Button>
      ),
    },
  ];

  const historyColumns: Column<HistoryRow>[] = [
    { key: "affiliate", header: "Affiliate", sortable: true, accessor: (r) => r.affiliate, render: (r) => <span className="font-medium text-gray-900">{r.affiliate}</span> },
    { key: "amount", header: "Amount", sortable: true, align: "right", accessor: (r) => r.amount, render: (r) => inr(r.amount) },
    { key: "method", header: "Method", accessor: (r) => r.method, render: (r) => <Badge tone={methodTone(r.method)}>{methodLabel(r.method)}</Badge> },
    { key: "reference", header: "Reference", accessor: (r) => r.reference ?? "", render: (r) => (r.reference ? <span className="font-mono text-xs text-gray-600">{r.reference}</span> : <span className="text-gray-300">—</span>) },
    { key: "date", header: "Date", sortable: true, accessor: (r) => r.date, render: (r) => <span className="text-gray-500">{r.date}</span> },
    {
      key: "invoice",
      header: "",
      align: "right",
      render: (r) => (
        <button onClick={() => downloadInvoice(r.id)} className="inline-flex items-center gap-1 rounded-lg border border-gray-300 px-2 py-1 text-xs font-medium text-gray-600 hover:bg-gray-50">
          <Download className="h-3.5 w-3.5" /> Invoice
        </button>
      ),
    },
  ];

  return (
    <div>
      <PageHeader
        title="Payouts"
        subtitle={`Minimum payout ${inr(data?.minPayout ?? 0)}`}
        actions={<Button variant="success" disabled={!data || eligible === 0} onClick={payAllEligible}>Pay all eligible ({eligible})</Button>}
      />

      <div className="mb-4 grid grid-cols-2 gap-4 lg:grid-cols-4">
        {!data ? (
          Array.from({ length: 4 }).map((_, i) => <Skeleton key={i} className="h-[92px]" />)
        ) : (
          <>
            <StatCard label="Total owed" value={inr(totalOwed)} icon={<Wallet className="h-5 w-5" />} accent="#d97706" />
            <StatCard label="Eligible now" value={eligible} icon={<BadgeCheck className="h-5 w-5" />} accent="#16a34a" />
            <StatCard label="Payout requests" value={data.requests.length} icon={<Inbox className="h-5 w-5" />} accent="#2563eb" />
            <StatCard label="Total paid (lifetime)" value={inr(data.totalPaid)} icon={<CheckCircle2 className="h-5 w-5" />} accent="#1A3C6E" />
          </>
        )}
      </div>

      <div className="mb-4 grid gap-4 lg:grid-cols-2">
        {data && data.requests.length > 0 && (
          <Card title="Payout requests" subtitle="Raised by affiliates">
            <ul className="divide-y divide-gray-50 text-sm">
              {data.requests.map((r) => (
                <li key={r.id} className="flex items-center justify-between py-2">
                  <span className="text-gray-700">{r.affiliate}</span>
                  <span className="flex items-center gap-3">
                    <span className="font-medium text-gray-900">{inr(r.amount)}</span>
                    <span className="text-xs text-gray-400">{r.date}</span>
                  </span>
                </li>
              ))}
            </ul>
          </Card>
        )}
        {data && data.methodBreakdown.length > 0 && (
          <Card title="Paid by method" subtitle="Lifetime breakdown">
            <ul className="divide-y divide-gray-50 text-sm">
              {data.methodBreakdown.map((m) => (
                <li key={m.method} className="flex items-center justify-between py-2">
                  <Badge tone={methodTone(m.method)}>{methodLabel(m.method)}</Badge>
                  <span className="flex items-center gap-3">
                    <span className="text-xs text-gray-400">{m.count} payout{m.count === 1 ? "" : "s"}</span>
                    <span className="font-medium text-gray-900">{inr(m.amount)}</span>
                  </span>
                </li>
              ))}
            </ul>
          </Card>
        )}
      </div>

      <div className="space-y-6">
        <div>
          <h2 className="mb-2 text-sm font-semibold text-gray-700">Pending balances</h2>
          <DataTable
            columns={owedColumns}
            rows={data?.owed ?? []}
            rowKey={(r) => r.id}
            loading={!data}
            exportName="payouts-owed"
            searchPlaceholder="Search affiliate…"
            empty={{ icon: <Wallet className="h-6 w-6" />, title: "Nothing to pay out", description: "Affiliates with a pending balance will appear here." }}
          />
        </div>

        <div>
          <h2 className="mb-2 text-sm font-semibold text-gray-700">Payment history</h2>
          <DataTable
            columns={historyColumns}
            rows={data?.history ?? []}
            rowKey={(r) => r.id}
            loading={!data}
            exportName="payouts-history"
            searchPlaceholder="Search affiliate…"
            empty={{ icon: <CheckCircle2 className="h-6 w-6" />, title: "No payments yet", description: "Paid payouts — with downloadable invoices — will appear here." }}
          />
        </div>
      </div>
    </div>
  );
}
