import { Suspense } from "react";
import Image from "next/image";
import { getAdminUser } from "@/lib/admin-permissions";
import { getActiveBrandId } from "@/lib/brand-scope";
import { pool } from "@/lib/db";
import PageHeader from "@/components/admin/PageHeader";
import { CardList, CardListItem } from "@/components/admin/CardList";
import StatusPill, { type StatusKind } from "@/components/admin/StatusPill";
import EmptyState from "@/components/admin/EmptyState";
import PullToRefresh from "@/components/admin/PullToRefresh";
import ProductsFilterChips from "@/components/admin/products/ProductsFilterChips";
import StockAdjustButton from "@/components/admin/products/StockAdjustButton";

export const dynamic = "force-dynamic";

/**
 * Row shape for the v2 products list. Mirrors the columns we actually
 * select from the `products` table — the plan's speculative shape used
 * `stock` / `image_url` / `price_cents` which is close, but the real
 * stock column is `inventory` (not `stock`), `image_url` and
 * `price_cents` are correct as-is, and there is no `hidden` field
 * (visibility is the boolean `active`).
 */
interface DbProductRow {
  id: string;
  name: string;
  price_cents: number;
  inventory: number;
  image_url: string | null;
  active: boolean;
  brand_id: string;
}

/**
 * Map an inventory count onto the StatusPill vocabulary. Matches the
 * thresholds the v1 admin Products page uses (out = 0, low < 10, else in
 * stock). The `kind` doubles as a CSS-friendly token; the `label` is the
 * user-visible string (includes the count so the user can read it at
 * a glance in the field).
 */
function stockStatus(inventory: number): { kind: StatusKind; label: string } {
  if (inventory === 0) return { kind: "out", label: "Out of stock" };
  if (inventory < 10) return { kind: "low", label: `⚠ ${inventory} left` };
  return { kind: "in-stock", label: `${inventory} in stock` };
}

/**
 * Build the inventory/active filter clause for a given `?filter=` value.
 *
 * - "all"      → no filter
 * - "in-stock" → inventory >= 10
 * - "low"      → 0 < inventory < 10
 * - "out"      → inventory = 0
 * - "hidden"   → active = false (no separate `hidden` column in the
 *                schema — "hidden" maps to the legacy "inactive" state)
 * - unknown    → same as "all" (defensive: don't 500 on a bad URL)
 */
function filterClause(filter: string | undefined): { sql: string; params: unknown[] } {
  switch (filter) {
    case "in-stock":
      return { sql: " AND inventory >= 10", params: [] };
    case "low":
      return { sql: " AND inventory > 0 AND inventory < 10", params: [] };
    case "out":
      return { sql: " AND inventory = 0", params: [] };
    case "hidden":
      return { sql: " AND active = false", params: [] };
    case "all":
    default:
      return { sql: "", params: [] };
  }
}

