import {
  ActionRowBuilder,
  ButtonBuilder,
  ButtonStyle,
  ChannelType,
  Client,
  EmbedBuilder,
  Events,
  GatewayIntentBits,
  PermissionFlagsBits
} from 'discord.js';
import { env } from '../config/env.js';
import { addAuditLog, getGuildSettings, saveGuildSettings } from '../database/repositories.js';

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

function parseColor(input: string | null): number {
  const cleaned = (input ?? '#7c5cff').replace('#', '');
  return /^[0-9a-fA-F]{6}$/.test(cleaned) ? Number.parseInt(cleaned, 16) : 0x7c5cff;
}

client.once(Events.ClientReady, ready => {
  console.log(`VX BOT connecté : ${ready.user.tag} — ${ready.guilds.cache.size} serveur(s)`);
  ready.user.setActivity('les créations de VX GAMES');
});

async function sendGuildLog(guildId: string, embed: EmbedBuilder) {
  const settings = getGuildSettings(guildId);
  if (!settings.logChannelId) return;
  const guild = client.guilds.cache.get(guildId);
  const channel = guild?.channels.cache.get(settings.logChannelId);
  if (channel?.isTextBased() && !channel.isDMBased()) {
    await channel.send({ embeds: [embed] }).catch(error => console.error('Log Discord impossible :', error));
  }
}

client.on(Events.GuildMemberAdd, async member => {
  const settings = getGuildSettings(member.guild.id);

  if (settings.autoRoleId) {
    const role = member.guild.roles.cache.get(settings.autoRoleId);
    if (role && member.guild.members.me?.permissions.has(PermissionFlagsBits.ManageRoles)) {
      await member.roles.add(role).catch(error => console.error('Autorôle impossible :', error));
    }
  }

  await sendGuildLog(member.guild.id, new EmbedBuilder()
    .setColor(0x55e6a5)
    .setTitle('Membre arrivé')
    .setDescription(`<@${member.id}> a rejoint le serveur.`)
    .setFooter({ text: `ID : ${member.id}` })
    .setTimestamp());

  if (!settings.welcomeEnabled || !settings.welcomeChannelId) return;
  const channel = member.guild.channels.cache.get(settings.welcomeChannelId);
  if (!channel || channel.type !== ChannelType.GuildText) return;

  const description = settings.welcomeMessage
    .replaceAll('{user}', `<@${member.id}>`)
    .replaceAll('{server}', member.guild.name)
    .replaceAll('{count}', String(member.guild.memberCount));

  const embed = new EmbedBuilder()
    .setColor(0x7c5cff)
    .setAuthor({ name: 'VX GAMES • Nouveau membre', iconURL: member.guild.iconURL() ?? undefined })
    .setDescription(description)
    .setThumbnail(member.user.displayAvatarURL({ size: 256 }))
    .setFooter({ text: `Membre n°${member.guild.memberCount}` })
    .setTimestamp();

  await channel.send({ embeds: [embed] }).catch(error => console.error('Message d’accueil impossible :', error));
});

