require('dotenv').config();
const { Client, GatewayIntentBits, EmbedBuilder, ActionRowBuilder, REST, Routes, PermissionsBitField, StringSelectMenuBuilder, ChannelType, Collection, ButtonBuilder, ButtonStyle, Events } = require('discord.js');
const config = require('./config.js');
const { prefix, guildID, botID, ticketChannelID, staffRoleID, logChannelID, welcomeChannelID, logstaffChannelID, ticketCategoryID, leaveChannelID, boostChannelID, chisonoChannelID, tredquatRolelID, quindiciaRolelID, diciottoRolelID, nordRolelID, centroRolelID, sudRolelID, esteroRoleID, maschioRolelID, femminaRolelID, altroRolelID } = config;

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

const activeTickets = {}; // Definizione dell'oggetto per tenere traccia dei ticket attivi

client.commands = new Collection();

const clearCommand = require('./clearCommand.js');
client.commands.set(clearCommand.data.name, clearCommand);

const pingCommand = require('./pingCommand.js');
client.commands.set(pingCommand.data.name, pingCommand);

const anonCommand = require('./anonCommand.js');
client.commands.set(anonCommand.data.name, anonCommand);

client.on('ready', () => {
  console.log(`Il bot è online come ${client.user.tag}`);
  updateCommands(); 
});

client.on('guildMemberAdd', async (member) => {
  const welcomeChannel = await client.channels.fetch(welcomeChannelID);
  const roleID = '991387929563910165'; // Sostituisci con l'ID del ruolo base nel server 
  await member.roles.add(roleID);

  if (welcomeChannel) {
    const welcomeEmbed = new EmbedBuilder()
      .setColor('#1010CB')
      .setTitle('Benvenuto/a!')
      .setDescription(`Benvenuto/a su ${member.guild.name}, ${member}!`)
      .setThumbnail(member.user.displayAvatarURL())
      .addFields(
        { name: '*Questo è* ', value: '*un server senza topic specifico, aperto a tutti e tutte, con poche ed essenziali regole basate sul buon senso.*' },
      )
      .setImage('https://i.pinimg.com/originals/27/1f/9e/271f9e3efbc58dbb075903c7096ba99c.gif')
      .setTimestamp()
      .setFooter({ text: 'L U N A R®'});
    await welcomeChannel.send({ embeds: [welcomeEmbed] });
  }
});

client.on('guildMemberRemove', async (member) => {
  const leaveChannel = await client.channels.fetch(leaveChannelID);

  if (leaveChannel) {
    const leaveEmbed = new EmbedBuilder()
      .setColor('#1010CB')
      .setTitle('Membro uscito')
      .setDescription(`${member.user.tag} ha lasciato il server, a presto!`)
      .setThumbnail(member.user.displayAvatarURL())
      .setTimestamp()
      .setFooter({ text: 'L U N A R®'});
    await leaveChannel.send({ embeds: [leaveEmbed] });
  }
});

client.on('guildMemberUpdate', async (oldMember, newMember) => {
  const oldBoosting = oldMember.premiumSince;
  const newBoosting = newMember.premiumSince;

  if (!oldBoosting && newBoosting) {
    const boostChannel = await client.channels.fetch(boostChannelID);

    if (boostChannel) {
      const boostEmbed = new EmbedBuilder()
        .setColor('#FF73FA')
        .setTitle('Grazie per il boost!')
        .setDescription(`Grazie mille ${newMember.user.tag} per aver boostato il server! 🎉`)
        .setThumbnail('https://i.pinimg.com/originals/7d/c0/c9/7dc0c919ef58d2514ddb524d7b3ff373.gif')
        .setTimestamp()
        .setFooter({ text: 'L U N A R®'});
      await boostChannel.send({ embeds: [boostEmbed] });
    }
  }
});

