import { ButtonInteraction, MessageFlags } from "discord.js";
import { config } from "@/lib/config";
import { getEnrollmentSuccessMessage } from "./enrollment.view";
import { classService } from "@modules/class/class.service";
import { userService } from "@modules/user/user.service";
import { UserError } from "@/lib/errors";
import { sendWebhookMessage } from "@/lib/webhookUtils";

export async function handleEnrollmentInteraction(interaction: ButtonInteraction) {
    if (!interaction.inCachedGuild()) {
        throw new UserError("This action can only be performed in a server.");
    }

    const { studentRole, visitorRole } = config;

    if (!studentRole || !visitorRole) {
        throw new UserError("No student or visitor role configured for enrollment.");
    }

    // 1. Ensure user exists in DB and check current enrollment status
    const user = await userService.getOrCreateUser(interaction.user.id, interaction.user.username);
    if (!user) {
        throw new UserError("User profiles could not be loaded. Please try again later.");
    }

    // Check DB enrollment
    if (user.class) {
        throw new UserError("You are already enrolled in a class.");
    }

    const member = interaction.member;

    // Check Discord role enrollment (Double safety)
    if (member.roles.cache.has(studentRole)) {
        throw new UserError("You already have the student role.");
    }

    // 2. Get available classes
    const allClasses = await classService.getAllClasses();
    const validClasses = allClasses.filter(c => c.roleId);

    if (validClasses.length === 0) {
        throw new UserError("No classes with specified roles found in database.");
    }

    // 3. Pick random class
    const selectedClass = validClasses[Math.floor(Math.random() * validClasses.length)]!;
    const classRoleId = selectedClass.roleId!;

    // Check if the role exists in the guild
    const classRole = interaction.guild.roles.cache.get(classRoleId);
    if (!classRole) {
        throw new UserError(`The configured role ID \`${classRoleId}\` for class **${selectedClass.name}** does not exist in this server.`);
    }

    // 4. Perform Enrollment Actions
    await member.roles.remove(visitorRole);
    await member.roles.add(studentRole);
    await member.roles.add(classRole);

    // Persist to DB
    await classService.assignClass(user.id.toString(), selectedClass.id);

    await interaction.reply({
        ...getEnrollmentSuccessMessage(classRole.name),
        flags: MessageFlags.Ephemeral
    });

    // 5. Send Welcome Message (if configured)
    if (config.welcomeChannelId) {
        const welcomeChannel = interaction.guild.channels.cache.get(config.welcomeChannelId);
        if (welcomeChannel && welcomeChannel.isTextBased()) {
            const rawMessage = config.welcomeMessage || "Welcome to Aurora, {user}! You have been enrolled as a **{class}**.";

            const processedMessage = rawMessage
                .replace(/{user}/g, member.toString())
                .replace(/{username}/g, member.user.username)
                .replace(/{class}/g, selectedClass.name)
                .replace(/{guild}/g, interaction.guild.name);

            let payload;
            try {
                payload = JSON.parse(processedMessage);
            } catch {
                payload = processedMessage;
            }

            // Fire and forget webhook
            sendWebhookMessage(welcomeChannel, payload, interaction.client.user, "New Student Enrollment")
                .catch((err: any) => console.error("Failed to send welcome message:", err));
        }
    }
}