// src/discordService.js
// Discord bot client initialization and role management functions

const { Client, GatewayIntentBits } = require('discord.js');
const rolesConfig = require('../config/roles.json');

const client = new Client({
    intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers]
});

// Initialize the Discord bot login
client.login(process.env.DISCORD_BOT_TOKEN);

client.on('ready', () => {
    console.log(`[Discord] Bot logged in as ${client.user.tag}`);
});

/**
 * Assign a Discord role to a user based on their subscription tier
 * @param {string} userId - Discord user ID (snowflake)
 * @param {string} tier - Subscription tier name (e.g., 'awakened', 'fire_elemental')
 * @returns {Promise<boolean>} - Success status
 */
async function assignDiscordRole(userId, tier) {
    try {
        const guild = client.guilds.cache.get(process.env.GUILD_ID);
        if (!guild) throw new Error('Guild not found.');

        // Fetch the member. If they aren't in the server, this throws an error.
        const member = await guild.members.fetch(userId);
        
        const roleId = rolesConfig[tier];
        if (!roleId) throw new Error(`No role mapping found for tier: ${tier}`);

        const role = guild.roles.cache.get(roleId);
        if (!role) throw new Error(`Role ID ${roleId} not found in server.`);

        await member.roles.add(role);
        console.log(`[Discord] Assigned role ${tier} to user ${userId}`);
        return true;
    } catch (error) {
        console.error(`[Discord] Failed to assign role to ${userId}:`, error.message);
        return false;
    }
}

/**
 * Remove all subscription roles from a user (used for cancellations or before upgrades)
 * @param {string} userId - Discord user ID (snowflake)
 * @returns {Promise<boolean>} - Success status
 */
async function removeAllSubscriptionRoles(userId) {
    try {
        const guild = client.guilds.cache.get(process.env.GUILD_ID);
        if (!guild) throw new Error('Guild not found.');

        const member = await guild.members.fetch(userId);
        
        // Extract all role IDs from the config
        const allRoleIds = Object.values(rolesConfig);
        
        // discord.js allows removing an array of role IDs at once
        await member.roles.remove(allRoleIds);
        console.log(`[Discord] Removed all subscription roles from ${userId}`);
        return true;
    } catch (error) {
        console.error(`[Discord] Failed to remove roles for ${userId}:`, error.message);
        throw error;
    }
}

/**
 * Update subscription roles (remove old, add new) - used for tier changes
 * @param {string} userId - Discord user ID
 * @param {string|null} newTier - New tier name, or null for cancellation
 */
async function updateSubscriptionRoles(userId, newTier = null) {
    try {
        const guild = client.guilds.cache.get(process.env.GUILD_ID);
        const member = await guild.members.fetch(userId);
        
        // 1. Remove ALL possible subscription roles
        const allRoleIds = Object.values(rolesConfig);
        await member.roles.remove(allRoleIds);

        // 2. Add the new role (if not cancelled)
        if (newTier && rolesConfig[newTier]) {
            const newRole = guild.roles.cache.get(rolesConfig[newTier]);
            if (newRole) await member.roles.add(newRole);
        }
        
        console.log(`[Discord] Updated roles for ${userId} to ${newTier || 'none'}`);
    } catch (error) {
        console.error(`[Discord] Role update failed for ${userId}:`, error);
    }
}

module.exports = { 
    client, 
    rolesConfig, 
    assignDiscordRole, 
    removeAllSubscriptionRoles,
    updateSubscriptionRoles
};
