process.env.FFMPEG_PATH = require('ffmpeg-static');
const path = require('path');
const fs = require('fs');
const { Client, GatewayIntentBits, Events } = require('discord.js');
const { joinVoiceChannel, createAudioPlayer, createAudioResource, AudioPlayerStatus, NoSubscriberBehavior } = require('@discordjs/voice');
const { CronJob } = require('cron');
const play = require('play-dl');

// Ensure .env is loaded early
require('dotenv').config({ path: path.join(__dirname, '.env') });

// Tambahkan folder ffmpeg ke PATH
const ffmpegDir = path.dirname(process.env.FFMPEG_PATH);
if (!process.env.PATH.includes(ffmpegDir)) {
    process.env.PATH = `${ffmpegDir}${path.delimiter}${process.env.PATH}`;
}

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

const VC_ID = process.env.VC_ID;
const AUDIO_PATH = path.join(__dirname, 'assets/audio/sahur.mp3');
const PREFIX = '!';

// Global state
const queues = new Map(); // guildId -> { queue: [], player, connection }

function logToFile(message) {
    const logMessage = `[${new Date().toISOString()}] ${message}\n`;
    try {
        fs.appendFileSync(path.join(__dirname, 'bot.log'), logMessage);
    } catch (err) {
        console.error('Failed to write to log file:', err);
    }
    console.log(message);
}

client.once(Events.ClientReady, () => {
    console.log('Bot berhasil login!');
    logToFile(`Ready! Logged in as ${client.user.tag}`);
    
    // Sahur Alarm
    const sahurTime = process.env.SAHUR_TIME || '30 03 * * *'; 
    let cronTime = sahurTime;
    if (sahurTime.includes(':') && !sahurTime.includes('*')) {
        const [hour, minute] = sahurTime.split(':');
        cronTime = `0 ${minute} ${hour} * * *`;
    }

    try {
        new CronJob(cronTime, async () => {
            logToFile('Sahur alarm triggered!');
            const guild = client.guilds.cache.first();
            if (!guild) return;
            const channel = guild.channels.cache.get(VC_ID);
            if (channel) {
                playLocal(channel, AUDIO_PATH);
            }
        }, null, true, 'Asia/Jakarta');
        logToFile(`Alarm scheduled at ${cronTime}`);
    } catch (e) {
        logToFile(`Failed to schedule alarm: ${e.message}`);
    }
});

async function playLocal(channel, filePath) {
    try {
        const connection = joinVoiceChannel({
            channelId: channel.id,
            guildId: channel.guild.id,
            adapterCreator: channel.guild.voiceAdapterCreator,
        });

        const player = createAudioPlayer();
        const resource = createAudioResource(filePath);
        player.play(resource);
        connection.subscribe(player);

        player.once(AudioPlayerStatus.Idle, () => {
            connection.destroy();
        });
    } catch (err) {
        logToFile(`Error playing local file: ${err.message}`);
    }
}

