"use client";

import { useCallback, useEffect, useState } from "react";
import { Ticket, Store, Layers, Plus, Pencil, Trash2, ChevronDown, ChevronUp } from "lucide-react";
import { api } from "@/lib/api";
import { PageHeader, Button, Badge, Card, FormField, Input, Select, Checkbox } from "@/components/ui";
import { DataTable, type Column } from "@/components/data-table";
import { Modal, useConfirm } from "@/components/modal";
import { useToast } from "@/components/toast";

type Combines = { product: boolean; order: boolean; shipping: boolean };
type Coupon = {
  id: string;
  name: string;
  couponCode: string | null;
  discountType: string | null;
  discountValue: number | null;
  usageLimit: number | null;
  maxRedemptions: number | null;
  newCustomersOnly: boolean;
  minOrderValue: number | null;
  minCartQty: number | null;
  expiresAt: string | null;
  combines: Combines;
  personal: boolean;
  status: string;
};
type Assignable = { id: string; name: string; email: string; hasCoupon: boolean };

const inr = (n: number) => "₹" + n.toLocaleString("en-IN");

const emptyForm = {
  affiliateId: "",
  couponCode: "",
  discountType: "PERCENT",
  discountValue: "",
  singleUsePerCustomer: false,
  maxRedemptions: "",
  minOrderValue: "",
  minCartQty: "",
  expiresAt: "",
  newCustomersOnly: false,
  personal: false,
  combineProduct: false,
  combineOrder: false,
  combineShipping: false,
  pushToShopify: true,
};
type Form = typeof emptyForm;

