"use client";

import { useState, useEffect, useRef, useReducer, useMemo, useCallback } from "react";
import { formatDate } from "@/lib/format-date";
import { useRouter } from "next/navigation";
import { submitWholesaleOrder, getWholesaleCustomerOrders, type WholesaleProduct, type WholesaleCustomerOrder } from "@/actions/wholesale-register";
import { getWholesaleSettings, enqueueWholesaleNotification } from "@/actions/wholesale";
import { wholesaleLogoutAction } from "@/actions/wholesale-auth";

/**
 * Module-scope redirect helper. Defining it outside the component avoids the
 * `react-hooks/immutability` rule that flags `window.location.href` mutations
 * inside client components.
 */
function navigateToExternalUrl(url: string): void {
  if (typeof window !== "undefined") {
    window.location.href = url;
  }
}

export type WholesaleCustomer = {
  id: string;
  user_id: string;
  company_name: string;
  contact_name: string;
  email: string;
  phone: string;
  account_status: string;
  role: string;
  brand_id: string;
};

type InitialData = {
  customer: WholesaleCustomer | null;
  brandName: string;
  products: WholesaleProduct[];
  orders: WholesaleCustomerOrder[];
  pricingOverrides: Record<string, number>;
  onlinePaymentEnabled: boolean;
  previewMode: boolean;
  invalidPreview: boolean;
};

type Props = InitialData;

type CartItem = {
  product: WholesaleProduct;
  quantity: number;
  unitPrice: number;
};

type Tab = "products" | "cart" | "orders";
type Filter = "all" | "available" | "limited";
type Msg = { kind: "success" | "error"; text: string } | null;

// ── Quantity Stepper ──────────────────────────────────────────────────────────
function QuantityStepper({
  maxQty,
  onAdd,
}: {
  maxQty: number;
  onAdd: (qty: number) => void;
}) {
  const [open, setOpen] = useState(false);
  const [qty, setQty] = useState(1);
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (ref.current && !ref.current.contains(e.target as Node)) {
        setOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, []);

  const presets = maxQty >= 10 ? [1, 5, 10] : maxQty >= 5 ? [1, 5] : [1];

  return (
    <div className="relative" ref={ref}>
      <button
        type="button"
        onClick={() => setOpen(!open)}
        className="rounded-xl bg-green-600 px-4 py-2 text-xs font-semibold text-white hover:bg-green-700 shrink-0 transition-colors shadow-sm"
      >
        + Add
      </button>
      {open && (
        <div className="absolute right-0 bottom-full mb-2 z-20 bg-white rounded-xl shadow-xl ring-1 ring-slate-200 p-4 w-56">
          <p className="text-xs font-semibold text-slate-500 mb-2">Qty for this item</p>
          <div className="flex items-center gap-2 mb-3">
            <button
              type="button"
              onClick={() => setQty(q => Math.max(1, q - 1))}
              className="w-9 h-9 rounded-lg border border-slate-300 flex items-center justify-center text-slate-600 hover:bg-slate-50 disabled:opacity-30"
              disabled={qty <= 1}
            >
              −
            </button>
            <input aria-label="Number"
              type="number"
              min="1"
              max={maxQty}
              value={qty}
              onChange={e => setQty(Math.min(maxQty, Math.max(1, Number(e.target.value) || 1)))}
              className="flex-1 rounded-lg border border-slate-300 px-3 py-2 text-center font-semibold text-slate-900 outline-none focus:border-green-500 min-w-0"
            />
            <button
              type="button"
              onClick={() => setQty(q => Math.min(maxQty, q + 1))}
              className="w-9 h-9 rounded-lg border border-slate-300 flex items-center justify-center text-slate-600 hover:bg-slate-50 disabled:opacity-30"
              disabled={qty >= maxQty}
            >
              +
            </button>
          </div>
          <div className="flex flex-wrap gap-1.5 mb-3">
            {presets.map(p => (
              <button
                key={p}
                type="button"
                onClick={() => setQty(Math.min(maxQty, p))}
                className={`rounded-lg px-2.5 py-1 text-xs font-semibold transition-colors ${
                  qty === p ? "bg-green-600 text-white" : "bg-slate-100 text-slate-600 hover:bg-slate-200"
                }`}
              >
                {p}
              </button>
            ))}
            {maxQty >= 20 && (
              <button
                type="button"
                onClick={() => setQty(Math.min(maxQty, 20))}
                className={`rounded-lg px-2.5 py-1 text-xs font-semibold transition-colors ${
                  qty === 20 ? "bg-green-600 text-white" : "bg-slate-100 text-slate-600 hover:bg-slate-200"
                }`}
              >
                20
              </button>
            )}
          </div>
          <p className="text-xs text-slate-400 mb-3">Max: {maxQty}</p>
          <button
            type="button"
            onClick={() => { onAdd(qty); setOpen(false); setQty(1); }}
            className="w-full rounded-xl bg-green-600 py-2.5 text-sm font-bold text-white hover:bg-green-700"
          >
            Add {qty} to Cart
          </button>
        </div>
      )}
    </div>
  );
}