client.on(Events.MessageCreate, async (message) => {
    if (message.author.bot || !message.content.startsWith(PREFIX)) return;

    const args = message.content.slice(PREFIX.length).trim().split(/ +/);
    const command = args.shift().toLowerCase();
    const voiceChannel = message.member?.voice.channel;

    try {
        if (command === 'join') {
            if (!voiceChannel) return message.reply('Anda harus berada di voice channel!');
            joinVoiceChannel({
                channelId: voiceChannel.id,
                guildId: message.guild.id,
                adapterCreator: message.guild.voiceAdapterCreator,
            });
            message.reply('Sudah join! 🎧');
        }

        else if (command === 'testsahur') {
            if (!voiceChannel) return message.reply('Anda harus berada di voice channel!');
            if (!fs.existsSync(AUDIO_PATH)) return message.reply(`File audio tidak ditemukan di ${AUDIO_PATH}`);
            playLocal(voiceChannel, AUDIO_PATH);
            message.reply('Memainkan suara sahur... 📢');
        }

        else if (command === 'play') {
            if (!voiceChannel) return message.reply('Anda harus berada di voice channel!');
            const query = args.join(' ');
            if (!query) return message.reply('Berikan link atau nama lagu!');

            let serverQueue = queues.get(message.guild.id);

            if (!serverQueue) {
                serverQueue = {
                    songs: [],
                    connection: null,
                    player: createAudioPlayer({
                        behaviors: { noSubscriber: NoSubscriberBehavior.Play }
                    }),
                };
                queues.set(message.guild.id, serverQueue);
            }

            message.reply('Mencari lagu... 🔍');
            
            let songInfo;
            if (play.sp_validate(query) === 'track') {
                const sp_data = await play.spotify(query);
                const search = await play.search(`${sp_data.name} ${sp_data.artists[0].name}`, { limit: 1 });
                songInfo = { title: sp_data.name, url: search[0].url };
            } else if (play.so_validate(query)) {
                const so_data = await play.soundcloud(query);
                songInfo = { title: so_data.name, url: so_data.url };
            } else {
                const yt_info = await play.search(query, { limit: 1 });
                if (yt_info.length === 0) return message.channel.send('Lagu tidak ditemukan!');
                songInfo = { title: yt_info[0].title, url: yt_info[0].url };
            }

            serverQueue.songs.push(songInfo);

            if (serverQueue.songs.length === 1) {
                playSong(message.guild.id, voiceChannel);
                message.channel.send(`🎵 Sekarang memutar: **${songInfo.title}**`);
            } else {
                message.channel.send(`✅ **${songInfo.title}** ditambahkan ke antrean.`);
            }
        }

        else if (command === 'skip') {
            const serverQueue = queues.get(message.guild.id);
            if (!serverQueue) return message.reply('Tidak ada lagu yang sedang diputar!');
            serverQueue.player.stop();
            message.reply('Lagu dilewati! ⏭️');
        }

        else if (command === 'stop') {
            const serverQueue = queues.get(message.guild.id);
            if (serverQueue) {
                serverQueue.songs = [];
                serverQueue.player.stop();
                if (serverQueue.connection) serverQueue.connection.destroy();
                queues.delete(message.guild.id);
            }
            message.reply('Musik dihentikan. 👋');
        }

        else if (command === 'pause') {
            const serverQueue = queues.get(message.guild.id);
            if (serverQueue) serverQueue.player.pause();
            message.reply('Dipause. ⏸️');
        }

        else if (command === 'resume') {
            const serverQueue = queues.get(message.guild.id);
            if (serverQueue) serverQueue.player.unpause();
            message.reply('Dilanjutkan. ▶️');
        }
    } catch (error) {
        logToFile(`Command Error (${command}): ${error.stack || error.message}`);
        message.reply(`❌ Terjadi kesalahan: ${error.message}`);
    }
});

async function playSong(guildId, channel) {
    const serverQueue = queues.get(guildId);
    if (!serverQueue || serverQueue.songs.length === 0) {
        return;
    }

    try {
        const song = serverQueue.songs[0];
        const stream = await play.stream(song.url);
        const resource = createAudioResource(stream.stream, { inputType: stream.type });

        if (!serverQueue.connection) {
            serverQueue.connection = joinVoiceChannel({
                channelId: channel.id,
                guildId: guildId,
                adapterCreator: channel.guild.voiceAdapterCreator,
            });
            serverQueue.connection.subscribe(serverQueue.player);
        }

        serverQueue.player.play(resource);

        serverQueue.player.once(AudioPlayerStatus.Idle, () => {
            serverQueue.songs.shift();
            playSong(guildId, channel);
        });
    } catch (err) {
        logToFile(`Playback Error: ${err.message}`);
        serverQueue.songs.shift();
        playSong(guildId, channel);
    }
}

// Login at the very bottom
client.login(process.env.DISCORD_TOKEN);
