import type { ReactNode } from "react";

import { AccessDeniedView } from "@/app/customer/_components/access-denied-view";
import { CustomerPageShell } from "@/app/customer/_components/customer-page-shell";
import { customerPageAllows } from "@/app/customer/_lib/customer-page-guard";
import type { CustomerRouteGuard } from "@/app/customer/_lib/customer-route-guard";
import {
  getCustomerSessionContext,
  type CustomerPortalCapabilities,
  type CustomerSessionContext,
} from "@/lib/frontend-auth/server";

export type AdminPageContext = {
  denied: boolean;
  deniedView: ReactNode | null;
  session: CustomerSessionContext;
  routes: readonly string[];
  capabilities: CustomerPortalCapabilities | undefined;
};

type LoadAdminPageContextOptions = {
  /** Route key(s) required for page access (any-of). */
  page: CustomerRouteGuard;
  /** Label shown on AccessDeniedView when denied. */
  label: string;
};

/**
 * Shared RSC bootstrap for tenant admin pages: page ACL 鈡 AccessDenied or session.
 */
export async function loadAdminPageContext(
  tenant: string,
  options: LoadAdminPageContextOptions,
): Promise<AdminPageContext> {
  const allowed = await customerPageAllows(tenant, options.page);
  const session = await getCustomerSessionContext(tenant);

  if (!allowed) {
    return {
      denied: true,
      deniedView: (
        <CustomerPageShell>
          <AccessDeniedView label={options.label} />
        </CustomerPageShell>
      ),
      session,
      routes: session.permissions.routes,
      capabilities: session.permissions.capabilities,
    };
  }

  return {
    denied: false,
    deniedView: null,
    session,
    routes: session.permissions.routes,
    capabilities: session.permissions.capabilities,
  };
}

export function firstSearchParam(value: string | string[] | undefined): string {
  if (Array.isArray(value)) {
    return value[0] ?? "";
  }
  return value ?? "";
}

/**
 * Shared RSC query parsing for tenant admin list pages (page / pageSize / q).
 */
export function parseAdminListPageQuery(
  query: Record<string, string | string[] | undefined>,
  defaultPageSize = 20,
): { page: number; pageSize: number; q: string } {
  // Inline parse to avoid circular imports with server helpers in RSC boundary.
  const pageRaw = Number(firstSearchParam(query.page));
  const pageSizeRaw = Number(firstSearchParam(query.pageSize));
  return {
    page: Number.isFinite(pageRaw) && pageRaw > 0 ? pageRaw : 1,
    pageSize: Number.isFinite(pageSizeRaw) && pageSizeRaw > 0 ? pageSizeRaw : defaultPageSize,
    q: firstSearchParam(query.q).trim(),
  };
}
