const { ActionRowBuilder, ButtonBuilder, ButtonStyle, EmbedBuilder } = require('discord.js');
const EmbedBuilders = require('../utils/embedBuilders');

class CommandHandler {
    constructor(playerService, supabase, logger, serverRegistrationService, subscriptionCommands) {
        this.playerService = playerService;
        this.supabase = supabase;
        this.logger = logger;
        this.serverRegistrationService = serverRegistrationService;
        this.subscriptionCommands = subscriptionCommands;
    }

    async handleCommand(interaction) {
        try {
            switch (interaction.commandName) {
                case 'register_server':
                    await this.handleRegisterServer(interaction);
                    break;
                case 'ping':
                    await interaction.editReply({ content: 'Pong!', ephemeral: true });
                    break;
                case 'finduser':
                    await this.handleFindUser(interaction);
                    break;
                case 'matchhistory':
                    await this.handleMatchHistory(interaction);
                    break;
                case 'subscribe':
                    await this.subscriptionCommands.handleSubscribe(interaction);
                    break;
                case 'unsubscribe':
                    await this.subscriptionCommands.handleUnsubscribe(interaction);
                    break;
                case 'list_subscriptions':
                    await this.subscriptionCommands.handleListSubscriptions(interaction);
                    break;
                case 'findteam':
                    await this.handleFindTeam(interaction);
                    break;
                default:
                    await interaction.editReply({ 
                        content: '❌ Unknown command', 
                        ephemeral: true 
                    });
            }
        } catch (error) {
            this.logger.error('Command handling error:', {
                command: interaction.commandName,
                error: error.message,
                stack: error.stack
            });

            try {
                await interaction.editReply({
                    content: '❌ An error occurred while processing your command.',
                    ephemeral: true
                });
            } catch (followUpError) {
                this.logger.error('Failed to send error response:', {
                    error: followUpError.message,
                    originalError: error.message
                });
            }
        }
    }

    async handleRegisterServer(interaction) {
        try {
            // Check for admin permissions
            if (!interaction.member.permissions.has('ADMINISTRATOR')) {
                await interaction.editReply({
                    content: '❌ You need administrator permissions to register this server.',
                    ephemeral: true
                });
                return;
            }

            const guildId = interaction.guildId;
            const serverName = interaction.guild.name;
            
            this.logger.debug('Starting server registration', {
                guildId,
                serverName,
                timestamp: new Date().toISOString()
            });

            // Attempt the database operation
            const result = await this.serverRegistrationService.registerServer(guildId, serverName);
            
            // Log the result
            this.logger.debug('Server registration result received', {
                status: result.status,
                serverId: result.server?.id,
                guildId,
                timestamp: new Date().toISOString()
            });

            // Prepare response message based on status
            let message;
            switch (result.status) {
                case 'created':
                    message = '✅ Server successfully registered! You can now use subscription commands.';
                    break;
                case 'updated':
                    message = '✅ Server information has been updated!';
                    break;
                case 'exists':
                    message = '✅ This server is already registered and ready to use subscription commands!';
                    break;
                default:
                    message = '❌ An unexpected error occurred during registration.';
            }

            await interaction.editReply({ 
                content: message,
                ephemeral: true 
            });

            // Log the successful operation
            this.logger.info('Server registration completed', {
                status: result.status,
                guildId,
                serverId: result.server.id,
                timestamp: new Date().toISOString()
            });

        } catch (error) {
            this.logger.error('Error in handleRegisterServer:', {
                error: error.message,
                stack: error.stack,
                guildId: interaction.guildId,
                serverName: interaction.guild?.name
            });

            // Send error message to user
            const errorMessage = error.message === 'Invalid guildId provided' || error.message === 'Invalid serverName provided'
                ? '❌ Invalid server information provided.'
                : '❌ An error occurred while registering the server. Please try again later.';

            await interaction.editReply({
                content: errorMessage,
                ephemeral: true
            });

            throw error;
        }
    }

