/**
 * @fileoverview Class management endpoints for Aurora API.
 * Provides CRUD operations for player classes/guilds.
 */

import type { RouteContext, RouteModule } from "./types";
import {
    jsonResponse,
    errorResponse,
    parseBody,
    parseStringIdFromPath,
    withErrorHandling
} from "./utils";
import { CreateClassSchema, UpdateClassSchema } from "./schemas";

/**
 * Classes routes handler.
 * 
 * Endpoints:
 * - GET /api/classes - List all classes
 * - POST /api/classes - Create a new class
 * - PUT /api/classes/:id - Update a class
 * - DELETE /api/classes/:id - Delete a class
 */
async function handler(ctx: RouteContext): Promise<Response | null> {
    const { pathname, method, req } = ctx;

    // Only handle requests to /api/classes*
    if (!pathname.startsWith("/api/classes")) {
        return null;
    }

    const { classService } = await import("@shared/modules/class/class.service");

    /**
     * @route GET /api/classes
     * @description Returns all classes/guilds in the system.
     * 
     * @response 200 - `{ classes: Class[] }`
     * @response 500 - Error fetching classes
     * 
     * @example
     * // Response
     * {
     *   "classes": [
     *     { "id": "1", "name": "Warrior", "balance": "5000", "roleId": "123456789" }
     *   ]
     * }
     */
    if (pathname === "/api/classes" && method === "GET") {
        return withErrorHandling(async () => {
            const classes = await classService.getAllClasses();
            return jsonResponse({ classes });
        }, "fetch classes");
    }

    /**
     * @route POST /api/classes
     * @description Creates a new class/guild.
     * 
     * @body {
     *   id: string | number (required) - Unique class identifier,
     *   name: string (required) - Class display name,
     *   balance?: string | number - Initial class balance (default: 0),
     *   roleId?: string - Associated Discord role ID
     * }
     * @response 201 - `{ success: true, class: Class }`
     * @response 400 - Missing required fields
     * @response 500 - Error creating class
     * 
     * @example
     * // Request
     * POST /api/classes
     * { "id": "2", "name": "Mage", "balance": "0", "roleId": "987654321" }
     */
    if (pathname === "/api/classes" && method === "POST") {
        return withErrorHandling(async () => {
            const data = await req.json() as Record<string, any>;

            if (!data.id || !data.name || typeof data.name !== 'string') {
                return errorResponse("Missing required fields: id and name are required", 400);
            }

            const newClass = await classService.createClass({
                id: BigInt(data.id),
                name: data.name,
                balance: data.balance ? BigInt(data.balance) : 0n,
                roleId: data.roleId || null,
            });

            return jsonResponse({ success: true, class: newClass }, 201);
        }, "create class");
    }

    /**
     * @route PUT /api/classes/:id
     * @description Updates an existing class.
     * 
     * @param id - Class ID
     * @body {
     *   name?: string - Updated class name,
     *   balance?: string | number - Updated balance,
     *   roleId?: string - Updated Discord role ID
     * }
     * @response 200 - `{ success: true, class: Class }`
     * @response 404 - Class not found
     * @response 500 - Error updating class
     */
    if (pathname.match(/^\/api\/classes\/\d+$/) && method === "PUT") {
        const id = parseStringIdFromPath(pathname);
        if (!id) return null;

        return withErrorHandling(async () => {
            const data = await req.json() as Record<string, any>;

            const updateData: any = {};
            if (data.name !== undefined) updateData.name = data.name;
            if (data.balance !== undefined) updateData.balance = BigInt(data.balance);
            if (data.roleId !== undefined) updateData.roleId = data.roleId;

            const updatedClass = await classService.updateClass(BigInt(id), updateData);

            if (!updatedClass) {
                return errorResponse("Class not found", 404);
            }

            return jsonResponse({ success: true, class: updatedClass });
        }, "update class");
    }

    /**
     * @route DELETE /api/classes/:id
     * @description Deletes a class. Users assigned to this class will need to be reassigned.
     * 
     * @param id - Class ID
     * @response 204 - Class deleted (no content)
     * @response 500 - Error deleting class
     */
    if (pathname.match(/^\/api\/classes\/\d+$/) && method === "DELETE") {
        const id = parseStringIdFromPath(pathname);
        if (!id) return null;

        return withErrorHandling(async () => {
            await classService.deleteClass(BigInt(id));
            return new Response(null, { status: 204 });
        }, "delete class");
    }

    return null;
}

export const classesRoutes: RouteModule = {
    name: "classes",
    handler
};
