import { auth } from "@/auth";
import {
  listProducts,
  listCategories,
  listProductStatuses,
  getProductMarketMetrics,
  isValidSortKey,
  isValidPageSize,
  isValidAvailabilityFilter,
  DEFAULT_PRODUCT_PAGE_SIZE,
  type ProductSortKey,
  type ProductAvailabilityFilter,
  type ProductMarketMetricView,
} from "@/database/products";
import { listSavedProductIds } from "@/database/saved-products";
import { recordSearch } from "@/database/search-history";
import { toProductCardView, type ProductCardView } from "@/lib/product-data/view-models";
import {
  ProductsPageContent,
  type ProductCatalogVariant,
  type ProductsFilterState,
} from "@/components/dashboard/products-page-content";

function parseNumber(value: string | undefined): number | undefined {
  if (!value) return undefined;
  const n = Number(value);
  return Number.isFinite(n) ? n : undefined;
}

function parseScore(value: string | undefined): number | undefined {
  const n = parseNumber(value);
  if (n === undefined) return undefined;
  return Math.max(0, Math.min(100, Math.round(n)));
}

function parseBoolean(value: string | undefined): boolean {
  return value === "true" || value === "1";
}

export async function ProductCatalogPage({
  searchParams,
  variant,
}: {
  searchParams: Promise<Record<string, string | string[] | undefined>>;
  variant: ProductCatalogVariant;
}) {
  const raw = await searchParams;
  const get = (key: string): string | undefined => {
    const v = raw[key];
    return Array.isArray(v) ? v[0] : v;
  };

  const q = get("q");
  const category = get("category");
  const minPrice = parseNumber(get("minPrice"));
  const maxPrice = parseNumber(get("maxPrice"));
  const minOpportunity = parseScore(get("minOpportunity"));
  const minTrend = parseScore(get("minTrend"));
  const maxSaturation = parseScore(get("maxSaturation"));
  const minConfidence = parseScore(get("minConfidence"));
  const minGrowthVelocity = parseScore(get("minGrowthVelocity"));
  const minDemandAcceleration = parseScore(get("minDemandAcceleration"));
  const maxRisk = parseScore(get("maxRisk"));
  const minCompetitionTrend = parseScore(get("minCompetitionTrend"));
  const minGrowth = parseScore(get("minGrowth"));
  const minMomentum = parseScore(get("minMomentum"));
  const savedOnly = parseBoolean(get("savedOnly"));
  const availabilityParam = get("availability") ?? "";
  const availability: ProductAvailabilityFilter = isValidAvailabilityFilter(availabilityParam) ? availabilityParam : "active";
  const upstreamStatus = get("upstreamStatus");
  const sortParam = get("sort") ?? "";
  const sort: ProductSortKey = isValidSortKey(sortParam) ? sortParam : "opportunity";
  const pageParam = parseNumber(get("page"));
  const page = pageParam && pageParam > 0 ? Math.floor(pageParam) : 1;
  const pageSizeParam = parseNumber(get("pageSize"));
  const pageSize = pageSizeParam && isValidPageSize(pageSizeParam) ? pageSizeParam : DEFAULT_PRODUCT_PAGE_SIZE;

  const filters: ProductsFilterState = {
    q,
    category,
    minPrice,
    maxPrice,
    minOpportunity,
    minTrend,
    maxSaturation,
    minConfidence,
    minGrowthVelocity,
    minDemandAcceleration,
    maxRisk,
    minCompetitionTrend,
    minGrowth,
    minMomentum,
    savedOnly,
    availability,
    upstreamStatus,
  };

  let loadError = false;
  let products: ProductCardView[] = [];
  let categories: string[] = [];
  let statuses: string[] = [];
  let total = 0;
  let savedProductIds: string[] = [];
  let marketMetrics: Record<string, ProductMarketMetricView> = {};

  try {
    const session = await auth();
    const userId = session?.user?.id;
    const [listResult, categoryList, statusList] = await Promise.all([
      listProducts({
        q,
        category,
        minPrice,
        maxPrice,
        minOpportunity,
        minTrend,
        maxSaturation,
        minConfidence,
        minGrowthVelocity,
        minDemandAcceleration,
        maxRisk,
        minCompetitionTrend,
        minGrowth,
        minMomentum,
        savedOnly,
        availability,
        upstreamStatus,
        userId,
        sort,
        page,
        pageSize,
      }),
      listCategories(),
      listProductStatuses(),
    ]);

    products = listResult.products.map(toProductCardView);
    categories = categoryList;
    statuses = statusList;
    total = listResult.total;
    if (variant === "marketExplorer") {
      marketMetrics = await getProductMarketMetrics(listResult.products.map((product) => product.id));
    }

    if (userId) {
      const productIds = listResult.products.map((p) => p.id);
      savedProductIds = Array.from(await listSavedProductIds(userId, productIds));
      if (q) {
        recordSearch(userId, q, listResult.total).catch(() => {});
      }
    }
  } catch (error) {
    console.error("[product catalog page] failed to load products", error);
    loadError = true;
  }

  return (
    <ProductsPageContent
      variant={variant}
      products={products}
      categories={categories}
      total={total}
      page={page}
      pageSize={pageSize}
      sort={sort}
      savedProductIds={savedProductIds}
      filters={filters}
      statuses={statuses}
      loadError={loadError}
      marketMetrics={marketMetrics}
    />
  );
}
