import { redirect } from "next/navigation";
import { NewOrderScreen } from "@/components/panel/new-order/new-order-screen";
import type {
  CategoryDTO,
  NewOrderConfig,
  PlatformKey,
  ServiceDTO,
  ServiceTypeKey,
} from "@/components/panel/new-order/types";
import { PanelShell } from "@/components/panel/shell";
import { LandingPage } from "@/components/public/landing";
import { db } from "@/lib/db";
import { getOptionalUser } from "@/lib/guards";
import { userRate } from "@/lib/pricing";
import { dec, money } from "@/lib/serialize";
import { getGeneralSettings, getModuleSettings } from "@/lib/settings";
import { SUBSCRIPTION_DELAY_VALUES } from "@/lib/validation/order";

export const dynamic = "force-dynamic";

function hiddenIds(value: unknown): Set<number> {
  if (!Array.isArray(value)) return new Set();
  return new Set(value.map((v) => Number(v)).filter((n) => Number.isInteger(n)));
}

export default async function HomePage(props: {
  searchParams: Promise<Record<string, string | string[] | undefined>>;
}) {
  const searchParams = await props.searchParams;
  const raw = searchParams.service;
  const deepLink = Array.isArray(raw) ? raw[0] : raw;
  const initialServiceId = deepLink && /^\d+$/.test(deepLink) ? Number(deepLink) : null;

  const sessionUser = await getOptionalUser();
  if (!sessionUser) return <LandingPage />;

  const [dbUser, totalOrders, categories, customRates, general, modules] = await Promise.all([
    db.user.findUnique({
      where: { id: sessionUser.id },
      select: {
        id: true,
        username: true,
        balance: true,
        discountPercent: true,
        hiddenServices: true,
      },
    }),
    db.order.count(),
    db.category.findMany({
      where: { active: true },
      orderBy: [{ position: "asc" }, { name: "asc" }],
      include: {
        services: {
          where: { active: true },
          orderBy: [{ position: "asc" }, { id: "asc" }],
        },
      },
    }),
    db.userCustomRate.findMany({
      where: { userId: sessionUser.id },
      select: { serviceId: true, rate: true },
    }),
    getGeneralSettings(),
    getModuleSettings(),
  ]);

  if (!dbUser) redirect("/signin");

  const symbol = general.currencySymbol || "$";
  const hidden = hiddenIds(dbUser.hiddenServices);
  const rateOverrides = new Map(customRates.map((r) => [r.serviceId, r.rate]));

  const services: ServiceDTO[] = [];
  const categoryDTOs: CategoryDTO[] = [];

  for (const category of categories) {
    const list = category.services.filter((s) => !hidden.has(s.id));
    if (list.length === 0) continue;

    categoryDTOs.push({
      id: category.id,
      name: category.name,
      platform: category.platform as PlatformKey,
      serviceCount: list.length,
    });

    for (const service of list) {
      const rate = userRate(service, dbUser, rateOverrides.get(service.id) ?? null);
      const rateLabel = money(rate, symbol);
      services.push({
        id: service.id,
        name: service.name,
        description: service.description ?? "",
        type: service.type as ServiceTypeKey,
        categoryId: category.id,
        categoryName: category.name,
        platform: category.platform as PlatformKey,
        rate: dec(rate),
        rateLabel,
        label: `${service.id} - ${service.name} - ${rateLabel} per 1000`,
        min: service.min,
        max: service.max,
        increment: service.increment ?? null,
        dripfeedEnabled: service.dripfeedEnabled,
        refillEnabled: service.refillEnabled,
        refillDays: service.refillDays ?? null,
        cancelEnabled: service.cancelEnabled,
        averageTimeMinutes: service.averageTimeMinutes ?? null,
        denyLinkDuplicates: service.denyLinkDuplicates,
        search: `${service.id} ${service.name} ${category.name} ${service.description ?? ""}`
          .toLowerCase()
          .trim(),
      });
    }
  }

  const config: NewOrderConfig = {
    currencySymbol: symbol,
    minDripIntervalMinutes: Math.max(1, Math.trunc(general.minDripIntervalMinutes || 1)),
    averageTimeEnabled: modules.averageTime.enabled,
    delayOptions: [...SUBSCRIPTION_DELAY_VALUES],
  };

  const balanceLabel = money(dbUser.balance, symbol);

  return (
    <PanelShell
      user={{
        id: dbUser.id,
        username: dbUser.username,
        role: sessionUser.role,
        balance: balanceLabel,
        impersonated: Boolean(sessionUser.impersonatedBy),
      }}
    >
      <NewOrderScreen
        user={{
          username: dbUser.username,
          balance: dec(dbUser.balance),
          balanceLabel,
        }}
        totalOrders={totalOrders}
        services={services}
        categories={categoryDTOs}
        config={config}
        initialServiceId={initialServiceId}
      />
    </PanelShell>
  );
}