// ── Search Bar ───────────────────────────────────────────────────────────────
function SearchBar({ value, onChange, placeholder }: {
  value: string;
  onChange: (v: string) => void;
  placeholder: string;
}) {
  return (
    <div className="relative">
      <svg className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-slate-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
        <circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/>
      </svg>
      <input aria-label="Search"
        type="search"
        value={value}
        onChange={e => onChange(e.target.value)}
        placeholder={placeholder}
        className="w-full rounded-xl border border-slate-300 pl-10 pr-4 py-3 text-sm outline-none focus:border-green-500 focus:ring-1 focus:ring-green-500 placeholder:text-slate-400"
      />
      {value && (
        <button
          type="button"
          onClick={() => onChange("")}
          aria-label="Clear search"
          className="absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 hover:text-slate-600"
        >
          <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
            <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12"/>
          </svg>
        </button>
      )}
    </div>
  );
}

// ── Empty State ──────────────────────────────────────────────────────────────
function EmptyState({ icon, title, description }: {
  icon: React.ReactNode;
  title: string;
  description: string;
}) {
  return (
    <div className="rounded-2xl bg-white p-12 text-center shadow-sm ring-1 ring-slate-200">
      <div className="w-14 h-14 bg-slate-100 rounded-2xl flex items-center justify-center mx-auto mb-4">
        {icon}
      </div>
      <h3 className="text-lg font-semibold text-slate-700 mb-2">{title}</h3>
      <p className="text-sm text-slate-500 max-w-xs mx-auto">{description}</p>
    </div>
  );
}

