"use client";

import { useEffect, useState } from "react";
import {
  Wallet,
  CheckCircle2,
  XCircle,
  Clock3,
  Check,
  X,
  Pencil,
  Plus,
  Trash2,
  ImageOff,
  Hash,
  CreditCard,
  CalendarClock,
  AlertCircle,
} from "lucide-react";
import { PageHeader } from "@/components/ui/PageHeader";
import { StatCard } from "@/components/ui/StatCard";
import { Avatar } from "@/components/ui/Avatar";
import { NetworkBadge } from "@/components/NetworkBadge";
import { Drawer } from "@/components/ui/Drawer";
import { Button } from "@/components/ui/Button";
import { Switch } from "@/components/ui/Switch";
import { TextField, SelectField } from "@/components/ui/Field";
import { EmptyState } from "@/components/ui/EmptyState";
import { Skeleton } from "@/components/ui/Skeleton";
import { formatCurrency, formatDateTime } from "@/lib/mock-data";
import { useAdminOrders } from "@/lib/data/admin-orders-provider";
import { totalRevenue, countByStatus } from "@/lib/data/dashboard-stats";
import {
  AdminPaymentMethod,
  PaymentMethodInput,
  PaymentMethodInUseError,
  fetchAllPaymentMethods,
  createPaymentMethod,
  updatePaymentMethodDetails,
  setPaymentMethodActive,
  deletePaymentMethod,
} from "@/lib/data/payment-methods";
import { PaymentMethodTypeDb } from "@/lib/supabase/types";
import { NetworkId } from "@/lib/types";
import { cn } from "@/lib/cn";

// Payment accounts get full CRUD on purpose — unlike packages, these are
// operational receiving accounts (a JazzCash number, a bank account),
// not a fixed product catalog. Admins can freely add a new one or remove
// one that was never actually used; an account with real order history
// can only be disabled (see lib/data/payment-methods.ts).

const METHOD_TYPE_OPTIONS: { value: PaymentMethodTypeDb; label: string }[] = [
  { value: "jazzcash", label: "JazzCash" },
  { value: "easypaisa", label: "EasyPaisa" },
  { value: "bank", label: "Bank Account" },
];

const METHOD_LABEL_DEFAULT: Record<PaymentMethodTypeDb, string> = {
  jazzcash: "JazzCash",
  easypaisa: "EasyPaisa",
  bank: "Bank Transfer",
};

type AccountFormState = {
  methodType: PaymentMethodTypeDb;
  label: string;
  accountTitle: string;
  accountNumber: string;
};

const EMPTY_FORM: AccountFormState = {
  methodType: "jazzcash",
  label: "",
  accountTitle: "",
  accountNumber: "",
};

function accountToForm(acc: AdminPaymentMethod): AccountFormState {
  return {
    methodType: acc.methodType,
    label: acc.label,
    accountTitle: acc.accountTitle,
    accountNumber: acc.accountNumber,
  };
}