export default async function ProductsV2Page({
  searchParams,
}: {
  searchParams: Promise<{ filter?: string }>;
}) {
  const adminUser = await getAdminUser();
  if (!adminUser) return null;

  const [activeBrandId, params] = await Promise.all([
    getActiveBrandId(adminUser),
    searchParams,
  ]);
  const filter = params.filter;
  const { sql: filterSql, params: filterParams } = filterClause(filter);

  // Mirror the v2 stops page's brand-scoping pattern: explicit active
  // brand > platform_admin "all brands" > multi-brand membership list.
  let products: DbProductRow[] = [];
  let queryError: string | null = null;
  try {
    const selectFields = `
      id, name, price_cents, inventory, image_url, active, brand_id
    `;
    const orderBy = `name ASC`;

    if (activeBrandId) {
      const result = await pool.query<DbProductRow>(
        `SELECT ${selectFields}
           FROM products
          WHERE brand_id = $1 ${filterSql}
          ORDER BY ${orderBy}
          LIMIT 200`,
        [activeBrandId, ...filterParams],
      );
      products = result.rows;
    } else if (adminUser.role === "platform_admin") {
      const result = await pool.query<DbProductRow>(
        `SELECT ${selectFields}
           FROM products
          WHERE 1=1 ${filterSql}
          ORDER BY ${orderBy}
          LIMIT 200`,
        [...filterParams],
      );
      products = result.rows;
    } else {
      const brandIds = adminUser.brand_ids ?? [];
      if (brandIds.length === 0) {
        products = [];
      } else {
        const result = await pool.query<DbProductRow>(
          `SELECT ${selectFields}
             FROM products
            WHERE brand_id = ANY($1::uuid[]) ${filterSql}
            ORDER BY ${orderBy}
            LIMIT 200`,
          [brandIds, ...filterParams],
        );
        products = result.rows;
      }
    }
  } catch (e) {
    queryError = e instanceof Error ? e.message : String(e);
    console.error("[admin/v2/products] query error:", queryError);
  }

  if (queryError) {
    return (
      <main>
        <PageHeader title="Products" />
        <Suspense fallback={null}>
          <ProductsFilterChips active={filter ?? "all"} />
        </Suspense>
        <div className="px-4 pb-24">
          <EmptyState
            title="Couldn't load products"
            description={queryError}
            icon={<span aria-hidden="true">⚠️</span>}
          />
        </div>
      </main>
    );
  }

  if (products.length === 0) {
    return (
      <main>
        <PageHeader title="Products" />
        <Suspense fallback={null}>
          <ProductsFilterChips active={filter ?? "all"} />
        </Suspense>
        <PullToRefresh>
          <EmptyState
            title="No products"
            description="Add your first product to start selling."
            icon={<span aria-hidden="true">🥬</span>}
          />
        </PullToRefresh>
      </main>
    );
  }

  return (
    <main>
      <PageHeader
        title="Products"
        subtitle={`${products.length} product${products.length === 1 ? "" : "s"}`}
      />
      <Suspense fallback={null}>
        <ProductsFilterChips active={filter ?? "all"} />
      </Suspense>
      <PullToRefresh>
        <CardList ariaLabel="Products">
          {products.map((product) => {
            const stock = stockStatus(product.inventory);
            // price_cents → display dollars, two decimals. The schema
            // stores integer cents, so the legacy `price` field (in
            // dollars) would be `price_cents / 100`.
            const priceDollars = (product.price_cents / 100).toFixed(2);
            return (
              <CardListItem key={product.id} href={`/admin/v2/products/${product.id}`}>
                <div className="flex items-start gap-3">
                  {product.image_url ? (
                    // Product images may live on a third-party CDN;
                    // we whitelist remotePatterns or rely on `unoptimized`
                    // when the host isn't whitelisted. The Image
                    // component is used for its layout + sizing
                    // behaviors, even when we don't optimize the bytes.
                    <Image
                      src={product.image_url}
                      alt=""
                      width={64}
                      height={64}
                      unoptimized
                      className="w-16 h-16 rounded-2xl object-cover shrink-0"
                    />
                  ) : (
                    <div
                      className="w-16 h-16 rounded-2xl shrink-0 flex items-center justify-center"
                      style={{ backgroundColor: "var(--color-surface-3)" }}
                      aria-hidden="true"
                    >
                      🥬
                    </div>
                  )}
                  <div className="flex-1 min-w-0">
                    <div className="flex items-start justify-between gap-2">
                      <div className="text-h2" style={{ fontWeight: 700, lineHeight: 1.3 }}>{product.name}</div>
                      <StockAdjustButton productId={product.id} currentStock={product.inventory} />
                    </div>
                    <div className="text-h1 font-display mt-1" style={{ fontWeight: 600 }}>${priceDollars}</div>
                    <div className="mt-2">
                      <StatusPill status={stock.kind} label={stock.label} />
                    </div>
                  </div>
                </div>
              </CardListItem>
            );
          })}
        </CardList>
      </PullToRefresh>
    </main>
  );
}