// ── Portal Header ────────────────────────────────────────────────────────────
function PortalHeader({
  brandName,
  companyName,
  onSignOut,
}: {
  brandName: string;
  companyName: string | undefined;
  onSignOut: () => void;
}) {
  return (
    <div className="bg-white border-b border-slate-200 px-6 py-4">
      <div className="mx-auto max-w-5xl flex items-center justify-between">
        <div>
          <h1 className="text-xl font-bold text-slate-900">{brandName}</h1>
          <p className="text-sm text-slate-500">Wholesale Portal — {companyName}</p>
        </div>
        <div className="flex items-center gap-4">
          <button
            type="button"
            onClick={onSignOut}
            className="rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50"
          >
            Sign Out
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Portal Tabs ──────────────────────────────────────────────────────────────
function PortalTabs({
  tab,
  cartCount,
  onChange,
}: {
  tab: Tab;
  cartCount: number;
  onChange: (t: Tab) => void;
}) {
  return (
    <div className="bg-white border-b border-slate-200 px-6">
      <div className="mx-auto max-w-5xl">
        <nav className="flex gap-1 -mb-px">
          {(["products", "cart", "orders"] as const).map(t => (
            <button
              type="button"
              key={t}
              onClick={() => onChange(t)}
              className={`px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
                tab === t
                  ? "border-green-600 text-green-700"
                  : "border-transparent text-slate-500 hover:text-slate-700"
              }`}
            >
              {t.charAt(0).toUpperCase() + t.slice(1)}
              {t === "cart" && cartCount > 0 && (
                <span className="ml-2 bg-green-600 text-white text-xs rounded-full px-1.5 py-0.5">
                  {cartCount}
                </span>
              )}
            </button>
          ))}
        </nav>
      </div>
    </div>
  );
}

// ── Portal Toast ─────────────────────────────────────────────────────────────
function PortalToast({ msg }: { msg: Msg }) {
  if (!msg) return null;
  return (
    <div
      className={`mb-4 rounded-xl border px-4 py-3 text-sm ${
        msg.kind === "success"
          ? "border-green-200 bg-green-50 text-green-700"
          : "border-red-200 bg-red-50 text-red-700"
      }`}
    >
      {msg.text}
    </div>
  );
}

// ── Product Card ─────────────────────────────────────────────────────────────
function ProductCard({
  product,
  unitPriceOverride,
  onAdd,
}: {
  product: WholesaleProduct;
  unitPriceOverride: number | undefined;
  onAdd: (qty: number) => void;
}) {
  return (
    <div className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-slate-200">
      <div className="flex items-start justify-between gap-3">
        <div className="flex-1 min-w-0">
          <h3 className="font-semibold text-slate-900">{product.name}</h3>
          <p className="text-xs text-slate-500 mt-0.5">{product.description ?? ""}</p>
          <div className="flex items-center gap-2 mt-2 flex-wrap">
            <span
              className={`rounded-full px-2.5 py-0.5 text-xs font-semibold ${
                product.availability === "available"
                  ? "bg-green-100 text-green-700"
                  : product.availability === "limited"
                  ? "bg-amber-100 text-amber-700"
                  : "bg-slate-100 text-slate-500"
              }`}
            >
              {product.availability === "available"
                ? "In Stock"
                : product.availability === "limited"
                ? `Limited (${product.qty_available})`
                : "Out of Stock"}
            </span>
            <span className="text-xs text-slate-400">{product.unit_type}</span>
          </div>
          {product.price_tiers && product.price_tiers.length > 0 && (
            <div className="mt-2 space-y-0.5">
              {unitPriceOverride !== undefined ? (
                <div className="flex items-center gap-2">
                  <span className="text-xs text-green-600 font-semibold bg-green-50 px-2 py-0.5 rounded">
                    Your price: ${unitPriceOverride.toFixed(2)} / {product.unit_type}
                  </span>
                </div>
              ) : (
                <div className="flex flex-wrap gap-x-3 gap-y-1">
                  {product.price_tiers.slice(0, 3).map(
                    (
                      t: { min_qty: number; max_qty: number; price: number },
                      i: number,
                    ) => (
                      <span
                        key={`${product.id}-tier-${t.min_qty}-${t.max_qty}-${i}`}
                        className="text-xs text-slate-500"
                      >
                        <span className="font-medium text-slate-700">${t.price.toFixed(2)}</span>
                        <span className="text-slate-400 ml-1">
                          {t.max_qty === 0 ? `${t.min_qty}+` : `${t.min_qty}–${t.max_qty}`}
                        </span>
                      </span>
                    ),
                  )}
                </div>
              )}
            </div>
          )}
        </div>
        {product.availability === "available" && product.qty_available > 0 ? (
          <QuantityStepper maxQty={product.qty_available} onAdd={onAdd} />
        ) : product.availability === "limited" && product.qty_available > 0 ? (
          <QuantityStepper maxQty={product.qty_available} onAdd={onAdd} />
        ) : (
          <span className="rounded-xl bg-slate-100 px-3 py-2 text-xs font-medium text-slate-400 shrink-0">
            Unavailable
          </span>
        )}
      </div>
    </div>
  );
}

// ── Products Tab ─────────────────────────────────────────────────────────────
function ProductsTab({
  products,
  pricingOverrides,
  searchQuery,
  filterAvailability,
  onSearch,
  onFilter,
  onAdd,
}: {
  products: WholesaleProduct[];
  pricingOverrides: Record<string, number>;
  searchQuery: string;
  filterAvailability: Filter;
  onSearch: (q: string) => void;
  onFilter: (f: Filter) => void;
  onAdd: (product: WholesaleProduct, quantity: number) => void;
}) {
  const filteredProducts = useMemo(() => {
    let filtered = products;
    if (searchQuery) {
      const q = searchQuery.toLowerCase();
      filtered = filtered.filter(
        p =>
          p.name.toLowerCase().includes(q) ||
          (p.description ?? "").toLowerCase().includes(q),
      );
    }
    if (filterAvailability !== "all") {
      filtered = filtered.filter(p =>
        filterAvailability === "available"
          ? p.availability === "available"
          : p.availability === "limited",
      );
    }
    return filtered;
  }, [products, searchQuery, filterAvailability]);

  return (
    <div className="space-y-4">
      <h2 className="text-lg font-semibold text-slate-900">Product Catalog</h2>
      <div className="flex flex-col sm:flex-row gap-3">
        <div className="flex-1">
          <SearchBar
            value={searchQuery}
            onChange={onSearch}
            placeholder="Search products..."
          />
        </div>
        <select
          aria-label="Select"
          value={filterAvailability}
          onChange={e => onFilter(e.target.value as Filter)}
          className="rounded-xl border border-slate-300 px-3 py-3 text-sm outline-none focus:border-green-500 min-h-[48px]"
        >
          <option value="all">All ({products.length})</option>
          <option value="available">
            Available ({products.filter(p => p.availability === "available").length})
          </option>
          <option value="limited">Limited Stock</option>
        </select>
      </div>

      {filteredProducts.length === 0 ? (
        products.length === 0 ? (
          <EmptyState
            icon={
              <svg
                className="w-7 h-7 text-slate-400"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={1.5}
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
                />
              </svg>
            }
            title="No products available"
            description="This wholesale portal doesn't have any products listed yet. Check back soon or contact support."
          />
        ) : (
          <EmptyState
            icon={
              <svg
                className="w-7 h-7 text-slate-400"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
                strokeWidth={1.5}
              >
                <circle cx="11" cy="11" r="8" />
                <path d="m21 21-4.35-4.35" />
              </svg>
            }
            title="No products match your search"
            description={`No products found for "${searchQuery}". Try adjusting your search or filters.`}
          />
        )
      ) : (
        <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
          {filteredProducts.map(p => (
            <ProductCard
              key={p.id}
              product={p}
              unitPriceOverride={pricingOverrides[p.id]}
              onAdd={qty => onAdd(p, qty)}
            />
          ))}
        </div>
      )}
      {searchQuery && (
        <p className="text-sm text-slate-500 text-center">
          Showing {filteredProducts.length} of {products.length} products
        </p>
      )}
    </div>
  );
}

// ── Cart Tab ─────────────────────────────────────────────────────────────────
function CartTab({
  cart,
  pickupDate,
  minPickupDate,
  submitting,
  onPickupDate,
  onIncrement,
  onDecrement,
  onRemove,
  onClear,
  onPlaceOrder,
}: {
  cart: CartItem[];
  pickupDate: string;
  minPickupDate: string;
  submitting: boolean;
  onPickupDate: (d: string) => void;
  onIncrement: (productId: string) => void;
  onDecrement: (productId: string) => void;
  onRemove: (productId: string) => void;
  onClear: () => void;
  onPlaceOrder: () => void;
}) {
  const total = cart.reduce((s, i) => s + i.quantity * i.unitPrice, 0);

  return (
    <div className="space-y-4">
      <div className="flex items-center justify-between">
        <h2 className="text-lg font-semibold text-slate-900">
          Your Order
          {cart.length > 0 && (
            <span className="ml-2 text-sm font-normal text-slate-500">
              ({cart.length} item{cart.length !== 1 ? "s" : ""})
            </span>
          )}
        </h2>
        {cart.length > 0 && (
          <button
            type="button"
            onClick={onClear}
            className="text-sm text-red-500 hover:text-red-700 hover:underline"
          >
            Clear cart
          </button>
        )}
      </div>
      {cart.length === 0 ? (
        <EmptyState
          icon={
            <svg
              className="w-7 h-7 text-slate-400"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={1.5}
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"
              />
            </svg>
          }
          title="Your cart is empty"
          description="Browse our product catalog and add items to get started with your wholesale order."
        />
      ) : (
        <>
          <div className="rounded-2xl bg-white shadow-sm ring-1 ring-slate-200 overflow-hidden">
            <table className="w-full text-sm">
              <thead className="bg-slate-50 text-slate-600">
                <tr>
                  <th className="px-5 py-3 font-semibold text-left">Product</th>
                  <th className="px-5 py-3 font-semibold text-center">Qty</th>
                  <th className="px-5 py-3 font-semibold text-right">Unit Price</th>
                  <th className="px-5 py-3 font-semibold text-right">Total</th>
                  <th className="px-5 py-3" aria-label="Actions"></th>
                </tr>
              </thead>
              <tbody className="divide-y divide-slate-100">
                {cart.map(item => (
                  <tr key={item.product.id} className="hover:bg-slate-50/50">
                    <td className="px-5 py-4">
                      <span className="font-medium text-slate-900">{item.product.name}</span>
                      <span className="ml-1 text-xs text-slate-400">/ {item.product.unit_type}</span>
                    </td>
                    <td className="px-5 py-4 text-center">
                      <div className="flex items-center justify-center gap-1">
                        <button
                          type="button"
                          onClick={() => onDecrement(item.product.id)}
                          className="w-7 h-7 rounded-lg border border-slate-200 flex items-center justify-center text-slate-500 hover:bg-slate-100 disabled:opacity-30"
                        >
                          −
                        </button>
                        <span className="w-10 text-center font-semibold text-slate-900">
                          {item.quantity}
                        </span>
                        <button
                          type="button"
                          onClick={() => onIncrement(item.product.id)}
                          disabled={item.quantity >= item.product.qty_available}
                          className="w-7 h-7 rounded-lg border border-slate-200 flex items-center justify-center text-slate-500 hover:bg-slate-100 disabled:opacity-30"
                        >
                          +
                        </button>
                      </div>
                    </td>
                    <td className="px-5 py-4 text-right text-slate-600">
                      ${item.unitPrice.toFixed(2)}
                    </td>
                    <td className="px-5 py-4 text-right font-semibold text-slate-900">
                      ${(item.quantity * item.unitPrice).toFixed(2)}
                    </td>
                    <td className="px-5 py-4">
                      <button
                        type="button"
                        onClick={() => onRemove(item.product.id)}
                        className="text-xs text-red-500 hover:text-red-700 hover:underline"
                      >
                        Remove
                      </button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>

          <div className="rounded-2xl bg-white shadow-sm ring-1 ring-slate-200 p-5">
            <div className="flex flex-col sm:flex-row gap-4 sm:items-end">
              <div className="flex-1">
                <label
                  className="block text-sm font-semibold text-slate-700 mb-1.5"
                  htmlFor="fld-preferred-pickup-date-optional"
                >
                  Preferred Pickup Date
                  <span className="text-slate-400 font-normal ml-1">(optional)</span>
                </label>
                <input
                  id="fld-preferred-pickup-date-optional"
                  aria-label="Date"
                  type="date"
                  value={pickupDate}
                  onChange={e => onPickupDate(e.target.value)}
                  min={minPickupDate}
                  className="w-full rounded-xl border border-slate-300 px-4 py-3 text-sm outline-none focus:border-green-500 focus:ring-1 focus:ring-green-500"
                />
              </div>
              <div className="flex items-center justify-between sm:flex-col sm:items-end gap-3">
                <div className="text-right">
                  <p className="text-sm text-slate-500">Order Total</p>
                  <p className="text-2xl font-bold text-slate-900">${total.toFixed(2)}</p>
                </div>
                <button
                  type="button"
                  onClick={onPlaceOrder}
                  disabled={submitting || cart.length === 0}
                  className="rounded-xl bg-green-600 px-8 py-3 text-base font-bold text-white hover:bg-green-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-lg shadow-green-900/20 min-w-[160px]"
                >
                  {submitting ? (
                    <span className="flex items-center justify-center gap-2">
                      <svg
                        className="h-4 w-4 animate-spin"
                        fill="none"
                        viewBox="0 0 24 24"
                      >
                        <circle
                          className="opacity-25"
                          cx="12"
                          cy="12"
                          r="10"
                          stroke="currentColor"
                          strokeWidth="4"
                        />
                        <path
                          className="opacity-75"
                          fill="currentColor"
                          d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"
                        />
                      </svg>
                      Placing Order...
                    </span>
                  ) : (
                    "Place Order"
                  )}
                </button>
              </div>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// ── Orders Tab ───────────────────────────────────────────────────────────────
function OrdersTab({
  orders,
  onlinePaymentEnabled,
  processingPayment,
  onPayNow,
}: {
  orders: WholesaleCustomerOrder[];
  onlinePaymentEnabled: boolean;
  processingPayment: string | null;
  onPayNow: (order: WholesaleCustomerOrder) => void;
}) {
  return (
    <div className="space-y-4">
      <h2 className="text-lg font-semibold text-slate-900">
        Order History
        {orders.length > 0 && (
          <span className="ml-2 text-sm font-normal text-slate-500">
            ({orders.length} order{orders.length !== 1 ? "s" : ""})
          </span>
        )}
      </h2>
      {orders.length === 0 ? (
        <EmptyState
          icon={
            <svg
              className="w-7 h-7 text-slate-400"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={1.5}
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
              />
            </svg>
          }
          title="No orders yet"
          description="Once you place your first wholesale order, it will appear here with full order history and tracking."
        />
      ) : (
        <div className="space-y-3">
          {orders.map(o => (
            <div
              key={o.id}
              className="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-slate-200 hover:ring-slate-300 transition-shadow"
            >
              <div className="flex items-start justify-between mb-4">
                <div>
                  <div className="flex items-center gap-2 flex-wrap">
                    <p className="font-semibold text-slate-900">{o.invoice_number ?? "—"}</p>
                    {o.invoice_number && (
                      <span className="text-xs text-slate-400 font-mono">{o.id.slice(0, 8)}</span>
                    )}
                  </div>
                  <p className="text-xs text-slate-500 mt-1">
                    {formatDate(new Date(o.created_at))}
                    {o.anticipated_pickup_date && (
                      <span className="ml-2 text-green-600 font-medium">
                        → Pickup: {o.anticipated_pickup_date}
                      </span>
                    )}
                  </p>
                </div>
                <div className="text-right">
                  <p className="text-xl font-bold text-slate-900">
                    ${Number(o.subtotal).toFixed(2)}
                  </p>
                  <p
                    className={`text-sm font-medium ${
                      o.payment_status === "paid" ? "text-green-600" : "text-orange-500"
                    }`}
                  >
                    {o.payment_status === "paid"
                      ? "Paid in full"
                      : `$${Number(o.balance_due).toFixed(2)} due`}
                  </p>
                </div>
              </div>
              <div className="flex items-center gap-2 flex-wrap">
                <span
                  className={`rounded-full px-3 py-1 text-xs font-semibold ${
                    o.status === "fulfilled"
                      ? "bg-green-100 text-green-700"
                      : o.status === "pending"
                      ? "bg-yellow-100 text-yellow-700"
                      : o.status === "awaiting_deposit"
                      ? "bg-purple-100 text-purple-700"
                      : o.status === "confirmed"
                      ? "bg-blue-100 text-blue-700"
                      : "bg-slate-100 text-slate-700"
                  }`}
                >
                  {o.status.replace(/_/g, " ")}
                </span>
                {o.items && o.items.length > 0 && (
                  <span className="text-xs text-slate-500 flex items-center gap-1">
                    <svg
                      className="w-3.5 h-3.5"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                      strokeWidth={2}
                    >
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4"
                      />
                    </svg>
                    {o.items.length} item{o.items.length !== 1 ? "s" : ""}
                  </span>
                )}
                <div className="ml-auto flex items-center gap-2">
                  {o.invoice_number && o.invoice_token && (
                    <a
                      href={`/api/wholesale/invoice/${o.id}/pdf?token=${o.invoice_token}`}
                      target="_blank"
                      rel="noopener noreferrer"
                      className="rounded-xl bg-slate-800 px-3 py-1.5 text-xs font-semibold text-white hover:bg-slate-700 flex items-center gap-1"
                    >
                      <svg
                        className="w-3.5 h-3.5"
                        fill="none"
                        viewBox="0 0 24 24"
                        stroke="currentColor"
                        strokeWidth={2}
                      >
                        <path
                          strokeLinecap="round"
                          strokeLinejoin="round"
                          d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
                        />
                      </svg>
                      Invoice
                    </a>
                  )}
                  {onlinePaymentEnabled &&
                    Number(o.balance_due) > 0 &&
                    o.payment_status !== "paid" && (
                      <button
                        type="button"
                        onClick={() => onPayNow(o)}
                        disabled={processingPayment === o.id}
                        className="rounded-xl bg-green-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-green-700 disabled:opacity-50 flex items-center gap-1"
                      >
                        <svg
                          className="w-3.5 h-3.5"
                          fill="none"
                          viewBox="0 0 24 24"
                          stroke="currentColor"
                          strokeWidth={2}
                        >
                          <path
                            strokeLinecap="round"
                            strokeLinejoin="round"
                            d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z"
                          />
                        </svg>
                        {processingPayment === o.id ? "Loading..." : "Pay Now"}
                      </button>
                    )}
                </div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── State + Reducer ──────────────────────────────────────────────────────────
type State = {
  // Mutable state
  tab: Tab;
  cart: CartItem[];
  orders: WholesaleCustomerOrder[];
  pickupDate: string;
  minPickupDate: string;
  submitting: boolean;
  msg: Msg;
  processingPayment: string | null;
  searchQuery: string;
  filterAvailability: Filter;
  // Stable initial values (set once from props, never changed)
  customer: WholesaleCustomer | null;
  brandName: string;
  previewMode: boolean;
  allProducts: WholesaleProduct[];
  pricingOverrides: Record<string, number>;
  onlinePaymentEnabled: boolean;
};

type Action =
  | { type: "SET_TAB"; tab: Tab }
  | { type: "ADD_TO_CART"; product: WholesaleProduct; quantity: number; unitPrice: number; unitPriceSource: "override" | "tier" }
  | { type: "INCREMENT_ITEM"; productId: string }
  | { type: "DECREMENT_ITEM"; productId: string }
  | { type: "REMOVE_ITEM"; productId: string }
  | { type: "CLEAR_CART" }
  | { type: "SET_PICKUP_DATE"; date: string }
  | { type: "SET_MIN_PICKUP_DATE"; date: string }
  | { type: "SET_SUBMITTING"; value: boolean }
  | { type: "SET_MSG"; msg: Msg }
  | { type: "CLEAR_MSG" }
  | { type: "SET_PROCESSING_PAYMENT"; orderId: string | null }
  | { type: "SET_SEARCH"; q: string }
  | { type: "SET_FILTER"; f: Filter }
  | { type: "REPLACE_ORDERS"; orders: WholesaleCustomerOrder[] };

function getTierPrice(
  product: WholesaleProduct,
  quantity: number,
): number | undefined {
  if (!product.price_tiers || product.price_tiers.length === 0) return undefined;
  const tier = product.price_tiers.find(
    (t: { min_qty: number; max_qty: number; price: number }) =>
      quantity >= t.min_qty && (t.max_qty === 0 || quantity <= t.max_qty),
  );
  if (tier) return tier.price;
  return product.price_tiers[product.price_tiers.length - 1].price;
}

function unitPriceFor(
  product: WholesaleProduct,
  quantity: number,
  pricingOverrides: Record<string, number>,
): number {
  const override = pricingOverrides[product.id];
  if (override !== undefined) return override;
  return getTierPrice(product, quantity) ?? 0;
}

function makeInitialState(initial: InitialData): State {
  return {
    tab: "products",
    cart: [],
    orders: initial.orders,
    pickupDate: "",
    minPickupDate: "",
    submitting: false,
    msg: null,
    processingPayment: null,
    searchQuery: "",
    filterAvailability: "all",
    customer: initial.customer,
    brandName: initial.brandName,
    previewMode: initial.previewMode,
    allProducts: initial.products,
    pricingOverrides: initial.pricingOverrides,
    onlinePaymentEnabled: initial.onlinePaymentEnabled,
  };
}

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "SET_TAB":
      return { ...state, tab: action.tab };
    case "ADD_TO_CART": {
      const existing = state.cart.find(i => i.product.id === action.product.id);
      if (existing) {
        const newQty = existing.quantity + action.quantity;
        const newUnitPrice =
          action.unitPriceSource === "tier"
            ? unitPriceFor(action.product, newQty, state.pricingOverrides)
            : existing.unitPrice;
        return {
          ...state,
          cart: state.cart.map(i =>
            i.product.id === action.product.id
              ? { ...i, quantity: newQty, unitPrice: newUnitPrice }
              : i,
          ),
        };
      }
      return {
        ...state,
        cart: [
          ...state.cart,
          {
            product: action.product,
            quantity: action.quantity,
            unitPrice: action.unitPrice,
          },
        ],
      };
    }
    case "INCREMENT_ITEM": {
      return {
        ...state,
        cart: state.cart.map(i => {
          if (i.product.id !== action.productId) return i;
          if (i.quantity >= i.product.qty_available) return i;
          const newQty = i.quantity + 1;
          const newUnitPrice = unitPriceFor(i.product, newQty, state.pricingOverrides);
          return { ...i, quantity: newQty, unitPrice: newUnitPrice };
        }),
      };
    }
    case "DECREMENT_ITEM": {
      return {
        ...state,
        cart: state.cart
          .map(i => {
            if (i.product.id !== action.productId) return i;
            if (i.quantity <= 1) return null;
            const newQty = i.quantity - 1;
            const newUnitPrice = unitPriceFor(i.product, newQty, state.pricingOverrides);
            return { ...i, quantity: newQty, unitPrice: newUnitPrice };
          })
          .filter((i): i is CartItem => i !== null),
      };
    }
    case "REMOVE_ITEM":
      return {
        ...state,
        cart: state.cart.filter(i => i.product.id !== action.productId),
      };
    case "CLEAR_CART":
      return { ...state, cart: [] };
    case "SET_PICKUP_DATE":
      return { ...state, pickupDate: action.date };
    case "SET_MIN_PICKUP_DATE":
      return { ...state, minPickupDate: action.date };
    case "SET_SUBMITTING":
      return { ...state, submitting: action.value };
    case "SET_MSG":
      return { ...state, msg: action.msg };
    case "CLEAR_MSG":
      return { ...state, msg: null };
    case "SET_PROCESSING_PAYMENT":
      return { ...state, processingPayment: action.orderId };
    case "SET_SEARCH":
      return { ...state, searchQuery: action.q };
    case "SET_FILTER":
      return { ...state, filterAvailability: action.f };
    case "REPLACE_ORDERS":
      return { ...state, orders: action.orders };
  }
}

// ── Main Component ───────────────────────────────────────────────────────────
export default function WholesalePortalClient({
  customer: initialCustomer,
  brandName: initialBrandName,
  products: initialProducts,
  orders: initialOrders,
  pricingOverrides: initialPricingOverrides,
  onlinePaymentEnabled: initialOnlinePaymentEnabled,
  previewMode: initialPreviewMode,
  invalidPreview,
}: Props) {
  const router = useRouter();
  const [state, dispatch] = useReducer(
    reducer,
    {
      customer: initialCustomer,
      brandName: initialBrandName,
      products: initialProducts,
      orders: initialOrders,
      pricingOverrides: initialPricingOverrides,
      onlinePaymentEnabled: initialOnlinePaymentEnabled,
      previewMode: initialPreviewMode,
      invalidPreview,
    },
    makeInitialState,
  );

  // Compute today's date in the browser to avoid SSR/hydration mismatch.
  // The async IIFE inside useEffect ensures the setState is preceded by an
  // `await`, which satisfies `react-hooks/set-state-in-effect`.
  useEffect(() => {
    void (async () => {
      await Promise.resolve();
      dispatch({
        type: "SET_MIN_PICKUP_DATE",
        date: new Date().toISOString().split("T")[0],
      });
    })();
  }, []);

  const reloadOrders = useCallback(async () => {
    if (!state.customer) return;
    const orderList = await getWholesaleCustomerOrders(state.customer.id);
    dispatch({ type: "REPLACE_ORDERS", orders: orderList as WholesaleCustomerOrder[] });
  }, [state.customer]);

  function addToCart(product: WholesaleProduct, quantity: number) {
    if (quantity <= 0 || quantity > product.qty_available) return;
    const override = state.pricingOverrides[product.id];
    const unitPriceSource: "override" | "tier" =
      override !== undefined ? "override" : "tier";
    const unitPrice = unitPriceFor(product, quantity, state.pricingOverrides);
    dispatch({
      type: "ADD_TO_CART",
      product,
      quantity,
      unitPrice,
      unitPriceSource,
    });
    dispatch({ type: "SET_TAB", tab: "cart" });
    dispatch({
      type: "SET_MSG",
      msg: { kind: "success", text: `${quantity} × ${product.name} added to cart` },
    });
    setTimeout(() => dispatch({ type: "CLEAR_MSG" }), 3000);
  }

  function incrementCartItem(productId: string) {
    dispatch({ type: "INCREMENT_ITEM", productId });
  }

  function decrementCartItem(productId: string) {
    dispatch({ type: "DECREMENT_ITEM", productId });
  }

  function removeCartItem(productId: string) {
    dispatch({ type: "REMOVE_ITEM", productId });
  }

  function clearCart() {
    dispatch({ type: "CLEAR_CART" });
  }

  async function handlePlaceOrder() {
    if (!state.customer || state.cart.length === 0) return;
    dispatch({ type: "SET_SUBMITTING", value: true });
    dispatch({ type: "CLEAR_MSG" });

    const checkoutSessionId = crypto.randomUUID();
    const items = state.cart.map(c => ({
      product_id: c.product.id,
      quantity: c.quantity,
      unit_price: c.unitPrice,
    }));

    const result = await submitWholesaleOrder({
      brandId: state.customer.brand_id,
      customerId: state.customer.id,
      anticipatedPickupDate: state.pickupDate || undefined,
      items,
      checkoutSessionId,
    });

    dispatch({ type: "SET_SUBMITTING", value: false });
    if (result.success) {
      dispatch({
        type: "SET_MSG",
        msg: {
          kind: "success",
          text: `Order placed! Invoice: ${result.invoiceNumber} — Status: ${result.status}`,
        },
      });
      dispatch({ type: "CLEAR_CART" });
      dispatch({ type: "SET_PICKUP_DATE", date: "" });
      void reloadOrders();

      if (result.orderId && state.customer) {
        const total = state.cart.reduce((s, i) => s + i.quantity * i.unitPrice, 0);
        enqueueWholesaleNotification({
          brandId: state.customer.brand_id,
          customerId: state.customer.id,
          orderId: result.orderId,
          type: "order_confirmation",
          emailTo: state.customer.email,
          subject: `Order ${result.invoiceNumber} Confirmed`,
          bodyHtml: `
            <h2>Thank you for your order, ${state.customer.company_name}!</h2>
            <p>Your wholesale order <strong>${result.invoiceNumber}</strong> has been received.</p>
            <p><strong>Total:</strong> $${total.toFixed(2)}</p>
            ${result.status === "awaiting_deposit" ? `<p><strong>Deposit Required:</strong> Your order is awaiting a deposit payment.</p>` : ""}
            <p>We'll notify you when your order is ready for pickup.</p>
          `,
          bodyText: `Order ${result.invoiceNumber} confirmed. Total: $${total.toFixed(2)}. Status: ${result.status}.`,
        });

        const settings = await getWholesaleSettings(state.customer.brand_id);
        const adminEmail =
          settings?.notification_email ??
          settings?.from_email ??
          settings?.invoice_business_email ??
          null;
        if (adminEmail) {
          enqueueWholesaleNotification({
            brandId: state.customer.brand_id,
            customerId: state.customer.id,
            orderId: result.orderId,
            type: "order_confirmation",
            emailTo: adminEmail,
            subject: `[Admin] New Wholesale Order — ${result.invoiceNumber}`,
            bodyHtml: `
              <h2>New Wholesale Order</h2>
              <p>A new wholesale order has been placed by <strong>${state.customer.company_name}</strong>.</p>
              <p><strong>Invoice:</strong> ${result.invoiceNumber}</p>
              <p><strong>Total:</strong> $${total.toFixed(2)}</p>
              <p><strong>Status:</strong> ${result.status}</p>
              ${result.status === "awaiting_deposit" ? `<p><strong>Action Required:</strong> Awaiting deposit payment.</p>` : ""}
            `,
            bodyText: `New wholesale order ${result.invoiceNumber} from ${state.customer.company_name}. Total: $${total.toFixed(2)}. Status: ${result.status}.`,
          });
        }

        fetch(`/api/wholesale/notifications/send`, { method: "POST" }).catch(() => {});
      }
    } else {
      let errorText = result.error ?? "Failed to place order.";
      if (result.creditLimit !== undefined) {
        errorText += ` (Credit limit: $${result.creditLimit} | Outstanding: $${result.outstandingBalance?.toFixed(2)} | Order total: $${result.orderTotal?.toFixed(2)})`;
      }
      dispatch({ type: "SET_MSG", msg: { kind: "error", text: errorText } });
    }
  }

  async function handlePayNow(order: WholesaleCustomerOrder) {
    if (!state.customer) return;
    dispatch({ type: "SET_PROCESSING_PAYMENT", orderId: order.id });
    let checkoutUrl: string | undefined;
    try {
      const res = await fetch("/api/wholesale/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ orderId: order.id, customerId: state.customer.id }),
      });
      const data = await res.json();
      if (!data.checkoutUrl) {
        dispatch({
          type: "SET_MSG",
          msg: { kind: "error", text: data.error ?? "Failed to start payment." },
        });
        dispatch({ type: "SET_PROCESSING_PAYMENT", orderId: null });
        return;
      }
      checkoutUrl = data.checkoutUrl;
    } catch {
      dispatch({
        type: "SET_MSG",
        msg: { kind: "error", text: "Payment request failed." },
      });
      dispatch({ type: "SET_PROCESSING_PAYMENT", orderId: null });
      return;
    }
    dispatch({ type: "SET_PROCESSING_PAYMENT", orderId: null });
    navigateToExternalUrl(checkoutUrl!);
  }

  async function handleSignOut() {
    await wholesaleLogoutAction();
    router.push("/wholesale/login");
  }

  // When the server reports an invalid preview id, render an empty state
  // without trying to fetch anything client-side.
  if (invalidPreview) {
    return <InvalidPreviewScreen />;
  }

  return (
    <div className="min-h-screen bg-slate-100">
      {state.previewMode && (
        <div className="bg-yellow-400 text-yellow-900 text-center py-2 text-sm font-medium">
          Admin Preview — viewing portal as {state.customer?.company_name}
        </div>
      )}
      <PortalHeader
        brandName={state.brandName}
        companyName={state.customer?.company_name}
        onSignOut={handleSignOut}
      />
      <PortalTabs
        tab={state.tab}
        cartCount={state.cart.length}
        onChange={(t) => dispatch({ type: "SET_TAB", tab: t })}
      />

      <div className="mx-auto max-w-5xl px-6 py-6">
        <PortalToast msg={state.msg} />

        {state.tab === "products" && (
          <ProductsTab
            products={state.allProducts}
            pricingOverrides={state.pricingOverrides}
            searchQuery={state.searchQuery}
            filterAvailability={state.filterAvailability}
            onSearch={(q) => dispatch({ type: "SET_SEARCH", q })}
            onFilter={(f) => dispatch({ type: "SET_FILTER", f })}
            onAdd={addToCart}
          />
        )}

        {state.tab === "cart" && (
          <CartTab
            cart={state.cart}
            pickupDate={state.pickupDate}
            minPickupDate={state.minPickupDate}
            submitting={state.submitting}
            onPickupDate={(d) => dispatch({ type: "SET_PICKUP_DATE", date: d })}
            onIncrement={incrementCartItem}
            onDecrement={decrementCartItem}
            onRemove={removeCartItem}
            onClear={clearCart}
            onPlaceOrder={handlePlaceOrder}
          />
        )}

        {state.tab === "orders" && (
          <OrdersTab
            orders={state.orders}
            onlinePaymentEnabled={state.onlinePaymentEnabled}
            processingPayment={state.processingPayment}
            onPayNow={handlePayNow}
          />
        )}
      </div>

      <div className="mx-auto max-w-5xl px-6 py-8 text-center">
        <p className="text-xs text-slate-400">
          Powered by{" "}
          <a
            href="https://cielohermosa.com"
            target="_blank"
            rel="noopener noreferrer"
            className="hover:text-slate-600"
          >
            Route Commerce
          </a>
        </p>
      </div>
    </div>
  );
}

// ── Invalid Preview Screen ───────────────────────────────────────────────────
// Rendered when the server reports an invalid preview id. Shows an empty
// state without trying to fetch anything client-side.
function InvalidPreviewScreen() {
  return (
    <div className="min-h-screen bg-slate-100">
      <div className="mx-auto max-w-5xl px-6 py-12">
        <EmptyState
          icon={
            <svg
              className="w-7 h-7 text-slate-400"
              fill="none"
              viewBox="0 0 24 24"
              stroke="currentColor"
              strokeWidth={1.5}
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"
              />
            </svg>
          }
          title="Preview customer not found"
          description="The preview_customer_id did not match any wholesale customer."
        />
      </div>
    </div>
  );
}