export default function PaymentsPage() {
  // Same shared context Orders/Dashboard already use — the Verification
  // Queue below is real data and real actions, not a second, disconnected
  // copy of the Orders page.
  const { orders, loading: ordersLoading, error: ordersError, approveOrder, rejectOrder } = useAdminOrders();

  const [accounts, setAccounts] = useState<AdminPaymentMethod[]>([]);
  const [accountsLoading, setAccountsLoading] = useState(true);
  const [accountsError, setAccountsError] = useState<string | null>(null);

  const [editingAccount, setEditingAccount] = useState<AdminPaymentMethod | null>(null);
  const [creating, setCreating] = useState(false);
  const [form, setForm] = useState<AccountFormState>(EMPTY_FORM);
  const [formError, setFormError] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [togglingId, setTogglingId] = useState<string | null>(null);
  const [confirmingDeleteId, setConfirmingDeleteId] = useState<string | null>(null);
  const [deleting, setDeleting] = useState(false);

  const [selectedOrderId, setSelectedOrderId] = useState<string | null>(null);
  const [screenshotUrl, setScreenshotUrl] = useState<string | null>(null);
  const [queueActionError, setQueueActionError] = useState<string | null>(null);
  const [actingOnOrder, setActingOnOrder] = useState<string | null>(null);

  const selectedOrder = orders.find((o) => o.dbId === selectedOrderId) ?? null;
  const pendingQueue = orders.filter((o) => o.status === "pending");

  async function loadAccounts() {
    try {
      const result = await fetchAllPaymentMethods();
      setAccounts(result);
      setAccountsError(null);
    } catch (err) {
      setAccountsError(err instanceof Error ? err.message : "Couldn't load payment accounts.");
    } finally {
      setAccountsLoading(false);
    }
  }

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

  useEffect(() => {
    setQueueActionError(null);
    setScreenshotUrl(selectedOrder?.screenshotPath ?? null);
  }, [selectedOrder?.dbId, selectedOrder?.screenshotPath]);

  function openEdit(acc: AdminPaymentMethod) {
    setEditingAccount(acc);
    setCreating(false);
    setForm(accountToForm(acc));
    setFormError(null);
  }

  function openCreate() {
    setEditingAccount(null);
    setCreating(true);
    setForm(EMPTY_FORM);
    setFormError(null);
  }

  function closeDrawer() {
    setEditingAccount(null);
    setCreating(false);
    setFormError(null);
  }

  function validateForm(f: AccountFormState): string | null {
    if (!f.label.trim()) return "Give this account a label.";
    if (!f.accountTitle.trim()) return "Account title is required.";
    if (!f.accountNumber.trim()) return "Account number is required.";
    return null;
  }

  async function handleSave() {
    const validationError = validateForm(form);
    if (validationError) {
      setFormError(validationError);
      return;
    }
    setFormError(null);
    setSaving(true);
    try {
      const input: PaymentMethodInput = {
        methodType: form.methodType,
        label: form.label.trim(),
        accountTitle: form.accountTitle.trim(),
        accountNumber: form.accountNumber.trim(),
      };
      if (creating) {
        await createPaymentMethod(input);
      } else if (editingAccount) {
        await updatePaymentMethodDetails(editingAccount.dbId, input);
      }
      await loadAccounts();
      closeDrawer();
    } catch (err) {
      setFormError(err instanceof Error ? err.message : "Couldn't save changes.");
    } finally {
      setSaving(false);
    }
  }

  async function toggleActive(acc: AdminPaymentMethod) {
    setTogglingId(acc.dbId);
    try {
      await setPaymentMethodActive(acc.dbId, !acc.isActive);
      await loadAccounts();
    } catch (err) {
      setAccountsError(err instanceof Error ? err.message : "Couldn't update that account.");
    } finally {
      setTogglingId(null);
    }
  }

  async function handleDelete(acc: AdminPaymentMethod) {
    if (confirmingDeleteId !== acc.dbId) {
      setConfirmingDeleteId(acc.dbId);
      return;
    }
    setDeleting(true);
    try {
      await deletePaymentMethod(acc.dbId);
      await loadAccounts();
      setConfirmingDeleteId(null);
    } catch (err) {
      setAccountsError(
        err instanceof PaymentMethodInUseError || err instanceof Error
          ? err.message
          : "Couldn't delete that account."
      );
      setConfirmingDeleteId(null);
    } finally {
      setDeleting(false);
    }
  }

  async function handleQueueAction(orderDbId: string, action: () => Promise<void>) {
    setActingOnOrder(orderDbId);
    setQueueActionError(null);
    try {
      await action();
      if (selectedOrderId === orderDbId) setSelectedOrderId(null);
    } catch (err) {
      setQueueActionError(err instanceof Error ? err.message : "Something went wrong.");
    } finally {
      setActingOnOrder(null);
    }
  }

  return (
    <div>
      <PageHeader
        title="Payments"
        subtitle="Manage your receiving accounts and verify incoming payments"
      />

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
        <StatCard
          label="Pending Verification"
          value={String(countByStatus(orders, "pending"))}
          icon={Clock3}
          tone="danger"
        />
        <StatCard
          label="Approved"
          value={String(countByStatus(orders, "approved"))}
          icon={CheckCircle2}
          tone="teal"
        />
        <StatCard
          label="Rejected"
          value={String(countByStatus(orders, "rejected"))}
          icon={XCircle}
          tone="danger"
        />
        <StatCard
          label="Verified Revenue"
          value={formatCurrency(totalRevenue(orders))}
          icon={Wallet}
          tone="gold"
        />
      </div>

      <div className="mt-5">
        <div className="mb-3 flex items-center justify-between">
          <h3 className="font-display text-[15px] font-semibold">Payment Accounts</h3>
          <Button size="sm" onClick={openCreate}>
            <Plus size={14} /> Add Account
          </Button>
        </div>

        {accountsError && (
          <div className="mb-4 flex items-center gap-2 rounded-xl bg-danger/10 px-4 py-3 text-sm text-danger">
            <AlertCircle size={16} /> {accountsError}
          </div>
        )}

        {accountsLoading ? (
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
            {Array.from({ length: 3 }).map((_, i) => (
              <Skeleton key={i} className="h-36 w-full" />
            ))}
          </div>
        ) : accounts.length === 0 ? (
          <EmptyState
            icon={Wallet}
            title="No payment accounts yet"
            description="Add a JazzCash, EasyPaisa, or bank account for customers to pay into."
            action={
              <Button size="sm" onClick={openCreate}>
                <Plus size={14} /> Add Account
              </Button>
            }
          />
        ) : (
          <div className="grid grid-cols-1 gap-4 sm:grid-cols-3">
            {accounts.map((acc) => (
              <div
                key={acc.dbId}
                className={cn("panel flex flex-col gap-3 p-4", !acc.isActive && "opacity-60")}
              >
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <span className={cn("h-2.5 w-2.5 rounded-full", acc.colorClass)} />
                    <p className="text-sm font-semibold">{acc.label}</p>
                  </div>
                  <Switch
                    checked={acc.isActive}
                    onChange={() => toggleActive(acc)}
                    label={acc.isActive ? "Disable account" : "Enable account"}
                    disabled={togglingId === acc.dbId}
                  />
                </div>
                <div className="rounded-xl bg-black/[0.03] px-3 py-2.5 dark:bg-white/[0.04]">
                  <p className="text-[11px] text-muted">{acc.accountTitle}</p>
                  <p className="tnum font-mono text-sm font-semibold">{acc.accountNumber}</p>
                </div>
                <div className="flex items-center gap-1.5">
                  <button
                    onClick={() => openEdit(acc)}
                    className="flex h-8 flex-1 items-center justify-center gap-1.5 rounded-lg border border-black/[0.08] text-xs font-medium text-muted hover:bg-black/5 dark:border-white/[0.08] dark:hover:bg-white/5"
                  >
                    <Pencil size={12} /> Edit
                  </button>
                  <button
                    onClick={() => handleDelete(acc)}
                    disabled={deleting && confirmingDeleteId === acc.dbId}
                    className={cn(
                      "flex h-8 flex-1 items-center justify-center gap-1.5 rounded-lg border text-xs font-medium disabled:opacity-50",
                      confirmingDeleteId === acc.dbId
                        ? "border-danger bg-danger/10 text-danger"
                        : "border-black/[0.08] text-muted hover:bg-black/5 dark:border-white/[0.08] dark:hover:bg-white/5"
                    )}
                  >
                    <Trash2 size={12} /> {confirmingDeleteId === acc.dbId ? "Confirm?" : "Delete"}
                  </button>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <div className="panel mt-5">
        <div className="border-b border-black/[0.06] px-5 py-4 dark:border-white/[0.06]">
          <h3 className="font-display text-[15px] font-semibold">Verification Queue</h3>
          <p className="text-xs text-muted">Orders waiting for you to confirm payment</p>
        </div>

        {ordersError && (
          <div className="mx-5 mt-4 flex items-center gap-2 rounded-xl bg-danger/10 px-4 py-3 text-sm text-danger">
            <AlertCircle size={16} className="shrink-0" /> {ordersError}
          </div>
        )}

        {ordersLoading ? (
          <div className="flex flex-col gap-2 p-4">
            {Array.from({ length: 3 }).map((_, i) => (
              <Skeleton key={i} className="h-16 w-full" />
            ))}
          </div>
        ) : ordersError ? null : pendingQueue.length === 0 ? (
          <EmptyState
            icon={CheckCircle2}
            title="All caught up"
            description="No payments waiting for verification."
          />
        ) : (
          <div className="flex flex-col divide-y divide-black/[0.05] dark:divide-white/[0.05]">
            {pendingQueue.map((o) => (
              <div
                key={o.dbId}
                className="flex flex-col gap-3 p-4 sm:flex-row sm:items-center sm:justify-between"
              >
                <div className="flex items-center gap-3">
                  <Avatar name={o.customerName} size="sm" />
                  <div className="min-w-0">
                    <p className="text-[13px] font-medium">{o.customerName}</p>
                    <div className="flex items-center gap-1.5 text-[11px] text-muted">
                      <NetworkBadge network={o.network as NetworkId} size="sm" className="!h-4 !w-8" />
                      {o.packageName} &middot; {o.referenceNumber ?? "—"}
                    </div>
                  </div>
                </div>
                <div className="flex items-center gap-3">
                  <p className="tnum text-sm font-semibold">{formatCurrency(o.amount)}</p>
                  <button
                    onClick={() => setSelectedOrderId(o.dbId)}
                    className="rounded-lg border border-black/[0.1] px-3 py-1.5 text-xs font-semibold text-muted dark:border-white/[0.1]"
                  >
                    Details
                  </button>
                  <button
                    disabled={actingOnOrder === o.dbId}
                    onClick={() => handleQueueAction(o.dbId, () => rejectOrder(o))}
                    className="flex h-8 w-8 items-center justify-center rounded-lg bg-danger/10 text-danger disabled:opacity-50"
                  >
                    <X size={14} />
                  </button>
                  <button
                    disabled={actingOnOrder === o.dbId}
                    onClick={() => handleQueueAction(o.dbId, () => approveOrder(o))}
                    className="flex h-8 w-8 items-center justify-center rounded-lg bg-success/12 text-success disabled:opacity-50"
                  >
                    <Check size={14} />
                  </button>
                </div>
              </div>
            ))}
          </div>
        )}
      </div>

      <Drawer
        open={!!selectedOrder}
        onClose={() => setSelectedOrderId(null)}
        title={selectedOrder?.id ?? ""}
        subtitle={selectedOrder?.customerName}
        footer={
          selectedOrder && (
            <div className="flex gap-2">
              <Button
                variant="secondary"
                fullWidth
                disabled={actingOnOrder === selectedOrder.dbId}
                className="!bg-danger/10 !text-danger"
                onClick={() => handleQueueAction(selectedOrder.dbId, () => rejectOrder(selectedOrder))}
              >
                <X size={15} /> Reject
              </Button>
              <Button
                fullWidth
                disabled={actingOnOrder === selectedOrder.dbId}
                onClick={() => handleQueueAction(selectedOrder.dbId, () => approveOrder(selectedOrder))}
              >
                <Check size={15} /> Approve
              </Button>
            </div>
          )
        }
      >
        {selectedOrder && (
          <div className="flex flex-col gap-5">
            {queueActionError && (
              <div className="flex items-start gap-2 rounded-xl bg-danger/10 px-3.5 py-3 text-sm text-danger">
                <AlertCircle size={16} className="mt-0.5 shrink-0" /> {queueActionError}
              </div>
            )}
            <div className="panel flex items-center gap-3 !shadow-none p-3.5">
              <NetworkBadge network={selectedOrder.network as NetworkId} size="md" />
              <div className="min-w-0 flex-1">
                <p className="truncate text-sm font-semibold">{selectedOrder.packageName}</p>
              </div>
              <p className="tnum text-sm font-semibold">{formatCurrency(selectedOrder.amount)}</p>
            </div>
            <div className="flex flex-col gap-3 rounded-2xl border border-black/[0.06] p-4 dark:border-white/[0.06]">
              <div className="flex items-center justify-between text-sm">
                <span className="flex items-center gap-2 text-xs text-muted">
                  <Hash size={14} /> Transaction ID
                </span>
                <span className="tnum font-mono font-medium">{selectedOrder.referenceNumber ?? "—"}</span>
              </div>
              <div className="flex items-center justify-between text-sm">
                <span className="flex items-center gap-2 text-xs text-muted">
                  <CreditCard size={14} /> Payment Method
                </span>
                <span className="font-medium">{selectedOrder.paymentMethodLabel ?? "—"}</span>
              </div>
              <div className="flex items-center justify-between text-sm">
                <span className="flex items-center gap-2 text-xs text-muted">
                  <CalendarClock size={14} /> Date & Time
                </span>
                <span className="font-medium">{formatDateTime(selectedOrder.createdAt)}</span>
              </div>
            </div>
            <div>
              <p className="mb-2 text-xs font-semibold uppercase tracking-wide text-muted">Screenshot</p>
              {screenshotUrl ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={screenshotUrl}
                  alt="Payment screenshot"
                  className="w-full rounded-2xl border border-black/[0.06] object-cover dark:border-white/[0.06]"
                />
              ) : (
                <div className="flex h-40 flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-black/[0.12] text-muted dark:border-white/[0.12]">
                  <ImageOff size={22} />
                  <p className="text-xs">
                    {selectedOrder.screenshotPath ? "Loading screenshot…" : "No screenshot on this order"}
                  </p>
                </div>
              )}
            </div>
          </div>
        )}
      </Drawer>

      <Drawer
        open={creating || !!editingAccount}
        onClose={closeDrawer}
        title={creating ? "Add Payment Account" : `Edit ${editingAccount?.label ?? ""}`}
        footer={
          <Button fullWidth onClick={handleSave} disabled={saving}>
            {saving ? "Saving…" : creating ? "Add Account" : "Save Changes"}
          </Button>
        }
      >
        <div className="flex flex-col gap-4">
          <SelectField
            label="Account Type"
            value={form.methodType}
            options={METHOD_TYPE_OPTIONS}
            onChange={(e) => {
              const methodType = e.target.value as PaymentMethodTypeDb;
              setForm((f) => ({
                ...f,
                methodType,
                // Only auto-fill the label while creating, and only if it
                // hasn't been hand-edited yet — switching type shouldn't
                // clobber a custom label like "JazzCash — Backup".
                label: creating && !f.label.trim() ? METHOD_LABEL_DEFAULT[methodType] : f.label,
              }));
            }}
          />
          <TextField
            label="Label"
            placeholder="e.g. JazzCash"
            value={form.label}
            onChange={(e) => setForm((f) => ({ ...f, label: e.target.value }))}
          />
          <TextField
            label="Account Title"
            placeholder="e.g. SharedNet Services"
            value={form.accountTitle}
            onChange={(e) => setForm((f) => ({ ...f, accountTitle: e.target.value }))}
          />
          <TextField
            label="Account Number"
            placeholder="e.g. 0300 1234567"
            value={form.accountNumber}
            onChange={(e) => setForm((f) => ({ ...f, accountNumber: e.target.value }))}
          />
          {formError && (
            <div className="flex items-start gap-2 rounded-xl bg-danger/10 px-3.5 py-3 text-sm text-danger">
              <AlertCircle size={16} className="mt-0.5 shrink-0" /> {formError}
            </div>
          )}
        </div>
      </Drawer>
    </div>
  );
}
