"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { Users, Check, X, UserPlus } from "lucide-react";
import { api } from "@/lib/api";
import { PageHeader, Button, StatusBadge, Select, FormField, Input } from "@/components/ui";
import { DataTable, type Column } from "@/components/data-table";
import { useToast } from "@/components/toast";
import { Modal, useConfirm } from "@/components/modal";

type Aff = {
  id: string;
  name: string;
  email: string;
  status: string;
  couponCode: string | null;
  clicks: number;
  sales: number;
  balance: number;
};
type Group = { id: string; name: string };

const inr = (n: number) => "₹" + n.toLocaleString("en-IN");
const emptyForm = { name: "", email: "", password: "", status: "PENDING", groupId: "" };

export default function AffiliatesPage() {
  const router = useRouter();
  const toast = useToast();
  const confirm = useConfirm();
  const [rows, setRows] = useState<Aff[]>([]);
  const [groups, setGroups] = useState<Group[]>([]);
  const [loading, setLoading] = useState(true);
  const [status, setStatus] = useState("");
  const [selectedRows, setSelectedRows] = useState<Aff[]>([]);
  const [resetKey, setResetKey] = useState(0);

  const [addOpen, setAddOpen] = useState(false);
  const [form, setForm] = useState(emptyForm);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      setRows(await api.get("/admin/affiliates"));
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
    api.get("/admin/groups").then(setGroups).catch(() => {});
  }, [load]);

  const approve = async (a: Aff) => {
    try {
      await api.post(`/admin/affiliates/${a.id}/approve`);
      toast.success(`${a.name} approved — coupon issued.`);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    }
  };
  const reject = async (a: Aff) => {
    if (!(await confirm({ title: `Reject ${a.name}?`, message: "They won't be able to earn commissions.", tone: "danger", confirmText: "Reject" }))) return;
    try {
      await api.post(`/admin/affiliates/${a.id}/reject`);
      toast.info(`${a.name} rejected.`);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    }
  };
  const bulkApprove = async () => {
    const ids = selectedRows.filter((r) => r.status === "PENDING").map((r) => r.id);
    if (ids.length === 0) {
      toast.info("Select one or more pending affiliates.");
      return;
    }
    if (!(await confirm({ title: `Approve ${ids.length} affiliate(s)?`, message: "They'll be activated and issued coupons + welcome emails.", confirmText: "Approve all" }))) return;
    try {
      const r = await api.post("/admin/affiliates/bulk-approve", { ids });
      toast.success(`${r.approved} affiliate(s) approved.`);
      setSelectedRows([]);
      setResetKey((k) => k + 1);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  const bulkReject = async () => {
    const ids = selectedRows.map((r) => r.id);
    if (!ids.length) return;
    if (!(await confirm({ title: `Reject ${ids.length} affiliate(s)?`, tone: "danger", confirmText: "Reject all" }))) return;
    try {
      const r = await api.post("/admin/affiliates/bulk-reject", { ids });
      toast.success(`${r.rejected} rejected.`);
      setSelectedRows([]); setResetKey((k) => k + 1); load();
    } catch (e) { toast.error((e as Error).message); }
  };

  const bulkDelete = async () => {
    const ids = selectedRows.map((r) => r.id);
    if (!ids.length) return;
    if (!(await confirm({ title: `Delete ${ids.length} affiliate(s)?`, message: "This permanently removes them and their data.", tone: "danger", confirmText: "Delete all" }))) return;
    try {
      const r = await api.post("/admin/affiliates/bulk-delete", { ids });
      toast.info(`${r.deleted} deleted.`);
      setSelectedRows([]); setResetKey((k) => k + 1); load();
    } catch (e) { toast.error((e as Error).message); }
  };

  const createAffiliate = async () => {
    const e: Record<string, string> = {};
    if (!form.name.trim()) e.name = "Name is required.";
    if (!form.email.trim()) e.email = "Email is required.";
    else if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(form.email)) e.email = "Enter a valid email.";
    setErrors(e);
    if (Object.keys(e).length) return;
    setSaving(true);
    try {
      await api.post("/admin/affiliates", form);
      toast.success(`${form.name} added.`);
      setForm(emptyForm);
      setAddOpen(false);
      load();
    } catch (err) {
      toast.error((err as Error).message);
    } finally {
      setSaving(false);
    }
  };

  const filtered = useMemo(() => (status ? rows.filter((r) => r.status === status) : rows), [rows, status]);

  const columns: Column<Aff>[] = [
    {
      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: "status", header: "Status", sortable: true, accessor: (r) => r.status, render: (r) => <StatusBadge status={r.status} /> },
    { key: "couponCode", header: "Coupon", accessor: (r) => r.couponCode ?? "", render: (r) => <span className="font-mono text-xs text-gray-600">{r.couponCode ?? "—"}</span> },
    { key: "clicks", header: "Clicks", sortable: true, align: "right", accessor: (r) => r.clicks },
    { key: "sales", header: "Sales", sortable: true, align: "right", accessor: (r) => r.sales },
    { key: "balance", header: "Balance", sortable: true, align: "right", accessor: (r) => r.balance, render: (r) => <span className="font-medium">{inr(r.balance)}</span> },
    {
      key: "actions",
      header: "",
      align: "right",
      render: (r) =>
        r.status === "PENDING" ? (
          <div className="flex justify-end gap-2" onClick={(e) => e.stopPropagation()}>
            <Button size="sm" variant="success" icon={<Check className="h-3.5 w-3.5" />} onClick={() => approve(r)}>Approve</Button>
            <Button size="sm" variant="secondary" icon={<X className="h-3.5 w-3.5" />} onClick={() => reject(r)}>Reject</Button>
          </div>
        ) : (
          <span className="text-xs text-[var(--brand)]">Edit →</span>
        ),
    },
  ];

  const inputErr = (k: string) => errors[k];

  return (
    <div>
      <PageHeader
        title="Affiliates"
        subtitle={`${rows.length} partner${rows.length === 1 ? "" : "s"} in your program`}
        actions={<Button icon={<UserPlus className="h-4 w-4" />} onClick={() => setAddOpen(true)}>Add affiliate</Button>}
      />

      {selectedRows.length > 0 && (
        <div className="mb-3 flex items-center justify-between rounded-lg border border-[var(--brand)]/20 bg-[var(--brand-50)] px-4 py-2.5">
          <span className="text-sm font-medium text-[var(--brand)]">{selectedRows.length} selected</span>
          <Button size="sm" onClick={bulkApprove}>Approve pending</Button>
          <Button size="sm" variant="secondary" onClick={bulkReject}>Reject</Button>
          <Button size="sm" variant="secondary" onClick={bulkDelete}>Delete</Button>
        </div>
      )}

      <DataTable
        columns={columns}
        rows={filtered}
        rowKey={(r) => r.id}
        loading={loading}
        exportName="affiliates"
        searchPlaceholder="Search name, email, coupon…"
        selectable
        onSelectionChange={setSelectedRows}
        selectionResetKey={resetKey}
        onRowClick={(r) => router.push(`/admin/affiliates/${r.id}`)}
        filters={
          <Select value={status} onChange={(e) => setStatus(e.target.value)} className="h-9 w-40">
            <option value="">All statuses</option>
            <option value="PENDING">Pending</option>
            <option value="ACTIVE">Active</option>
            <option value="REJECTED">Rejected</option>
          </Select>
        }
        empty={{ icon: <Users className="h-6 w-6" />, title: "No affiliates yet", description: "Add one manually or wait for signups.", action: <Button size="sm" icon={<UserPlus className="h-4 w-4" />} onClick={() => setAddOpen(true)}>Add affiliate</Button> }}
      />

      <Modal
        open={addOpen}
        onClose={() => setAddOpen(false)}
        title="Add affiliate"
        footer={
          <>
            <Button variant="secondary" onClick={() => setAddOpen(false)}>Cancel</Button>
            <Button onClick={createAffiliate} loading={saving}>Add affiliate</Button>
          </>
        }
      >
        <div className="grid gap-4 sm:grid-cols-2">
          <div className="sm:col-span-2">
            <FormField label="Full name" required error={inputErr("name")}>
              <Input error={!!inputErr("name")} value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} placeholder="Sara Khan" />
            </FormField>
          </div>
          <div className="sm:col-span-2">
            <FormField label="Email" required error={inputErr("email")}>
              <Input error={!!inputErr("email")} value={form.email} onChange={(e) => setForm({ ...form, email: e.target.value })} placeholder="sara@example.com" />
            </FormField>
          </div>
          <FormField label="Password" hint="Optional — for portal login">
            <Input type="password" value={form.password} onChange={(e) => setForm({ ...form, password: e.target.value })} />
          </FormField>
          <FormField label="Status">
            <Select value={form.status} onChange={(e) => setForm({ ...form, status: e.target.value })}>
              <option value="PENDING">Pending</option>
              <option value="ACTIVE">Active (issue coupon now)</option>
            </Select>
          </FormField>
          <div className="sm:col-span-2">
            <FormField label="Commission group">
              <Select value={form.groupId} onChange={(e) => setForm({ ...form, groupId: e.target.value })}>
                <option value="">No group (use default)</option>
                {groups.map((g) => (
                  <option key={g.id} value={g.id}>{g.name}</option>
                ))}
              </Select>
            </FormField>
          </div>
        </div>
      </Modal>
    </div>
  );
}
