import ProductsPageClient from "@/components/products/ProductsPageClient";
import { normalizeProductFilter, productRepository } from "@/lib/repositories/productRepository";
import { shopRepository } from "@/lib/repositories/shopRepository";
import { resolveShopScope, restrictedShopIds } from "@/lib/storeScope";
import { getCurrentUser } from "@/lib/currentUser";

export const dynamic = "force-dynamic";

type SearchParams = Promise<Record<string, string | string[] | undefined>>;

function firstParam(value: string | string[] | undefined) {
  return Array.isArray(value) ? value[0] : value;
}

function productView(value: string | undefined) {
  return value === "master_sku" ? "master_sku" as const : "products" as const;
}

function productKeys(value: string | undefined) {
  if (!value) return [];
  return Array.from(new Set(value.split(",").map((key) => key.trim()).filter(Boolean)))
    .slice(0, 100)
    .map((key) => {
      const [shopId, itemId, modelId = "0"] = key.split(":");
      return shopId && itemId ? { shopId, itemId, modelId } : null;
    })
    .filter((key): key is { shopId: string; itemId: string; modelId: string } => key !== null);
}

export default async function ProductsPage({ searchParams }: { searchParams: SearchParams }) {
  const params = await searchParams;
  const current = await getCurrentUser();
  const shops = current ? await shopRepository.findScopeOptionsForUser(current) : [];
  const activeShopId = resolveShopScope(firstParam(params.shop_id), shops);
  const shopIds = restrictedShopIds(current?.role, activeShopId, shops);
  const q = firstParam(params.q) || null;
  const status = firstParam(params.status) || null;
  const requestedFilter = normalizeProductFilter(firstParam(params.filter));
  const scopedProductKeys = productKeys(firstParam(params.product_keys));
  // Tautan lama memakai filter=hpp_missing. Setelah HPP diisi, filter itu
  // menyembunyikan SKU yang justru ingin diperiksa pengguna.
  const filter = scopedProductKeys.length > 0 && requestedFilter === "hpp_missing" ? null : requestedFilter;
  const view = productView(firstParam(params.view));
  const page = Number(firstParam(params.page) || "1") || 1;
  const pageSize = Number(firstParam(params.page_size) || "25") || 25;
  const [{ rows, total }, stats, mappedRows, masterSkuKeys] = await Promise.all([
    productRepository.findMany({ shopId: activeShopId, shopIds, search: q, status, filter, productKeys: scopedProductKeys, page, pageSize }),
    productRepository.stats(activeShopId, shopIds),
    view === "master_sku" ? productRepository.findMappedForMasterWorkspace(activeShopId, shopIds) : Promise.resolve([]),
    view === "master_sku" ? Promise.resolve([]) : productRepository.findMasterSkuKeys(activeShopId, shopIds),
  ]);
  const shopNameById = new Map(shops.map((shop) => [shop.shopId, shop.shopName || shop.shopId]));
  const grouped = new Map<string, {
    masterSku: string;
    productCount: number;
    shopIds: Set<string>;
    shopNames: Set<string>;
    platformSkus: Set<string>;
    productNames: Set<string>;
    hppFinalValues: Set<number>;
    missingHppFinal: number;
    imageUrl: string | null;
  }>();
  for (const row of mappedRows) {
    const masterSku = row.masterSku?.trim();
    if (!masterSku) continue;
    const group = grouped.get(masterSku) || {
      masterSku,
      productCount: 0,
      shopIds: new Set<string>(),
      shopNames: new Set<string>(),
      platformSkus: new Set<string>(),
      productNames: new Set<string>(),
      hppFinalValues: new Set<number>(),
      missingHppFinal: 0,
      imageUrl: row.imageUrl,
    };
    group.productCount += 1;
    group.shopIds.add(row.shopId);
    group.shopNames.add(shopNameById.get(row.shopId) || row.shopId);
    if (row.platformSku) group.platformSkus.add(row.platformSku);
    if (row.itemName) group.productNames.add(row.itemName);
    const finalHpp = row.hppFinal ?? row.hpp;
    if (finalHpp === null) group.missingHppFinal += 1;
    else group.hppFinalValues.add(finalHpp);
    if (!group.imageUrl && row.imageUrl) group.imageUrl = row.imageUrl;
    grouped.set(masterSku, group);
  }
  const masterSkuGroups = Array.from(grouped.values()).map((group) => ({
    masterSku: group.masterSku,
    productCount: group.productCount,
    shopCount: group.shopIds.size,
    shopNames: Array.from(group.shopNames),
    platformSkus: Array.from(group.platformSkus),
    productNames: Array.from(group.productNames),
    hppFinal: group.hppFinalValues.size === 1 ? Array.from(group.hppFinalValues)[0] : null,
    hppFinalMixed: group.hppFinalValues.size > 1,
    missingHppFinal: group.missingHppFinal,
    imageUrl: group.imageUrl,
  }));

  return (
    <ProductsPageClient
      key={`${activeShopId || "all"}:${q || ""}:${status || ""}:${filter || ""}:${view}:${page}`}
      initial={{
        shops: shops.map((shop) => ({ shopId: shop.shopId, shopName: shop.shopName, connected: shop.connected })),
        activeShopId,
        rows: rows.map((row) => ({
          ...row,
          updateTime: row.updateTime?.toISOString() ?? null,
          hppUpdatedAt: row.hppUpdatedAt?.toISOString() ?? null,
          hppAwalUpdatedAt: row.hppAwalUpdatedAt?.toISOString() ?? null,
          hppFinalUpdatedAt: row.hppFinalUpdatedAt?.toISOString() ?? null,
        })),
        total,
        stats: {
          ...stats,
          masterGroups: view === "master_sku"
            ? masterSkuGroups.length
            : new Set(masterSkuKeys.map((row) => row.masterSku?.trim()).filter(Boolean)).size,
        },
        masterSkuGroups,
        q,
        status,
        filter,
        profitRepair: scopedProductKeys.length > 0,
        repairHppComplete: scopedProductKeys.length > 0 && total > 0 && total <= rows.length
          && rows.every((row) => (row.hppFinal ?? row.hpp) !== null),
        view,
        page,
        pageSize,
      }}
    />
  );
}
