/**
 * @fileoverview Route registration module for Aurora API.
 * Aggregates all route handlers and provides a unified request handler.
 */

import type { RouteContext, RouteModule } from "./types";
import { authRoutes, isAuthenticated, getSession } from "./auth.routes";
import { healthRoutes } from "./health.routes";
import { statsRoutes } from "./stats.routes";
import { actionsRoutes } from "./actions.routes";
import { questsRoutes } from "./quests.routes";
import { settingsRoutes } from "./settings.routes";
import { guildSettingsRoutes } from "./guild-settings.routes";
import { itemsRoutes } from "./items.routes";
import { usersRoutes } from "./users.routes";
import { classesRoutes } from "./classes.routes";
import { moderationRoutes } from "./moderation.routes";
import { transactionsRoutes } from "./transactions.routes";
import { lootdropsRoutes } from "./lootdrops.routes";
import { assetsRoutes } from "./assets.routes";
import { errorResponse } from "./utils";

/** Routes that do NOT require authentication */
const publicRoutes: RouteModule[] = [
    authRoutes,
    healthRoutes,
];

/** Routes that require an authenticated admin session */
const protectedRoutes: RouteModule[] = [
    statsRoutes,
    actionsRoutes,
    questsRoutes,
    settingsRoutes,
    guildSettingsRoutes,
    itemsRoutes,
    usersRoutes,
    classesRoutes,
    moderationRoutes,
    transactionsRoutes,
    lootdropsRoutes,
    assetsRoutes,
];

/**
 * Main request handler that routes requests to appropriate handlers.
 * 
 * @param req - The incoming HTTP request
 * @param url - Parsed URL object
 * @returns Response from matching route handler, or null if no match
 * 
 * @example
 * const response = await handleRequest(req, url);
 * if (response) return response;
 * return new Response("Not Found", { status: 404 });
 */
export async function handleRequest(req: Request, url: URL): Promise<Response | null> {
    const ctx: RouteContext = {
        req,
        url,
        method: req.method,
        pathname: url.pathname,
    };

    // Try public routes first (auth, health)
    for (const module of publicRoutes) {
        const response = await module.handler(ctx);
        if (response !== null) return response;
    }

    // For API routes, enforce authentication
    if (ctx.pathname.startsWith("/api/")) {
        const session = getSession(req);
        if (!session) {
            return errorResponse("Unauthorized", 401);
        }

        // Admin-only routes: everything except stats and own user data
        const playerAllowedPrefixes = ["/api/stats", "/api/health"];
        const isPlayerAllowed = playerAllowedPrefixes.some(p => ctx.pathname.startsWith(p));

        // Players can access their own user data
        const isOwnUserRoute = ctx.pathname.match(/^\/api\/users\/\d+/) && session.role === "player";

        if (session.role === "player" && !isPlayerAllowed && !isOwnUserRoute) {
            return errorResponse("Admin access required", 403);
        }
    }

    // Try protected routes
    for (const module of protectedRoutes) {
        const response = await module.handler(ctx);
        if (response !== null) return response;
    }

    return null;
}

/**
 * Get list of all registered route module names.
 * Useful for debugging and documentation.
 */
export function getRegisteredRoutes(): string[] {
    return [...publicRoutes, ...protectedRoutes].map(m => m.name);
}