client.on(Events.InteractionCreate, async interaction => {
  if (interaction.isButton() && interaction.customId.startsWith('vxrole:')) {
    if (!interaction.inCachedGuild()) return;
    const roleId = interaction.customId.slice('vxrole:'.length);
    const role = interaction.guild.roles.cache.get(roleId);
    if (!role) return interaction.reply({ content: 'Ce rôle n’existe plus.', ephemeral: true });

    const member = interaction.member;
    const hasRole = member.roles.cache.has(roleId);
    try {
      if (hasRole) {
        await member.roles.remove(role);
        await interaction.reply({ content: `Le rôle **${role.name}** a été retiré.`, ephemeral: true });
      } else {
        await member.roles.add(role);
        await interaction.reply({ content: `Le rôle **${role.name}** a été ajouté.`, ephemeral: true });
      }
    } catch {
      await interaction.reply({
        content: 'Je ne peux pas gérer ce rôle. Place VX BOT au-dessus de celui-ci dans la hiérarchie.',
        ephemeral: true
      });
    }
    return;
  }

  if (!interaction.isChatInputCommand()) return;

  if (interaction.commandName === 'vxbot') {
    const embed = new EmbedBuilder()
      .setColor(0x7c5cff)
      .setTitle('VX BOT — Système opérationnel')
      .setDescription('Le bot officiel de **VX GAMES** est connecté et prêt.')
      .addFields(
        { name: 'Latence', value: `${client.ws.ping} ms`, inline: true },
        { name: 'Serveurs', value: String(client.guilds.cache.size), inline: true },
        { name: 'Version', value: '0.1.0', inline: true }
      )
      .setTimestamp();
    await interaction.reply({ embeds: [embed], ephemeral: true });
    return;
  }

  if (interaction.commandName === 'embed') {
    const requestedChannel = interaction.options.getChannel('salon', true);
    const channel = interaction.guild?.channels.cache.get(requestedChannel.id);
    const title = interaction.options.getString('titre', true);
    const description = interaction.options.getString('description', true);
    const color = parseColor(interaction.options.getString('couleur'));

    if (!channel?.isTextBased() || channel.isDMBased()) {
      await interaction.reply({ content: 'Salon invalide.', ephemeral: true });
      return;
    }

    const embed = new EmbedBuilder()
      .setColor(color)
      .setAuthor({ name: 'VX GAMES', iconURL: interaction.guild?.iconURL() ?? undefined })
      .setTitle(title)
      .setDescription(description)
      .setFooter({ text: `Publié par ${interaction.user.username}` })
      .setTimestamp();

    await channel.send({ embeds: [embed] });
    await interaction.reply({ content: `Embed publié dans <#${channel.id}>.`, ephemeral: true });
    return;
  }

  if (interaction.commandName === 'clear') {
    if (!interaction.inCachedGuild() || !interaction.channel?.isTextBased() || interaction.channel.isDMBased() || !('bulkDelete' in interaction.channel)) {
      await interaction.reply({ content: 'Cette commande doit être utilisée dans un salon textuel.', ephemeral: true });
      return;
    }
    const amount = interaction.options.getInteger('nombre', true);
    const deleted = await interaction.channel.bulkDelete(amount, true);
    addAuditLog({
      guildId: interaction.guildId,
      actorId: interaction.user.id,
      actorName: interaction.user.username,
      action: 'Messages supprimés',
      details: `${deleted.size} message(s) dans #${interaction.channel.name}`
    });
    await interaction.reply({ content: `${deleted.size} message(s) supprimé(s).`, ephemeral: true });
    return;
  }

  if (interaction.commandName === 'kick') {
    if (!interaction.inCachedGuild()) return;
    const user = interaction.options.getUser('membre', true);
    const reason = interaction.options.getString('raison') ?? `Action de ${interaction.user.username}`;
    const member = await interaction.guild.members.fetch(user.id).catch(() => null);
    if (!member?.kickable) {
      await interaction.reply({ content: 'Je ne peux pas expulser ce membre. Vérifie la hiérarchie des rôles.', ephemeral: true });
      return;
    }
    await member.kick(reason);
    addAuditLog({ guildId: interaction.guildId, actorId: interaction.user.id, actorName: interaction.user.username, action: 'Membre expulsé', details: `${user.username} — ${reason}` });
    await sendGuildLog(interaction.guildId, new EmbedBuilder().setColor(0xffb454).setTitle('Membre expulsé').setDescription(`**${user.username}** a été expulsé.\nRaison : ${reason}`).setTimestamp());
    await interaction.reply({ content: `**${user.username}** a été expulsé.`, ephemeral: true });
    return;
  }

  if (interaction.commandName === 'ban') {
    if (!interaction.inCachedGuild()) return;
    const user = interaction.options.getUser('membre', true);
    const reason = interaction.options.getString('raison') ?? `Action de ${interaction.user.username}`;
    const member = await interaction.guild.members.fetch(user.id).catch(() => null);
    if (member && !member.bannable) {
      await interaction.reply({ content: 'Je ne peux pas bannir ce membre. Vérifie la hiérarchie des rôles.', ephemeral: true });
      return;
    }
    await interaction.guild.members.ban(user.id, { reason });
    addAuditLog({ guildId: interaction.guildId, actorId: interaction.user.id, actorName: interaction.user.username, action: 'Membre banni', details: `${user.username} — ${reason}` });
    await sendGuildLog(interaction.guildId, new EmbedBuilder().setColor(0xff667d).setTitle('Membre banni').setDescription(`**${user.username}** a été banni.\nRaison : ${reason}`).setTimestamp());
    await interaction.reply({ content: `**${user.username}** a été banni.`, ephemeral: true });
    return;
  }

  if (interaction.commandName === 'setup' && interaction.options.getSubcommand() === 'welcome') {
    if (!interaction.guildId) return;
    const channel = interaction.options.getChannel('salon', true);
    const role = interaction.options.getRole('role');
    const message = interaction.options.getString('message') ?? 'Bienvenue {user} sur **{server}** !';

    const current = getGuildSettings(interaction.guildId);
    saveGuildSettings({
      ...current,
      welcomeEnabled: true,
      welcomeChannelId: channel.id,
      welcomeMessage: message,
      autoRoleId: role?.id ?? null
    });

    addAuditLog({
      guildId: interaction.guildId,
      actorId: interaction.user.id,
      actorName: interaction.user.username,
      action: 'Configuration Discord',
      details: 'Accueil et autorôle mis à jour via /setup.'
    });

    await interaction.reply({
      content: `Accueil activé dans <#${channel.id}>${role ? ` avec le rôle **${role.name}**` : ''}.`,
      ephemeral: true
    });
  }
});

export function makeRolePanelRow(roles: Array<{ id: string; label: string; emoji?: string }>) {
  return new ActionRowBuilder<ButtonBuilder>().addComponents(
    roles.map(role => {
      const button = new ButtonBuilder()
        .setCustomId(`vxrole:${role.id}`)
        .setLabel(role.label)
        .setStyle(ButtonStyle.Secondary);
      if (role.emoji) button.setEmoji(role.emoji);
      return button;
    })
  );
}

export async function startBot() {
  await client.login(env.DISCORD_BOT_TOKEN);
}
