/**
 * @fileoverview Lootdrop management endpoints for Aurora API.
 * Provides endpoints for viewing, spawning, and canceling lootdrops.
 */

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

/**
 * Lootdrops routes handler.
 * 
 * Endpoints:
 * - GET /api/lootdrops - List lootdrops
 * - POST /api/lootdrops - Spawn a lootdrop
 * - DELETE /api/lootdrops/:messageId - Cancel/delete a lootdrop
 */
async function handler(ctx: RouteContext): Promise<Response | null> {
    const { pathname, method, req, url } = ctx;

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

    /**
     * @route GET /api/lootdrops
     * @description Returns recent lootdrops, sorted by newest first.
     * 
     * @query limit - Max results (default: 50)
     * @response 200 - `{ lootdrops: Lootdrop[] }`
     * @response 500 - Error fetching lootdrops
     */
    if (pathname === "/api/lootdrops" && method === "GET") {
        return withErrorHandling(async () => {
            const { lootdrops } = await import("@shared/db/schema");
            const { DrizzleClient } = await import("@shared/db/DrizzleClient");
            const { desc } = await import("drizzle-orm");

            const limit = url.searchParams.get("limit") ? parseInt(url.searchParams.get("limit")!) : 50;

            const result = await DrizzleClient.select()
                .from(lootdrops)
                .orderBy(desc(lootdrops.createdAt))
                .limit(limit);

            return jsonResponse({ lootdrops: result });
        }, "fetch lootdrops");
    }

    /**
     * @route POST /api/lootdrops
     * @description Spawns a new lootdrop in a Discord channel.
     * Requires a valid text channel ID where the bot has permissions.
     * 
     * @body {
     *   channelId: string (required) - Discord channel ID to spawn in,
     *   amount?: number - Reward amount (random if not specified),
     *   currency?: string - Currency type
     * }
     * @response 201 - `{ success: true }`
     * @response 400 - Invalid channel or missing channelId
     * @response 500 - Error spawning lootdrop
     * 
     * @example
     * // Request
     * POST /api/lootdrops
     * { "channelId": "1234567890", "amount": 100, "currency": "Gold" }
     */
    if (pathname === "/api/lootdrops" && method === "POST") {
        return withErrorHandling(async () => {
            const { spawnLootdrop } = await import("../../../bot/modules/economy/lootdrop.handler");
            const { AuroraClient } = await import("../../../bot/lib/BotClient");
            const { TextChannel } = await import("discord.js");

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

            if (!data.channelId) {
                return errorResponse("Missing required field: channelId", 400);
            }

            const channel = await AuroraClient.channels.fetch(data.channelId);

            if (!channel || !(channel instanceof TextChannel)) {
                return errorResponse("Invalid channel. Must be a TextChannel.", 400);
            }

            await spawnLootdrop(channel, data.amount, data.currency);

            return jsonResponse({ success: true }, 201);
        }, "spawn lootdrop");
    }

    /**
     * @route DELETE /api/lootdrops/:messageId
     * @description Cancels and deletes an active lootdrop.
     * The lootdrop is identified by its Discord message ID.
     * 
     * @param messageId - Discord message ID of the lootdrop
     * @response 204 - Lootdrop deleted (no content)
     * @response 404 - Lootdrop not found
     * @response 500 - Error deleting lootdrop
     */
    if (pathname.match(/^\/api\/lootdrops\/[^\/]+$/) && method === "DELETE") {
        const messageId = parseStringIdFromPath(pathname);
        if (!messageId) return null;

        return withErrorHandling(async () => {
            const { deleteLootdrop } = await import("../../../bot/modules/economy/lootdrop.handler");
            const success = await deleteLootdrop(messageId);

            if (!success) {
                return errorResponse("Lootdrop not found", 404);
            }

            return new Response(null, { status: 204 });
        }, "delete lootdrop");
    }

    return null;
}

export const lootdropsRoutes: RouteModule = {
    name: "lootdrops",
    handler
};