const updateCommands = async () => {
  const commands = [
    clearCommand.data.toJSON(),
    pingCommand.data.toJSON(),
    anonCommand.data.toJSON(),
  ];

  const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);

  try {
    console.log('Inizio il refresh dei comandi dell\'applicazione (/).');

    await rest.put(
      Routes.applicationGuildCommands(botID, guildID),
      { body: commands }
    );

    console.log('Comandi dell\'applicazione (/) ricaricati con successo.');
  } catch (error) {
    console.error('Errore durante il refresh dei comandi dell\'applicazione:', error);
  }
};

client.on('interactionCreate', async interaction => {
  if (interaction.isCommand()) {
    const command = client.commands.get(interaction.commandName);
    if (!command) return;

    try {
      await command.execute(interaction);
    } catch (error) {
      console.error('Errore durante l\'esecuzione del comando:', error);
      await interaction.reply({ content: 'Si è verificato un errore durante l\'esecuzione del comando.', ephemeral: true });
    }
  } else if (interaction.isModalSubmit()) {
    // Gestione del submit del modulo anonimo
    if (interaction.customId === 'anonModal') {
      try {
        await anonCommand.handleModalSubmit(interaction);
      } catch (error) {
        console.error(error);
        await interaction.reply({ content: 'Si è verificato un errore durante l\'elaborazione del modulo.', ephemeral: true });
      }
    }
  } else if (interaction.channelId === chisonoChannelID && interaction.isStringSelectMenu()) {
    // Gestione delle selezioni del menu a tendina per i ruoli
    const { customId, values, member } = interaction;
    const selectedRoleID = values[0];

    // Definisci i gruppi di ruoli
    const etaRoles = [tredquatRolelID, quindiciaRolelID, diciottoRolelID];
    const localitaRoles = [nordRolelID, centroRolelID, sudRolelID, esteroRoleID];
    const genereRoles = [maschioRolelID, femminaRolelID, altroRolelID];

    let roleGroup = [];

    // Determina a quale gruppo di ruoli appartiene l'opzione selezionata
    if (etaRoles.includes(selectedRoleID)) {
      roleGroup = etaRoles;
    } else if (localitaRoles.includes(selectedRoleID)) {
      roleGroup = localitaRoles;
    } else if (genereRoles.includes(selectedRoleID)) {
      roleGroup = genereRoles;
    }

    try {
      // Rimuove i ruoli esistenti nel gruppo selezionato
      const rolesToRemove = member.roles.cache.filter(role => roleGroup.includes(role.id));
      await member.roles.remove(rolesToRemove);

      // Assegna il nuovo ruolo selezionato
      if (!rolesToRemove.has(selectedRoleID)) {
        await member.roles.add(selectedRoleID);
        await interaction.reply({ content: `Ruolo assegnato: <@&${selectedRoleID}>`, ephemeral: true });
      } else {
        await interaction.reply({ content: `Il ruolo è già stato rimosso: <@&${selectedRoleID}>`, ephemeral: true });
      }
    } catch (error) {
      console.error('Errore durante la gestione dell\'interazione:', error);
      await interaction.reply({ content: 'Si è verificato un errore durante la gestione della tua selezione.', ephemeral: true });
    }
  } else if (interaction.isStringSelectMenu()) {
    // Gestione della selezione del tipo di ticket
    const ticketType = interaction.values[0];
    const ticketUser = interaction.user;

    const ticketChannel = await client.channels.fetch(ticketChannelID);
    const logChannel = await client.channels.fetch(logChannelID);

    // Controlla se l'utente ha già un ticket aperto
    if (activeTickets[ticketUser.id]) {
      await interaction.reply({ content: 'Hai già un ticket aperto!', ephemeral: true });
      return;
    }

    const ticketChannelName = `${ticketType}-${ticketUser.username}`;

    try {
      const createdChannel = await ticketChannel.guild.channels.create({
        name: ticketChannelName,
        type: ChannelType.GuildText,
        parent: ticketCategoryID,
        permissionOverwrites: [
          {
            id: ticketChannel.guild.id,
            deny: [PermissionsBitField.Flags.ViewChannel],
          },
          {
            id: ticketUser.id,
            allow: [PermissionsBitField.Flags.ViewChannel],
          },
        ],
      });

      activeTickets[ticketUser.id] = createdChannel.id;

      const embed = new EmbedBuilder()
        .setColor(0x0099FF)
        .setTitle('Ticket Aperto')
        .setDescription(`Ciao ${ticketUser.username}, attendi che uno <@&${staffRoleID}> risponda al tuo ticket. Per chiudere il ticket premi il pulsante qui sotto.`);

      const button = new ButtonBuilder()
        .setCustomId('close_ticket')
        .setLabel('🔒 Chiudi')
        .setStyle(ButtonStyle.Danger);

      const row = new ActionRowBuilder().addComponents(button);

      await createdChannel.send({ embeds: [embed], components: [row] });

      await interaction.reply({ content: `Ticket ${ticketType} aperto con successo nel canale ${createdChannel}`, ephemeral: true });
    } catch (error) {
      console.error('Errore durante la creazione del ticket:', error);
      await interaction.reply({ content: 'Si è verificato un errore durante la creazione del ticket.', ephemeral: true });
    }
  } else if (interaction.isButton()) {
    if (interaction.customId === 'close_ticket') {
      const ticketChannel = interaction.channel;

      try {
        await ticketChannel.delete();
        delete activeTickets[interaction.user.id];
      } catch (error) {
        console.error('Errore durante la chiusura del ticket:', error);
        await interaction.reply({ content: 'Si è verificato un errore durante la chiusura del ticket.', ephemeral: true });
      }
    }
  }
});