    async handleFindUser(interaction) {
        try {
            const username = interaction.options.getString('username');
            const gameFilter = interaction.options.getString('game');

            // Input validation
            if (!username || typeof username !== 'string') {
                await interaction.editReply({
                    content: '❌ Invalid username provided.'
                });
                return;
            }

            // Enhanced sanitization
            const sanitizedUsername = username
                .replace(/[^a-zA-Z0-9\s\-_.]/g, '')
                .trim()
                .slice(0, 100);

            if (!sanitizedUsername) {
                await interaction.editReply({
                    content: '❌ Username must contain valid characters (letters, numbers, spaces, hyphens, underscores, or periods).'
                });
                return;
            }

            // Log sanitized input for monitoring
            this.logger.debug('User search input:', {
                original: username,
                sanitized: sanitizedUsername,
                game: gameFilter,
                userId: interaction.user.id,
                timestamp: new Date().toISOString()
            });

            const userData = await this.playerService.findUserByUsername(sanitizedUsername);
            if (!userData || !userData.success) {
                await interaction.editReply({
                    content: '❌ User not found or an error occurred while fetching data.'
                });
                return;
            }

            const playerData = typeof userData.player_data === 'string'
                ? JSON.parse(userData.player_data)
                : userData.player_data;

            // Check if the user is on a team for the specified game
            const isOnTeam = playerData.teams && Object.values(playerData.teams)
                .some(team => team.game_name === gameFilter);

            // Check if the user has played the specified game
            const hasPlayedGame = playerData.stats?.games && 
                Object.keys(playerData.stats.games)
                    .some(game => game.toLowerCase() === gameFilter.toLowerCase());

            if (!hasPlayedGame) {
                const teamMessage = isOnTeam ? 
                    `\nThey are on a team for ${gameFilter} but haven't played any matches yet.` : 
                    '';

                // Create a basic embed with user info
                const basicEmbed = new EmbedBuilder()
                    .setTitle(`User: ${playerData.username || 'Unknown'}`)
                    .setDescription(playerData.profile?.bio || 'No bio available')
                    .setColor('#0099ff');

                // Add avatar if available
                if (playerData.profile?.avatar) {
                    basicEmbed.setThumbnail(
                        `https://www.vrbattles.gg/assets/uploads/profile/${playerData.profile.avatar}`
                    );
                }

                // Add badge image if available
                if (playerData.profile?.current_level_badge) {
                    const badgeImageUrl = this.playerService.getBadgeImageUrl(playerData.profile.current_level_badge);
                    basicEmbed.setImage(badgeImageUrl);
                } else {
                    basicEmbed.setImage('https://www.vrbattles.gg/assets/images/Qubi/vrwearcubesatad.png');
                }

                // Add basic profile fields
                const profileFields = [];
                const profile = playerData.profile || {};
                if (profile.country) profileFields.push({ name: 'Country', value: profile.country, inline: true });
                if (profile.level) profileFields.push({ name: 'Level', value: profile.level.toString(), inline: true });
                if (profile.xp) profileFields.push({ name: 'Total XP', value: profile.xp.toString(), inline: true });
                if (profile.prestige) profileFields.push({ name: 'Prestige', value: profile.prestige.toString(), inline: true });

                if (profileFields.length > 0) {
                    basicEmbed.addFields(profileFields);
                }

                // Add message about no game stats
                basicEmbed.addFields({
                    name: `${gameFilter} Status`,
                    value: `❌ No match history found for ${gameFilter}${teamMessage}`
                });

                const row = this.createActionRow(playerData.username);

                await interaction.editReply({
                    embeds: [basicEmbed],
                    components: [row]
                });
                return;
            }

            const embed = EmbedBuilders.createUserEmbed(playerData, gameFilter, this.playerService);
            const row = this.createActionRow(playerData.username);

            await interaction.editReply({
                embeds: [embed],
                components: [row]
            });
        } catch (error) {
            this.logger.error('Error in handleFindUser:', {
                error: error.message,
                username: interaction.options.getString('username'),
                game: interaction.options.getString('game'),
                userId: interaction.user.id,
                timestamp: new Date().toISOString()
            });
            await interaction.editReply({
                content: '❌ An error occurred while searching for the user.'
            });
        }
    }

