import { createCommand } from "@shared/lib/utils";
import { SlashCommandBuilder } from "discord.js";
import { DrizzleClient } from "@shared/db/DrizzleClient";
import { users, items, inventory } from "@db/schema";
import { desc, sql, eq } from "drizzle-orm";
import { createWarningEmbed } from "@lib/embeds";
import { getLeaderboardEmbed } from "@/modules/leveling/leveling.view";

export const leaderboard = createCommand({
    data: new SlashCommandBuilder()
        .setName("leaderboard")
        .setDescription("View the top players")
        .addStringOption(option =>
            option.setName("type")
                .setDescription("Sort by XP, Balance, or Net Worth")
                .setRequired(true)
                .addChoices(
                    { name: "Level / XP", value: "xp" },
                    { name: "Balance", value: "balance" },
                    { name: "Net Worth", value: "networth" }
                )
        ),
    execute: async (interaction) => {
        await interaction.deferReply();

        const type = interaction.options.getString("type", true);

        let leaders;

        if (type === 'networth') {
            leaders = await DrizzleClient.select({
                username: users.username,
                level: users.level,
                xp: users.xp,
                balance: users.balance,
                netWorth: sql<bigint>`${users.balance} + COALESCE(SUM(${items.price} * ${inventory.quantity}), 0)`.as('net_worth')
            })
                .from(users)
                .leftJoin(inventory, eq(users.id, inventory.userId))
                .leftJoin(items, eq(inventory.itemId, items.id))
                .groupBy(users.id)
                .orderBy(desc(sql`net_worth`))
                .limit(10);
        } else {
            const isXp = type === "xp";
            leaders = await DrizzleClient.query.users.findMany({
                orderBy: isXp ? desc(users.xp) : desc(users.balance),
                limit: 10
            });
        }

        if (leaders.length === 0) {
            await interaction.editReply({ embeds: [createWarningEmbed("No users found.", "Leaderboard")] });
            return;
        }

        const embed = getLeaderboardEmbed(leaders, type as 'xp' | 'balance' | 'networth');

        await interaction.editReply({ embeds: [embed] });
    }
});
