import Link from "next/link";
import { redirect } from "next/navigation";
import { eq } from "drizzle-orm";
import { format } from "date-fns";
import { Search, ShoppingBag } from "lucide-react";
import { db } from "@db/client";
import { users } from "@db/schema";
import { getCurrentRole } from "@/lib/auth";
import { formatPrice } from "@/lib/format";
import { searchAdminMerchOrders, type MerchOrder } from "@db/queries/merch";
import { PageHeader, TableShell, StatusPill, EmptyState, buttonClass, type Tone } from "@/components/ui";
import AdminDbError, { dbErrorMessage } from "@/components/admin-db-error";

export const metadata = { title: "Merch orders · Admin" };

// No "refunded": merch has no refund flow (sales are final).
const STATUSES: MerchOrder["status"][] = ["paid", "pending", "cancelled"];
const METHODS: MerchOrder["fulfillment"][] = ["pickup", "delivery"];

const STATUS_TONE: Record<MerchOrder["status"], Tone> = {
  paid: "ok",
  pending: "warn",
  cancelled: "muted",
  refunded: "danger",
};

const FULFILLMENT_LABEL: Record<MerchOrder["fulfillmentStatus"], string> = {
  processing: "Processing",
  ready: "Ready for pickup",
  shipped: "Shipped",
  delivered: "Delivered",
  collected: "Collected",
};

const METHOD_LABELS: Record<MerchOrder["paymentMethod"], string> = { card: "Card", mpesa: "M-Pesa" };