client.once('ready', async () => {
  try {
    const ticketChannel = await client.channels.fetch(ticketChannelID);
    const messages = await ticketChannel.messages.fetch();
    messages.forEach(message => message.delete());

    const ticketEmbed = new EmbedBuilder()
      .setTitle('Apri un Ticket')
      .setDescription('Seleziona il tipo di ticket che vuoi aprire dalla lista qui sotto:')
      .addFields(
        { name: '*NOTA*', value: '*[Aprire un Ticket e non fornire alcuna risposta in esso per un tempo maggiore di 24h comporterà la chiusura automatica dello stesso.]*' }
      )
      .setColor('#e7eb88');

    const row = new ActionRowBuilder()
      .addComponents(
        new StringSelectMenuBuilder()
          .setCustomId('ticketType')
          .setPlaceholder('Seleziona il tipo di ticket')
          .addOptions([
            {
              label: '🔧Assistenza Tecnica',
              description: 'Richiedi assistenza tecnica',
              value: 'tech_support'
            },
            {
              label: '🥊Segnalazione',
              description: 'Segnalaci un problema, bug o altro',
              value: 'report'
            },
            {
              label: '🧨Rimuovi Sanzione',
              description: 'Richiedi la rimozione di una sanzione',
              value: 'remove_punishment'
            },
            {
              label: '🌺PartnerShip',
              description: 'Richiedi una Partnership',
              value: 'partnership'
            },
            {
              label: '🥥Altro',
              description: 'Richiedi assistenza per altro',
              value: 'other'
            }
          ])
      );

    await ticketChannel.send({ embeds: [ticketEmbed], components: [row] });
    console.log('Messaggio dei ticket inviato con successo.');

    updateCommands(); // Assicurati di chiamare updateCommands quando il bot è pronto
  } catch (error) {
    console.error('Errore durante la configurazione iniziale:', error);
  }
});

