require('dotenv').config();
const { REST, Routes } = require('discord.js');
const chalk = require('chalk');
const fs = require('node:fs');
const path = require('node:path');

const { token, clientId, CLIENT_ID, GUILD_ID } = process.env;
const finalClientId = clientId || CLIENT_ID;
const guildId = GUILD_ID;

if (!token) {
	console.error(chalk.red('❌ Le TOKEN n\'est pas défini dans les variables d\'environnement !'));
	console.error(chalk.yellow('💡 Ajoute TOKEN=ton_token dans ton fichier .env'));
	process.exit(1);
}

if (!finalClientId) {
	console.error(chalk.red('❌ Le CLIENT_ID n\'est pas défini dans les variables d\'environnement !'));
	console.error(chalk.yellow('💡 Pour obtenir ton CLIENT_ID:'));
	console.error(chalk.yellow('   1. Va sur https://discord.com/developers/applications'));
	console.error(chalk.yellow('   2. Sélectionne ton application'));
	console.error(chalk.yellow('   3. Va dans l\'onglet "General Information"'));
	console.error(chalk.yellow('   4. Copie "Application ID"'));
	console.error(chalk.yellow('   5. Ajoute CLIENT_ID=ton_client_id dans ton fichier .env'));
	process.exit(1);
}

const commands = [];
const commandsByCategory = new Map(); // Map pour stocker les commandes par catégorie
const foldersPath = path.join(__dirname, 'commands');
const commandFolders = fs.readdirSync(foldersPath);

for (const folder of commandFolders) {
	const commandsPath = path.join(foldersPath, folder);
	const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
	for (const file of commandFiles) {
		const filePath = path.join(commandsPath, file);
		const command = require(filePath);
		if ('data' in command && 'execute' in command) {
			const commandData = command.data.toJSON();
			const category = command.category || folder || 'other';
			
			// Ajouter à la liste des commandes
			commands.push(commandData);
			
			// Ajouter à la map par catégorie
			if (!commandsByCategory.has(category)) {
				commandsByCategory.set(category, []);
			}
			commandsByCategory.get(category).push({
				name: commandData.name,
				description: commandData.description,
				data: commandData
			});
		} else {
			console.warn(chalk.yellow(`⚠️  La commande à ${filePath} manque une propriété requise "data" ou "execute".`));
		}
	}
}

const rest = new REST().setToken(token);

(async () => {
	try {
		console.log(chalk.blue(`🔄 Déploiement de ${commands.length} commande(s) application (/)...`));
		console.log(chalk.cyan('\n📋 Commandes à déployer par catégorie:'));
		
		// Trier les catégories par ordre alphabétique
		const sortedCategories = Array.from(commandsByCategory.keys()).sort();
		
		for (const category of sortedCategories) {
			const categoryCommands = commandsByCategory.get(category);
			console.log(chalk.magenta(`\n   📁 ${category.toUpperCase()} (${categoryCommands.length} commande(s)):`));
			categoryCommands.forEach(cmd => {
				console.log(chalk.gray(`      - /${cmd.name} - ${cmd.description}`));
			});
		}

		// Déployer sur une guild spécifique si GUILD_ID est défini (plus rapide pour tester)
		// Si GUILD_ID est défini, on déploie SEULEMENT sur la guild (pas de global pour éviter les doublons)
		if (guildId) {
			console.log(chalk.yellow(`\n📍 Déploiement sur la guild: ${guildId} (uniquement)`));
			console.log(chalk.gray('   (Pas de déploiement global pour éviter les doublons)'));
			const guildData = await rest.put(
				Routes.applicationGuildCommands(finalClientId, guildId),
				{ body: commands },
			);
			console.log(chalk.green(`✅ ${guildData.length} commande(s) déployée(s) sur la guild avec succès !`));
			console.log(chalk.cyan('💡 Les commandes sont disponibles immédiatement sur cette guild uniquement.'));
			console.log(chalk.yellow('💡 Pour déployer globalement, retire GUILD_ID du .env et relance le script.'));
		} else {
			// Déployer globalement seulement si pas de GUILD_ID
			console.log(chalk.yellow(`\n🌍 Déploiement global (tous les serveurs)...`));
			const globalData = await rest.put(
				Routes.applicationCommands(finalClientId),
				{ body: commands },
			);
			console.log(chalk.green(`✅ ${globalData.length} commande(s) globale(s) rechargée(s) avec succès !`));
			console.log(chalk.yellow('\n💡 Note: Les commandes globales peuvent prendre 1-2h à apparaître sur Discord.'));
			console.log(chalk.yellow('   Pour un déploiement plus rapide sur une guild, ajoute GUILD_ID=ton_guild_id dans .env'));
			console.log(chalk.yellow('   Si elles n\'apparaissent pas après 2h, redémarre Discord (Ctrl+R).'));
		}

		// Afficher les commandes déployées par catégorie
		console.log(chalk.blue('\n📝 Commandes déployées par catégorie:'));
		
		for (const category of sortedCategories) {
			const categoryCommands = commandsByCategory.get(category);
			console.log(chalk.magenta(`\n   📁 ${category.toUpperCase()} (${categoryCommands.length} commande(s)):`));
			categoryCommands.forEach((cmd, index) => {
				console.log(chalk.gray(`      ${index + 1}. /${cmd.name} - ${cmd.description}`));
			});
		}

	} catch (error) {
		console.error(chalk.red('\n❌ Erreur lors du déploiement des commandes:'));
		console.error(chalk.red(`   Code: ${error.code || 'N/A'}`));
		console.error(chalk.red(`   Message: ${error.message || error}`));
		
		if (error.code === 50001) {
			console.error(chalk.red('\n   Le bot n\'a pas été trouvé. Vérifie que CLIENT_ID est correct dans .env'));
		} else if (error.code === 50013) {
			console.error(chalk.red('\n   Le bot n\'a pas les permissions nécessaires dans cette guild.'));
		} else if (error.code === 50035) {
			console.error(chalk.red('\n   Erreur de validation. Une commande a un format invalide.'));
			if (error.body?.errors) {
				console.error(chalk.red('   Détails:'));
				console.error(JSON.stringify(error.body.errors, null, 2));
			}
		} else if (error.rawError) {
			console.error(chalk.red('\n   Détails complets:'));
			console.error(JSON.stringify(error.rawError, null, 2));
		}
		
		if (error.requestBody) {
			console.error(chalk.yellow('\n   Corps de la requête:'));
			console.error(JSON.stringify(error.requestBody, null, 2));
		}
		
		process.exit(1);
	}
})();