const { SlashCommandBuilder, PermissionFlagsBits, ChannelType, EmbedBuilder } = require('discord.js');
const logger = require('../utils/logger');
// Removed direct import of musicPlayer

module.exports = {
    data: new SlashCommandBuilder()
        .setName('play')
        .setDescription('Plays audio from a URL or search query')
        .addStringOption(option =>
            option.setName('query')
                .setDescription('The URL or search term for the song/playlist')
                .setRequired(true))
        .addStringOption(option =>
            option.setName('source')
                .setDescription('Specify the search source (defaults to YouTube Music)')
                .setRequired(false)
                .addChoices(
                    { name: 'YouTube Music', value: 'youtubemusic' },
                    { name: 'YouTube', value: 'youtube' },
                    { name: 'SoundCloud', value: 'soundcloud' }
                )),
    async execute(interaction, client) {
        await interaction.deferReply(); // Defer reply immediately

        const member = interaction.member;
        const voiceChannel = member?.voice?.channel;
        const query = interaction.options.getString('query');
        const source = interaction.options.getString('source'); // Get the source option

        // 1. Check if user is in a voice channel
        if (!voiceChannel) {
            return interaction.editReply('You need to be in a voice channel to play music!');
        }

        // 2. Check bot permissions
        const permissions = voiceChannel.permissionsFor(client.user);
        if (!permissions.has(PermissionFlagsBits.Connect)) {
            return interaction.editReply('I need permission to **connect** to your voice channel!');
        }
        if (!permissions.has(PermissionFlagsBits.Speak)) {
            return interaction.editReply('I need permission to **speak** in your voice channel!');
        }
        if (voiceChannel.type !== ChannelType.GuildVoice) {
            return interaction.editReply('I can only join standard voice channels.');
        }

        try {
            // Get the initialized player from the client object
            const musicPlayer = interaction.client.player;
            if (!musicPlayer) {
                logger.error('Music player not initialized on client object!');
                return interaction.editReply('The music player is not ready yet. Please try again shortly.');
            }

            // 3. Get or create player
            let player = musicPlayer.getPlayer(interaction.guildId);
            if (!player) {
                try {
                    player = await musicPlayer.createPlayer({
                        guildId: interaction.guildId,
                        textChannel: interaction.channelId, // Use interaction.channelId directly
                        voiceChannel: voiceChannel.id // Use voiceChannel.id directly
                    });
                    logger.info(`Created player and connected to voice channel ${voiceChannel.name} (${voiceChannel.id}) for play command.`);
                } catch (error) {
                    logger.error(`Failed to create/connect player for guild ${interaction.guildId} during play command: ${error.message}`);
                    return interaction.editReply('An error occurred while trying to join the voice channel.');
                }
            } else if (player.voiceChannel !== voiceChannel.id) {
                // If player exists but in a different voice channel, destroy it and create a new one
                player.destroy();
                player = await musicPlayer.createPlayer({
                    guildId: interaction.guildId,
                    textChannel: interaction.channelId,
                    voiceChannel: voiceChannel.id
                });
                logger.info(`Moved player to voice channel ${voiceChannel.name} (${voiceChannel.id}) for play command.`);
            }

            // 4. Determine search identifier based on query and source
            let identifier;
            const isUrl = query.startsWith('http://') || query.startsWith('https://');

            if (isUrl) {
                identifier = query; // Use URL directly
            } else {
                // Prepend search prefix based on source or default
                switch (source) {
                    case 'youtube':
                        identifier = `ytsearch:${query}`;
                        break;
                    case 'soundcloud':
                        identifier = `scsearch:${query}`;
                        break;
                    case 'youtubemusic':
                    default: // Default to YouTube Music if source is 'youtubemusic' or not provided
                        identifier = `ytmsearch:${query}`;
                        break;
                }
            }
            logger.debug(`Constructed identifier: ${identifier}`);

            // 5. Search for tracks using the constructed identifier
            const searchResults = await musicPlayer.search({ // Use the player instance from the client
                identifier: identifier, // Pass the constructed identifier
                requester: interaction.user
            });

            if (!searchResults || searchResults.length === 0) {
                await interaction.editReply(`No results found for "${query}".`);
                if (!player.playing && player.queue.length === 0) {
                    player.destroy();
                }
                return;
            }

            // 6. Add track(s) to queue and create response embed
            const responseEmbed = new EmbedBuilder().setColor('#0099ff');

            // Add first track (or all tracks if it's a playlist)
            const firstTrack = searchResults[0];
            
            // Detect if it's a playlist based on number of tracks
            const isPlaylist = searchResults.length > 1 && 
                               searchResults[0].info.uri.includes('playlist');
            
            if (isPlaylist) {
                // Add all tracks to the queue
                for (const track of searchResults) {
                    await player.enqueue(track);
                }
                
                // Set up playlist embed
                responseEmbed
                    .setTitle('Playlist Added to Queue')
                    .setDescription(`**Playlist** (${searchResults.length} tracks)`)
                    .addFields({ name: 'Starting track', value: `[${firstTrack.info.title}](${firstTrack.info.uri})` });
                
                logger.info(`Added playlist with ${searchResults.length} tracks to queue (Guild: ${interaction.guildId})`);
            } else {
                // Add single track to queue
                await player.enqueue(firstTrack);
                
                // Set up track embed
                responseEmbed
                    .setTitle('Track Added to Queue')
                    .setDescription(`[${firstTrack.info.title}](${firstTrack.info.uri})`)
                    .addFields({ name: 'Position in queue', value: `${player.queue.length}`, inline: true });
                
                // Add thumbnail if available
                if (firstTrack.info.thumbnail) {
                    responseEmbed.setThumbnail(firstTrack.info.thumbnail);
                }
                
                logger.info(`Added track to queue: ${firstTrack.info.title} (Guild: ${interaction.guildId})`);
            }
            
            // Send response
            await interaction.editReply({ embeds: [responseEmbed] });
            
        } catch (error) {
            logger.error(`Error during search/play for query "${query}" in guild ${interaction.guildId}: ${error.message}`);
            await interaction.editReply('An unexpected error occurred while trying to play the music.').catch(e => 
                logger.error(`Failed to send error reply for play command: ${e.message}`)
            );
        }
        
        logger.info(`Executed command 'play' for user ${interaction.user.tag}`);
    },
};