client.once('ready', async () => {
  try {
    const chisonoChannel = await client.channels.fetch(chisonoChannelID);

    // Elimina tutti i messaggi esistenti nel canale
    const messages = await chisonoChannel.messages.fetch();
    messages.forEach(message => message.delete());

    // Creazione degli embed
    const etaEmbed = new EmbedBuilder()
      .setImage('https://s10.gifyu.com/images/Sohqi.gif')
      .setColor('#ffdd00');

    const localitaEmbed = new EmbedBuilder()
      .setImage('https://s12.gifyu.com/images/SohqU.gif')
      .setColor('#00ffdd');

    const genereEmbed = new EmbedBuilder()
      .setImage('https://s10.gifyu.com/images/Sohq0.gif')
      .setColor('#dd00ff');

    // Creazione dei menu a tendina
    const etaMenu = new StringSelectMenuBuilder()
      .setCustomId('etaSelect')
      .setPlaceholder('Seleziona la tua età')
      .addOptions([
        { label: '🎗13-14', value: tredquatRolelID },
        { label: '🧦15-17', value: quindiciaRolelID },
        { label: '📿18+', value: diciottoRolelID }
      ]);

    const localitaMenu = new StringSelectMenuBuilder()
      .setCustomId('localitaSelect')
      .setPlaceholder('Seleziona la tua località')
      .addOptions([
        { label: '🗻Nord', value: nordRolelID },
        { label: '🕍Centro', value: centroRolelID },
        { label: '🌊Sud', value: sudRolelID },
        { label: '🛴Estero', value: esteroRoleID }
      ]);

    const genereMenu = new StringSelectMenuBuilder()
      .setCustomId('genereSelect')
      .setPlaceholder('Seleziona il tuo genere')
      .addOptions([
        { label: '📘Maschio', value: maschioRolelID },
        { label: '📕Femmina', value: femminaRolelID },
        { label: '📙Altro', value: altroRolelID }
      ]);

    // Invio dei messaggi con gli embed e i menu
    await chisonoChannel.send({ embeds: [etaEmbed], components: [new ActionRowBuilder().addComponents(etaMenu)] });
    await chisonoChannel.send({ embeds: [localitaEmbed], components: [new ActionRowBuilder().addComponents(localitaMenu)] });
    await chisonoChannel.send({ embeds: [genereEmbed], components: [new ActionRowBuilder().addComponents(genereMenu)] });

    console.log('Embed e menu inviati con successo nel canale chisono.');
  } catch (error) {
    console.error('Errore durante la configurazione iniziale:', error);
  }
});

function logBan(member, executor, reason) {
  const logstaffChannel = client.channels.cache.get(config.logstaffChannelID);
  if (logstaffChannel) {
    const banEmbed = new EmbedBuilder()
      .setColor('#FF0000')
      .setTitle('Utente Bannato')
      .addFields(
        { name: 'Utente:', value: `${member.user.tag}`, inline: true },
        { name: 'Eseguito da:', value: `${executor.tag}`, inline: true }
      )
      .setTimestamp();
    logstaffChannel.send({ embeds: [banEmbed] });
  }
}

function logKick(member, executor, reason) {
  const logstaffChannel = client.channels.cache.get(config.logstaffChannelID);
  if (logstaffChannel) {
    const kickEmbed = new EmbedBuilder()
      .setColor('#FFA500')
      .setTitle('Utente Espulso')
      .addFields(
        { name: 'Utente:', value: `${member.user.tag}`, inline: true },
        { name: 'Eseguito da:', value: `${executor.tag}`, inline: true }
      )
      .setTimestamp();
    logstaffChannel.send({ embeds: [kickEmbed] });
  }
}

client.on('guildMemberUpdate', (oldMember, newMember) => {
  const oldTimeout = oldMember.communicationDisabledUntil;
  const newTimeout = newMember.communicationDisabledUntil;

  if (!oldTimeout && newTimeout) {
    const logstaffChannel = client.channels.cache.get(config.logstaffChannelID);
    const timeoutEmbed = new EmbedBuilder()
      .setColor('#800080')
      .setTitle('Utente in Timeout')
      .addFields(
        { name: 'Utente:', value: `${newMember.user.tag}`, inline: true },
        { name: 'Timeout fino a:', value: newTimeout.toUTCString(), inline: true }
      )
      .setTimestamp();
    logstaffChannel.send({ embeds: [timeoutEmbed] });
  }
});