export default function CouponsPage() {
  const toast = useToast();
  const confirm = useConfirm();
  const [rows, setRows] = useState<Coupon[]>([]);
  const [loading, setLoading] = useState(true);
  const [assignable, setAssignable] = useState<Assignable[]>([]);

  const [editorOpen, setEditorOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [form, setForm] = useState<Form>(emptyForm);
  const [advanced, setAdvanced] = useState(false);
  const [busy, setBusy] = useState(false);

  const [bulkOpen, setBulkOpen] = useState(false);
  const [bulk, setBulk] = useState({ discountType: "PERCENT", discountValue: "", newCustomersOnly: false });
  const [bulkBusy, setBulkBusy] = useState(false);
  const [pushing, setPushing] = useState(false);

  const [autoOpen, setAutoOpen] = useState(false);
  const [auto, setAuto] = useState<{ discountType: string; discountValue: string; singleUsePerCustomer: boolean; maxRedemptions: string; minOrderValue: string; newCustomersOnly: boolean; autoApplyDiscount: boolean; defaultCouponCode: string } | null>(null);
  const [autoBusy, setAutoBusy] = useState(false);

  const loadAuto = useCallback(async () => {
    const a = await api.get("/admin/auto-coupon");
    setAuto({
      discountType: a.discountType ?? "PERCENT",
      discountValue: a.discountValue?.toString() ?? "",
      singleUsePerCustomer: !!a.singleUsePerCustomer,
      maxRedemptions: a.maxRedemptions?.toString() ?? "",
      minOrderValue: a.minOrderValue?.toString() ?? "",
      newCustomersOnly: !!a.newCustomersOnly,
      autoApplyDiscount: !!a.autoApplyDiscount,
      defaultCouponCode: a.defaultCouponCode ?? "",
    });
  }, []);
  useEffect(() => {
    loadAuto();
  }, [loadAuto]);

  const setA = (patch: Partial<NonNullable<typeof auto>>) => setAuto((a) => (a ? { ...a, ...patch } : a));
  const saveAuto = async () => {
    if (!auto) return;
    setAutoBusy(true);
    try {
      await api.put("/admin/auto-coupon", auto);
      toast.success("Automatic Coupons saved.");
      setAutoOpen(false);
    } catch (e) {
      toast.error((e as Error).message);
    } finally {
      setAutoBusy(false);
    }
  };

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const [coupons, assign] = await Promise.all([api.get("/admin/coupons"), api.get("/admin/coupons/assignable")]);
      setRows(coupons);
      setAssignable(assign);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    load();
  }, [load]);

  const set = (patch: Partial<Form>) => setForm((f) => ({ ...f, ...patch }));

  const openCreate = () => {
    setEditingId(null);
    setForm(emptyForm);
    setAdvanced(false);
    setEditorOpen(true);
  };
  const openEdit = (c: Coupon) => {
    setEditingId(c.id);
    setForm({
      affiliateId: c.id,
      couponCode: c.couponCode ?? "",
      discountType: c.discountType ?? "PERCENT",
      discountValue: c.discountValue?.toString() ?? "",
      singleUsePerCustomer: c.usageLimit != null && c.usageLimit <= 1,
      maxRedemptions: c.maxRedemptions?.toString() ?? "",
      minOrderValue: c.minOrderValue?.toString() ?? "",
      minCartQty: c.minCartQty?.toString() ?? "",
      expiresAt: c.expiresAt ?? "",
      newCustomersOnly: c.newCustomersOnly,
      personal: c.personal ?? false,
      combineProduct: c.combines?.product ?? false,
      combineOrder: c.combines?.order ?? false,
      combineShipping: c.combines?.shipping ?? false,
      pushToShopify: false,
    });
    setAdvanced(!!(c.minCartQty || c.combines?.product || c.combines?.order || c.combines?.shipping));
    setEditorOpen(true);
  };

  const save = async () => {
    if (!editingId && !form.affiliateId) {
      toast.error("Choose an affiliate.");
      return;
    }
    if (form.couponCode.trim().length < 3) {
      toast.error("Coupon code must be at least 3 characters.");
      return;
    }
    setBusy(true);
    const payload = {
      affiliateId: form.affiliateId,
      couponCode: form.couponCode,
      discountType: form.discountType,
      discountValue: form.discountValue,
      usageLimitPerCustomer: form.singleUsePerCustomer ? 1 : "",
      maxRedemptions: form.maxRedemptions,
      minOrderValue: form.minOrderValue,
      minCartQty: form.minCartQty,
      expiresAt: form.expiresAt || null,
      newCustomersOnly: form.newCustomersOnly,
      personal: form.personal,
      combines: { product: form.combineProduct, order: form.combineOrder, shipping: form.combineShipping },
      pushToShopify: form.pushToShopify,
    };
    try {
      if (editingId) {
        await api.put(`/admin/coupons/${editingId}`, payload);
        toast.success("Coupon updated.");
      } else {
        const r = await api.post("/admin/coupons", payload);
        if (r.shopify?.pushed) toast.success(`Coupon ${r.couponCode} created & pushed to Shopify.`);
        else if (r.shopify?.error) toast.success(`Coupon ${r.couponCode} created (Shopify push failed: ${r.shopify.error}).`);
        else toast.success(`Coupon ${r.couponCode} created.`);
      }
      setEditorOpen(false);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    } finally {
      setBusy(false);
    }
  };

  const remove = async (c: Coupon) => {
    if (!(await confirm({ title: `Remove ${c.name}'s coupon?`, message: `Code ${c.couponCode} will be removed from this affiliate.`, tone: "danger", confirmText: "Remove" }))) return;
    try {
      await api.del(`/admin/coupons/${c.id}`);
      toast.info("Coupon removed.");
      load();
    } catch (e) {
      toast.error((e as Error).message);
    }
  };

  const applyBulk = async () => {
    setBulkBusy(true);
    try {
      const r = await api.post("/admin/coupons/bulk-update", bulk);
      if (r.ok) toast.success(`Updated ${r.updated} coupon(s).`);
      else toast.error(r.message || "Nothing to update.");
      setBulkOpen(false);
      load();
    } catch (e) {
      toast.error((e as Error).message);
    } finally {
      setBulkBusy(false);
    }
  };

  const pushToShopify = async () => {
    setPushing(true);
    try {
      const r = await api.post("/shopify/push-coupons");
      if (r.created !== undefined) toast.success(`${r.created} code(s) created in Shopify${r.failed ? `, ${r.failed} failed` : ""}.`);
      else toast.error(r.message || "Connect Shopify first.");
    } catch (e) {
      toast.error((e as Error).message);
    } finally {
      setPushing(false);
    }
  };

  const disc = (c: Coupon) => (c.discountValue == null ? "—" : c.discountType === "FIXED" ? inr(c.discountValue) : `${c.discountValue}%`);

  const columns: Column<Coupon>[] = [
    { key: "couponCode", header: "Code", sortable: true, accessor: (r) => r.couponCode ?? "", render: (r) => (
      <span className="flex items-center gap-2">
        <span className="font-mono text-xs font-semibold text-gray-700">{r.couponCode}</span>
        {r.personal && <Badge tone="neutral">Personal</Badge>}
      </span>
    ) },
    { key: "name", header: "Affiliate", sortable: true, accessor: (r) => r.name },
    { key: "discount", header: "Discount", accessor: (r) => r.discountValue ?? 0, render: (r) => <Badge tone="brand">{disc(r)} off</Badge> },
    { key: "minOrderValue", header: "Min order", align: "right", accessor: (r) => r.minOrderValue ?? 0, render: (r) => (r.minOrderValue ? inr(r.minOrderValue) : "—") },
    { key: "maxRedemptions", header: "Max uses", align: "right", accessor: (r) => r.maxRedemptions ?? 0, render: (r) => r.maxRedemptions ?? "∞" },
    { key: "newCustomersOnly", header: "New only", align: "center", accessor: (r) => (r.newCustomersOnly ? 1 : 0), render: (r) => (r.newCustomersOnly ? <Badge tone="info">Yes</Badge> : <span className="text-gray-400">—</span>) },
    { key: "expiresAt", header: "Expires", accessor: (r) => r.expiresAt ?? "", render: (r) => (r.expiresAt ? <span className="text-gray-600">{r.expiresAt}</span> : <span className="text-gray-400">Never</span>) },
    {
      key: "actions",
      header: "",
      align: "right",
      render: (r) => (
        <div className="flex justify-end gap-1">
          <button onClick={() => openEdit(r)} className="rounded-lg border border-gray-300 p-1.5 text-gray-500 hover:bg-gray-50" title="Edit"><Pencil className="h-3.5 w-3.5" /></button>
          <button onClick={() => remove(r)} className="rounded-lg border border-gray-300 p-1.5 text-gray-500 hover:bg-red-50 hover:text-red-600" title="Remove"><Trash2 className="h-3.5 w-3.5" /></button>
        </div>
      ),
    },
  ];

  const assignOptions = assignable.filter((a) => editingId || !a.hasCoupon);

  return (
    <div>
      <PageHeader
        title="Coupons"
        subtitle="Assign discount codes to affiliates"
        actions={
          <div className="flex flex-wrap gap-2">
            <Button variant="secondary" size="sm" icon={<Layers className="h-4 w-4" />} onClick={() => setBulkOpen(true)}>Bulk update</Button>
            <Button variant="secondary" size="sm" icon={<Store className="h-4 w-4" />} loading={pushing} onClick={pushToShopify}>Push to Shopify</Button>
            <Button size="sm" icon={<Plus className="h-4 w-4" />} onClick={openCreate}>Create coupon</Button>
          </div>
        }
      />

      <DataTable
        columns={columns}
        rows={rows}
        rowKey={(r) => r.id}
        loading={loading}
        exportName="coupons"
        searchPlaceholder="Search code, affiliate…"
        empty={{ icon: <Ticket className="h-6 w-6" />, title: "No coupons yet", description: "Click ‘Create coupon’ to assign a discount code to an affiliate." }}
      />

      {/* Automatic Coupons + auto-apply (GoAffPro-style) */}
      <div className="mt-4 grid gap-4 lg:grid-cols-2">
        <Card title="Automatic Coupons" subtitle="Default discount applied to every new affiliate's coupon">
          {!auto ? (
            <div className="h-16" />
          ) : (
            <div className="flex items-center justify-between gap-4">
              <p className="text-sm text-gray-600">
                Current: <span className="font-medium text-gray-900">{auto.discountValue || 0}{auto.discountType === "FIXED" ? "₹" : "%"} off</span>
                {auto.newCustomersOnly && " · new customers only"}
                {auto.singleUsePerCustomer && " · 1 per customer"}
              </p>
              <Button size="sm" variant="secondary" onClick={() => setAutoOpen(true)}>Setup</Button>
            </div>
          )}
        </Card>
        <Card title="Automatically apply discount" subtitle="Apply the coupon at checkout when a referral link is used">
          {!auto ? (
            <div className="h-16" />
          ) : (
            <div className="flex items-center justify-between gap-4">
              <Badge tone={auto.autoApplyDiscount ? "success" : "neutral"}>{auto.autoApplyDiscount ? "On" : "Off"}</Badge>
              <Button size="sm" variant="secondary" onClick={() => setAutoOpen(true)}>Configure</Button>
            </div>
          )}
        </Card>
      </div>

      {/* Automatic Coupons modal */}
      <Modal
        open={autoOpen}
        onClose={() => setAutoOpen(false)}
        title="Automatic Coupons"
        footer={<><Button variant="secondary" onClick={() => setAutoOpen(false)}>Cancel</Button><Button onClick={saveAuto} loading={autoBusy}>Save</Button></>}
      >
        {auto && (
          <div className="grid gap-4 sm:grid-cols-2">
            <p className="text-sm text-gray-500 sm:col-span-2">These settings decide the discount an affiliate&apos;s coupon gets when they&apos;re approved.</p>
            <FormField label="Discount type">
              <Select value={auto.discountType} onChange={(e) => setA({ discountType: e.target.value })}>
                <option value="PERCENT">Percentage off</option>
                <option value="FIXED">Fixed ₹ off</option>
              </Select>
            </FormField>
            <FormField label="Discount value">
              <Input type="number" min={0} value={auto.discountValue} onChange={(e) => setA({ discountValue: e.target.value })} placeholder="e.g. 10" />
            </FormField>
            <FormField label="Allowed uses (total)" hint="Blank = unlimited">
              <Input type="number" min={0} value={auto.maxRedemptions} onChange={(e) => setA({ maxRedemptions: e.target.value })} placeholder="Unlimited" />
            </FormField>
            <FormField label="Minimum order value (₹)" hint="Optional">
              <Input type="number" min={0} value={auto.minOrderValue} onChange={(e) => setA({ minOrderValue: e.target.value })} placeholder="No minimum" />
            </FormField>
            <div className="space-y-3 sm:col-span-2">
              <Checkbox label="Limit to single use per customer" checked={auto.singleUsePerCustomer} onChange={(e) => setA({ singleUsePerCustomer: e.target.checked })} />
              <Checkbox label="Give discount to new customers only" checked={auto.newCustomersOnly} onChange={(e) => setA({ newCustomersOnly: e.target.checked })} />
            </div>
            <div className="border-t border-gray-100 pt-4 sm:col-span-2">
              <Checkbox label="Automatically apply discount at checkout when referral link is used" checked={auto.autoApplyDiscount} onChange={(e) => setA({ autoApplyDiscount: e.target.checked })} />
              {auto.autoApplyDiscount && (
                <div className="mt-3">
                  <FormField label="Default coupon code" hint="Used when no affiliate is matched">
                    <Input value={auto.defaultCouponCode} onChange={(e) => setA({ defaultCouponCode: e.target.value.toUpperCase() })} placeholder="WELCOME10" className="font-mono" />
                  </FormField>
                </div>
              )}
            </div>
          </div>
        )}
      </Modal>

      {/* Create / edit coupon */}
      <Modal
        open={editorOpen}
        onClose={() => setEditorOpen(false)}
        title={editingId ? "Edit coupon" : "Create coupon"}
        footer={<><Button variant="secondary" onClick={() => setEditorOpen(false)}>Cancel</Button><Button onClick={save} loading={busy}>{editingId ? "Save changes" : "Create coupon"}</Button></>}
      >
        <div className="grid gap-4 sm:grid-cols-2">
          <div className="sm:col-span-2">
            <FormField label="Affiliate" required>
              {editingId ? (
                <Input value={rows.find((r) => r.id === editingId)?.name ?? ""} disabled />
              ) : (
                <Select value={form.affiliateId} onChange={(e) => set({ affiliateId: e.target.value })}>
                  <option value="">Choose an affiliate…</option>
                  {assignOptions.map((a) => (
                    <option key={a.id} value={a.id}>{a.name} ({a.email})</option>
                  ))}
                </Select>
              )}
            </FormField>
          </div>

          <FormField label="Coupon code" required>
            <Input value={form.couponCode} onChange={(e) => set({ couponCode: e.target.value.toUpperCase() })} placeholder="SARA10" className="font-mono" />
          </FormField>
          <FormField label="Discount type">
            <Select value={form.discountType} onChange={(e) => set({ discountType: e.target.value })}>
              <option value="PERCENT">Percentage off</option>
              <option value="FIXED">Fixed ₹ off</option>
            </Select>
          </FormField>
          <FormField label="Discount value" required>
            <Input type="number" min={0} value={form.discountValue} onChange={(e) => set({ discountValue: e.target.value })} placeholder={form.discountType === "FIXED" ? "e.g. 200" : "e.g. 10"} />
          </FormField>
          <FormField label="Minimum order value (₹)" hint="Optional">
            <Input type="number" min={0} value={form.minOrderValue} onChange={(e) => set({ minOrderValue: e.target.value })} placeholder="No minimum" />
          </FormField>
          <FormField label="Allowed uses (total)" hint="Blank = unlimited">
            <Input type="number" min={0} value={form.maxRedemptions} onChange={(e) => set({ maxRedemptions: e.target.value })} placeholder="Unlimited" />
          </FormField>
          <FormField label="Expires on" hint="Optional">
            <Input type="date" value={form.expiresAt} onChange={(e) => set({ expiresAt: e.target.value })} />
          </FormField>

          <div className="space-y-3 sm:col-span-2">
            <Checkbox label="Limit to single use per customer" checked={form.singleUsePerCustomer} onChange={(e) => set({ singleUsePerCustomer: e.target.checked })} />
            <Checkbox label="Give discount to new customers only" checked={form.newCustomersOnly} onChange={(e) => set({ newCustomersOnly: e.target.checked })} />
            <Checkbox label="Personal coupon (affiliate's own use — earns no commission)" checked={form.personal} onChange={(e) => set({ personal: e.target.checked })} />
            {!editingId && (
              <Checkbox label="Create this code in Shopify now" checked={form.pushToShopify} onChange={(e) => set({ pushToShopify: e.target.checked })} />
            )}
          </div>

          {/* Advanced (GoAffPro-style) */}
          <div className="sm:col-span-2">
            <button type="button" onClick={() => setAdvanced((a) => !a)} className="flex items-center gap-1 text-sm font-medium text-[var(--brand)] hover:underline">
              Advanced {advanced ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
            </button>
          </div>
          {advanced && (
            <>
              <FormField label="Minimum cart quantity" hint="Used only if no min order value">
                <Input type="number" min={0} value={form.minCartQty} onChange={(e) => set({ minCartQty: e.target.value })} placeholder="No minimum" />
              </FormField>
              <div className="hidden sm:block" />
              <div className="sm:col-span-2">
                <p className="mb-2 text-sm font-medium text-gray-700">Combine with other discounts</p>
                <div className="space-y-2">
                  <Checkbox label="Product discounts" checked={form.combineProduct} onChange={(e) => set({ combineProduct: e.target.checked })} />
                  <Checkbox label="Order discounts" checked={form.combineOrder} onChange={(e) => set({ combineOrder: e.target.checked })} />
                  <Checkbox label="Shipping discounts" checked={form.combineShipping} onChange={(e) => set({ combineShipping: e.target.checked })} />
                </div>
              </div>
            </>
          )}
        </div>
      </Modal>

      {/* Bulk update */}
      <Modal
        open={bulkOpen}
        onClose={() => setBulkOpen(false)}
        title="Bulk update coupons"
        footer={<><Button variant="secondary" onClick={() => setBulkOpen(false)}>Cancel</Button><Button onClick={applyBulk} loading={bulkBusy}>Apply to all</Button></>}
      >
        <p className="mb-4 text-sm text-gray-500">Applies to every active affiliate&apos;s coupon.</p>
        <div className="grid gap-4 sm:grid-cols-2">
          <FormField label="Discount type">
            <Select value={bulk.discountType} onChange={(e) => setBulk({ ...bulk, discountType: e.target.value })}>
              <option value="PERCENT">Percent off</option>
              <option value="FIXED">Fixed ₹ off</option>
            </Select>
          </FormField>
          <FormField label="Discount value">
            <Input type="number" min={0} value={bulk.discountValue} onChange={(e) => setBulk({ ...bulk, discountValue: e.target.value })} placeholder="e.g. 10" />
          </FormField>
          <div className="sm:col-span-2">
            <Checkbox label="Restrict to new customers only" checked={bulk.newCustomersOnly} onChange={(e) => setBulk({ ...bulk, newCustomersOnly: e.target.checked })} />
          </div>
        </div>
      </Modal>
    </div>
  );
}
