/**
 * 类型化路由常量
 *
 * 关键设计：
 *  - `as const` 让每个值都是字符串字面量类型，可用于 `PageProps<'/literal'>`。
 *  - 不导出 Client-only 模块（`use-auth-gate` 走独立路径导入），保证 Server bundle 不被污染。
 *  - 动态查询路由通过 `ROUTE_BUILDERS` 函数生成，避免手拼字符串。
 */

import type { PayChannel } from "@/data/schemas/payment";
import type { AppSubscriptionReturnTo } from "@/router/navigation-types";
import type { CharacterProfile } from "@/data/constants/character";
import {
  PAYMENT_ANALYTICS_ENTRY_PARAM,
  PAYMENT_ANALYTICS_REASON_PARAM,
  type PaymentAnalyticsContext,
} from "@/lib/analytics/payment_analytics_context";

/** 静态路由字面量 */
export const ROUTES = {
  root: "/",
  splash: "/splash",
  chat: "/chat",
  call: "/call",
  privateZone: "/private-zone",
  tip: "/tip",
  externalEntry: "/external-entry",
  auth: "/auth",
  profile: "/profile",
  feedback: "/feedback",
  subscription: "/subscription",
  coinsRules: "/coins-rules",
} as const;

export type StaticRoute = (typeof ROUTES)[keyof typeof ROUTES];

export interface CharacterRoutes {
  readonly splash: string;
  readonly chat: string;
  readonly call: string;
  readonly privateZone: string;
  readonly tip: string;
}

export function getCharacterRoutes(
  characterSlug: CharacterProfile["slug"],
): CharacterRoutes {
  const root = `/characters/${encodeURIComponent(characterSlug)}`;
  return {
    splash: `${root}/splash`,
    chat: `${root}/chat`,
    call: `${root}/call`,
    privateZone: `${root}/private-zone`,
    tip: `${root}/tip`,
  };
}

export type RouteSearchParams = Record<
  string,
  string | readonly string[] | undefined
>;

export function appendRouteSearchParams(
  pathname: string,
  searchParams: RouteSearchParams,
): string {
  const params = new URLSearchParams();
  for (const [key, value] of Object.entries(searchParams)) {
    if (typeof value === "string") {
      params.set(key, value);
      continue;
    }
    value?.forEach((item) => params.append(key, item));
  }
  const query = params.toString();
  return query ? `${pathname}?${query}` : pathname;
}

/** 动态查询路由构造器 */
export const ROUTE_BUILDERS = {
  subscription: (
    type: "vip" | "topup",
    options: {
      payChannel?: PayChannel;
      returnTo?: Exclude<AppSubscriptionReturnTo, null>;
      sourceCharacterSlug?: string;
      analytics?: PaymentAnalyticsContext;
      planId?: string;
      commercialOfferId?: string;
      resumeOrderId?: string;
      chatActionId?: string;
    } = {},
  ): `/subscription?${string}` => {
    const params = new URLSearchParams({ type });
    if (options.payChannel) params.set("payChannel", options.payChannel);
    if (options.returnTo) params.set("returnTo", options.returnTo);
    if (options.sourceCharacterSlug) {
      params.set("character", options.sourceCharacterSlug);
    }
    if (options.planId) params.set("planId", options.planId);
    if (options.commercialOfferId) {
      params.set("commercialOfferId", options.commercialOfferId);
    }
    if (options.resumeOrderId) {
      params.set("resumeOrderId", options.resumeOrderId);
    }
    if (options.chatActionId) {
      params.set("chatActionId", options.chatActionId);
    }
    if (options.analytics) {
      params.set(
        PAYMENT_ANALYTICS_ENTRY_PARAM,
        options.analytics.entryPoint,
      );
      params.set(
        PAYMENT_ANALYTICS_REASON_PARAM,
        options.analytics.triggerReason,
      );
    }
    return `${ROUTES.subscription}?${params.toString()}` as const;
  },
  authWithRedirect: (redirectTo: string): `/auth?redirect=${string}` =>
    `${ROUTES.auth}?redirect=${encodeURIComponent(redirectTo)}` as const,
} as const;

/** 所有静态路由，供 `proxy.ts` matcher 与未来 sitemap 使用 */
export const ALL_STATIC_ROUTES: readonly StaticRoute[] = [
  ROUTES.splash,
  ROUTES.chat,
  ROUTES.call,
  ROUTES.privateZone,
  ROUTES.tip,
  ROUTES.externalEntry,
  ROUTES.auth,
  ROUTES.profile,
  ROUTES.feedback,
  ROUTES.coinsRules,
] as const;

/** 联合路由类型 */
export type Route = StaticRoute;