    async handleMatchHistory(interaction) {
        try {
            const username = interaction.options.getString('username');
            const gameFilter = interaction.options.getString('game');

            const userData = await this.playerService.findUserByUsername(username);
            if (!userData || !userData.success) {
                await interaction.editReply({
                    content: '❌ User not found or an error occurred while fetching data.',
                });
                return;
            }

            const playerData = typeof userData.player_data === 'string'
                ? JSON.parse(userData.player_data)
                : userData.player_data;

            // Extract matches from player data
            const matches = Object.values(playerData.matches || {})
                .filter(match => !gameFilter || match.game_name.toLowerCase() === gameFilter.toLowerCase())
                .sort((a, b) => new Date(b.start_time) - new Date(a.start_time))
                .slice(0, 10);

            const embed = EmbedBuilders.createMatchHistoryEmbed(playerData, matches);
            const row = EmbedBuilders.createActionRow(playerData.username, this.playerService);

            await interaction.editReply({
                embeds: [embed],
                components: [row],
            });
        } catch (error) {
            this.logger.error('Error in handleMatchHistory:', {
                error: error.message,
                username: interaction.options.getString('username'),
                timestamp: new Date().toISOString()
            });
            throw error;
        }
    }

    async handleFindTeam(interaction) {
        try {
            const teamName = interaction.options.getString('teamname');
            const gameFilter = interaction.options.getString('game');

            // Input validation
            if (!teamName || typeof teamName !== 'string') {
                await interaction.editReply({
                    content: '❌ Invalid team name provided.',
                    ephemeral: false
                });
                return;
            }

            // Enhanced sanitization
            const sanitizedTeamName = teamName
                .replace(/[^a-zA-Z0-9\s\-_.]/g, '')
                .trim()
                .slice(0, 100);

            if (!sanitizedTeamName) {
                await interaction.editReply({
                    content: '❌ Team name must contain valid characters (letters, numbers, spaces, hyphens, underscores, or periods).',
                    ephemeral: false
                });
                return;
            }

            // Log sanitized input for monitoring
            this.logger.debug('Team search input:', {
                original: teamName,
                sanitized: sanitizedTeamName,
                game: gameFilter,
                userId: interaction.user.id,
                timestamp: new Date().toISOString()
            });

            const teamData = await this.playerService.findTeamByName(sanitizedTeamName, gameFilter);
            
            if (!teamData || !teamData.success || !teamData.teams || teamData.teams.length === 0) {
                await interaction.editReply({
                    content: '❌ No teams found matching your search criteria.',
                    ephemeral: false
                });
                return;
            }

            const embeds = EmbedBuilders.createTeamEmbed(teamData.teams);

            await interaction.editReply({
                embeds: embeds,
                components: [],
                ephemeral: false
            });
        } catch (error) {
            this.logger.error('Error in handleFindTeam:', {
                error: error.message,
                teamName: interaction.options.getString('teamname'),
                game: interaction.options.getString('game'),
                userId: interaction.user.id,
                timestamp: new Date().toISOString()
            });
            await interaction.editReply({
                content: '❌ An error occurred while searching for teams.',
                ephemeral: false
            });
        }
    }

    createActionRow(username) {
        return new ActionRowBuilder().addComponents(
            new ButtonBuilder()
                .setLabel('🔵 View Profile')
                .setStyle(ButtonStyle.Link)
                .setURL(`https://www.vrbattles.gg/profile/${username}`)
        );
    }
}

module.exports = CommandHandler;