client.on('messageDelete', async message => {
  if (message.partial) return; // If the message was not cached, ignore it
  const logChannel = await client.channels.fetch(logChannelID);
  if (logChannel) {
    const embed = new EmbedBuilder()
      .setColor('#FF0000')
      .setTitle('Messaggio Eliminato')
      .setDescription(`Un messaggio è stato eliminato in <#${message.channel.id}>`)
      .addFields(
        { name: 'Autore:', value: `${message.author.tag}`, inline: true },
        { name: 'Contenuto:', value: message.content || 'Nessun contenuto disponibile' }
      )
      .setTimestamp();
    logChannel.send({ embeds: [embed] });
  }
});

client.on('messageUpdate', async (oldMessage, newMessage) => {
  if (oldMessage.partial || newMessage.partial) return; // If the message was not cached, ignore it
  if (oldMessage.content === newMessage.content) return; // Ignore if the content is the same

  const logChannel = await client.channels.fetch(logChannelID);
  if (logChannel) {
    const embed = new EmbedBuilder()
      .setColor('#FFA500')
      .setTitle('Messaggio Modificato')
      .setDescription(`Un messaggio è stato modificato in <#${oldMessage.channel.id}>`)
      .addFields(
        { name: 'Autore:', value: `${oldMessage.author.tag}`, inline: true },
        { name: 'Prima:', value: oldMessage.content || 'Nessun contenuto disponibile' },
        { name: 'Dopo:', value: newMessage.content || 'Nessun contenuto disponibile' }
      )
      .setTimestamp();
    logChannel.send({ embeds: [embed] });
  }
});

client.on('channelUpdate', async (oldChannel, newChannel) => {
  const logChannel = await client.channels.fetch(logChannelID);

  if (oldChannel.name !== newChannel.name) {
    if (logChannel) {
      const embed = new EmbedBuilder()
        .setColor('#8A2BE2')
        .setTitle('Canale Aggiornato')
        .setDescription(`Un canale è stato aggiornato: <#${newChannel.id}>`)
        .addFields(
          { name: 'Nome Precedente:', value: oldChannel.name },
          { name: 'Nuovo Nome:', value: newChannel.name }
        )
        .setTimestamp();
      logChannel.send({ embeds: [embed] });
    }
  }
});

client.on('guildMemberUpdate', async (oldMember, newMember) => {
  const logChannel = await client.channels.fetch(logChannelID);

  if (!oldMember.roles.cache.equals(newMember.roles.cache)) {
    const oldRoles = oldMember.roles.cache.map(role => role.name).join(', ') || 'Nessun ruolo';
    const newRoles = newMember.roles.cache.map(role => role.name).join(', ') || 'Nessun ruolo';

    if (logChannel) {
      const embed = new EmbedBuilder()
        .setColor('#0000FF')
        .setTitle('Ruoli Aggiornati')
        .setDescription(`I ruoli di ${newMember.user.tag} sono stati aggiornati`)
        .addFields(
          { name: 'Prima:', value: oldRoles },
          { name: 'Dopo:', value: newRoles }
        )
        .setTimestamp();
      logChannel.send({ embeds: [embed] });
    }
  }
});

client.on(Events.InteractionCreate, async interaction => {
  if (interaction.isCommand()) {
    const command = client.commands.get(interaction.commandName);
    if (!command) return;

    try {
      await command.execute(interaction);
    } catch (error) {
      console.error('Errore durante l\'esecuzione del comando:', error);
      if (!interaction.replied && !interaction.deferred) {
        await interaction.reply({ content: 'Si è verificato un errore durante l\'esecuzione del comando.', ephemeral: true });
      }
    }
  } else if (interaction.isModalSubmit()) {
    if (interaction.customId === 'anonModal') {
      try {
        await anonCommand.handleModalSubmit(interaction);
      } catch (error) {
        console.error('Errore durante l\'elaborazione del modulo anonimo:', error);
        if (!interaction.replied && !interaction.deferred) {
          await interaction.reply({ content: 'Si è verificato un errore durante l\'elaborazione del modulo.', ephemeral: true });
        }
      }
    }
  }
});


client.login(process.env.TOKEN);