// Admin-only, read-only: every organizer's merch orders, for "I paid but
// never got my order" lookups. Fulfilment is the organizer's job, so there
// are no write actions here.
export default async function AdminMerchOrdersPage({
  searchParams,
}: {
  searchParams: Promise<{ q?: string; status?: string; fulfillment?: string; organizer?: string }>;
}) {
  const { isAdmin } = await getCurrentRole();
  if (!isAdmin) redirect("/dashboard");

  const sp = await searchParams;
  const q = sp.q?.trim() || undefined;
  const status = STATUSES.includes(sp.status as MerchOrder["status"]) ? (sp.status as MerchOrder["status"]) : undefined;
  const fulfillment = METHODS.includes(sp.fulfillment as MerchOrder["fulfillment"])
    ? (sp.fulfillment as MerchOrder["fulfillment"])
    : undefined;
  const organizerId = sp.organizer || undefined;

  const [loaded, organizer] = await Promise.all([
    searchAdminMerchOrders({ q, status, fulfillment, organizerId, limit: 100 })
      .then((rows) => ({ rows, error: null as string | null }))
      .catch((err) => {
        console.error("[admin/merch-orders] query failed:", err);
        return { rows: [] as Awaited<ReturnType<typeof searchAdminMerchOrders>>, error: dbErrorMessage(err) };
      }),
    organizerId
      ? db.select({ name: users.name }).from(users).where(eq(users.id, organizerId)).limit(1).then((r) => r[0]).catch(() => undefined)
      : undefined,
  ]);
  const { rows, error: loadError } = loaded;

  return (
    <div className="space-y-6">
      <PageHeader
        icon={ShoppingBag}
        title="Merch orders"
        description="Every organizer's merch orders. Search by buyer, order code or M-Pesa receipt to check a payment or see where an order is."
      />

      {loadError && <AdminDbError what="merch orders" error={loadError} />}

      <form className="flex flex-wrap items-end gap-2" action="/admin/merch-orders">
        <label className="min-w-[16rem] flex-1">
          <span className="mb-1 block text-xs text-be-muted">Buyer name, email, phone, order code, M-Pesa receipt or shop</span>
          <input name="q" defaultValue={q} placeholder="e.g. 0712 345 678 or J37J77" className="be-input w-full" />
        </label>
        <label>
          <span className="mb-1 block text-xs text-be-muted">Status</span>
          <select name="status" defaultValue={status ?? ""} className="be-input">
            <option value="">Any</option>
            {STATUSES.map((s) => (
              <option key={s} value={s}>
                {s}
              </option>
            ))}
          </select>
        </label>
        <label>
          <span className="mb-1 block text-xs text-be-muted">Delivery</span>
          <select name="fulfillment" defaultValue={fulfillment ?? ""} className="be-input">
            <option value="">Any</option>
            {METHODS.map((m) => (
              <option key={m} value={m}>
                {m}
              </option>
            ))}
          </select>
        </label>
        {organizerId && <input type="hidden" name="organizer" value={organizerId} />}
        <button type="submit" className={buttonClass("primary")}>
          <Search className="h-4 w-4" /> Search
        </button>
      </form>

      {organizerId && (
        <p className="text-sm text-be-muted">
          Showing merch orders for <strong className="text-be-text">{organizer?.name || "this organizer"}</strong>.{" "}
          <Link href="/admin/merch-orders" className="text-brand-green-h hover:underline">
            Show all organizers
          </Link>
        </p>
      )}

      {rows.length === 0 ? (
        <EmptyState
          icon={ShoppingBag}
          title={q || status || fulfillment ? "No matching orders" : "No merch orders yet"}
          body={q ? "Try the buyer's phone number, email, order code or M-Pesa receipt." : "Merch orders appear here as buyers check out."}
        />
      ) : (
        <>
          <TableShell>
            <thead>
              <tr>
                <th>Date</th>
                <th>Code</th>
                <th>Buyer</th>
                <th>Shop</th>
                <th>Items</th>
                <th>Payment</th>
                <th className="text-right">Amount</th>
                <th>Status</th>
                <th>Fulfilment</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((o) => (
                <tr key={o.id} className="align-top">
                  <td className="whitespace-nowrap text-be-muted">{format(o.createdAt, "PP p")}</td>
                  <td className="font-mono font-medium text-be-text">{o.pickupCode}</td>
                  <td>
                    <span className="font-medium text-be-text">{o.buyerName}</span>
                    <span className="block text-xs text-be-muted">
                      {o.buyerEmail} · {o.buyerPhone}
                    </span>
                  </td>
                  <td>
                    <span className="text-be-text">{o.shopName}</span>
                    <Link
                      href={`/admin/merch-orders?organizer=${o.organizerId}`}
                      className="block text-xs text-be-muted hover:underline"
                    >
                      {o.organizerName || "Unnamed organizer"}
                    </Link>
                  </td>
                  <td className="text-be-text">
                    {o.items.map((i) => (
                      <div key={i.id}>
                        {i.quantity} × {i.productName} <span className="text-be-muted">({i.variantLabel})</span>
                      </div>
                    ))}
                  </td>
                  <td className="text-be-text">
                    {METHOD_LABELS[o.paymentMethod]}
                    {o.mpesaReceipt && <span className="block font-mono text-xs text-be-muted">{o.mpesaReceipt}</span>}
                  </td>
                  <td className="whitespace-nowrap text-right tabular-nums text-be-text">
                    {formatPrice(o.totalCents, o.currency)}
                    {o.deliveryFeeCents > 0 && (
                      <span className="block text-xs text-be-muted">
                        incl. {formatPrice(o.deliveryFeeCents, o.currency)} delivery
                      </span>
                    )}
                  </td>
                  <td>
                    <StatusPill tone={STATUS_TONE[o.status]}>{o.status}</StatusPill>
                  </td>
                  <td className="text-be-text">
                    {o.status === "paid" ? (
                      <>
                        {o.fulfillment === "pickup" ? "Pickup" : "Delivery"}
                        <span className="block text-xs text-be-muted">{FULFILLMENT_LABEL[o.fulfillmentStatus]}</span>
                        {o.fulfillment === "delivery" && (
                          <span className="block max-w-[14rem] text-xs text-be-muted">
                            {o.deliveryAddress}, {o.deliveryCity}
                          </span>
                        )}
                        {o.trackingNote && <span className="block text-xs text-be-muted">{o.trackingNote}</span>}
                      </>
                    ) : (
                      <span className="text-be-muted">—</span>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </TableShell>
          {rows.length === 100 && (
            <p className="text-xs text-be-muted">Showing the 100 most recent matches. Search to narrow it down.</p>
          )}
        </>
      )}
    </div>
  );
}
