import { asc, eq, sql } from "drizzle-orm";
import { withPlatformAdmin, withBrand } from "@/db/client";
import { products, productImages, brands } from "@/db/schema";
import { getAdminUser } from "@/lib/admin-permissions";
import { getActiveBrandId } from "@/lib/brand-scope";
import AdminAccessDenied from "@/components/admin/AdminAccessDenied";
import ProductsClient from "@/components/admin/ProductsClient";
import { getBrands } from "@/actions/admin/users";

// Shape ProductsClient expects (legacy columns mapped from the new schema).
type ProductRow = {
  id: string;
  name: string;
  description: string;
  price: number;
  type: string;
  active: boolean;
  image_url: string | null;
  brand_id: string;
  is_taxable: boolean;
  available_from: string | null;
  available_until: string | null;
};

export default async function AdminProductsPage() {
  const adminUser = await getAdminUser();

  if (!adminUser) return <AdminAccessDenied />;

  if (!adminUser.can_manage_products) {
    return (
      <main className="min-h-screen bg-[var(--admin-bg)] px-4 sm:px-6 md:px-8 py-6 sm:py-8">
        <div className="mx-auto max-w-6xl">
          <h1 className="text-2xl sm:text-3xl font-bold text-[var(--admin-danger)]">Access Denied</h1>
          <p className="mt-2 text-sm text-[var(--admin-text-muted)]">You do not have permission to manage products.</p>
        </div>
      </main>
    );
  }

  const activeBrandId = await getActiveBrandId(adminUser);
  const brandId = activeBrandId;
  const isPlatformAdmin = adminUser.role === "platform_admin";

  // Platform admins need a brand picker for new products
  let brandOptions: { id: string; name: string }[] = [];
  if (isPlatformAdmin) {
    const result = await getBrands();
    brandOptions = result.brands ?? [];
  }

  // Query products + their first image. The new SaaS schema:
  //   * renamed `brand_id` → `brand_id` on products
  //   * renamed `price` (numeric) → `price_cents` (integer)
  //   * moved `image_url` off the products table into a separate
  //     `product_images` table (keyed by `product_id` + `position`)
  //   * dropped `type`, `is_taxable`, `deleted_at` (not part of the
  //     SaaS rebuild — they were legacy product-categorization columns)
  // We map the new columns back to the legacy shape that ProductsClient
  // consumes so the existing UI keeps working.
  let productsList: ProductRow[] = [];
  let queryError: string | null = null;
  try {
    const baseQuery = (db: Parameters<Parameters<typeof withBrand>[1]>[0]) =>
      db
        .select({
          id: products.id,
          name: products.name,
          description: products.description,
          priceCents: products.priceCents,
          active: products.active,
          brandId: products.brandId,
          brandName: brands.name,
          firstImageKey: productImages.storageKey,
          firstImagePosition: productImages.position,
        })
        .from(products)
        .leftJoin(brands, eq(brands.id, products.brandId))
        // Pull only the lowest-position image per product. The
        // `position` index on product_images (product_id, position) makes
        // this cheap; a real-world scale would replace it with a
        // DISTINCT ON subquery, but for the current catalog size this
        // join is fine and avoids a second round-trip.
        .leftJoin(
          productImages,
          sql`${productImages.id} = (
            SELECT id FROM product_images
             WHERE product_id = ${products.id}
             ORDER BY position ASC, created_at ASC
             LIMIT 1
          )`,
        )
        .orderBy(asc(products.name));

    const rows = isPlatformAdmin
      ? await withPlatformAdmin((db) => baseQuery(db))
      : brandId
        ? await withBrand(brandId, (db) => baseQuery(db))
        : [];

    // Resolve each row's first image to a public URL. Until object-store
    // wiring lands, just return the storage key (the <Image> component
    // will fail to load and fall back to the placeholder block).
    productsList = rows.map((r) => ({
      id: r.id,
      name: r.name,
      description: r.description ?? "",
      // Legacy UI expects `price` in dollars; the new schema stores cents.
      price: r.priceCents / 100,
      type: "pickup", // legacy column not in new schema
      active: r.active,
      image_url: r.firstImageKey, // storage key, not a public URL yet
      brand_id: r.brandId,
      is_taxable: false, // legacy column not in new schema
      available_from: null,
      available_until: null,
    }));
  } catch (err) {
    queryError = err instanceof Error ? err.message : String(err);
  }

  if (queryError) {
    return (
      <main className="min-h-screen bg-[var(--admin-bg)] px-4 sm:px-6 md:px-8 py-6 sm:py-8">
        <div className="mx-auto max-w-6xl">
          <h1 className="text-2xl sm:text-3xl font-bold text-[var(--admin-danger)]">Error loading products</h1>
          <pre className="mt-4 rounded-xl bg-[var(--admin-card-bg)] border border-[var(--admin-border)] p-4 text-sm text-[var(--admin-text-muted)]">
            {queryError}
          </pre>
        </div>
      </main>
    );
  }

  return (
    <div className="min-h-screen bg-[var(--admin-bg)]">
      <ProductsClient
        products={productsList}
        brandId={brandId ?? undefined}
        brands={brandOptions}
        isPlatformAdmin={isPlatformAdmin}
      />
    </div>
  );
}
