const { 
  SlashCommandBuilder, 
  EmbedBuilder, 
  PermissionFlagsBits,
  ChannelType
} = require('discord.js');

module.exports = {
  data: new SlashCommandBuilder()
    .setName('schedule')
    .setDescription('Schedule a message to be sent later')
    .setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages)
    .addSubcommand(sub =>
      sub.setName('message')
        .setDescription('Schedule a text message')
        .addChannelOption(option =>
          option.setName('channel')
            .setDescription('Channel to send the message to')
            .setRequired(true)
            .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
        )
        .addStringOption(option =>
          option.setName('content')
            .setDescription('Message content')
            .setRequired(true)
            .setMaxLength(2000)
        )
        .addIntegerOption(option =>
          option.setName('minutes')
            .setDescription('Minutes from now')
            .setRequired(true)
            .setMinValue(1)
            .setMaxValue(10080)
        )
        .addBooleanOption(option =>
          option.setName('ping_everyone')
            .setDescription('Ping @everyone')
            .setRequired(false)
        )
    )
    .addSubcommand(sub =>
      sub.setName('embed')
        .setDescription('Schedule an embed message')
        .addChannelOption(option =>
          option.setName('channel')
            .setDescription('Channel to send the embed to')
            .setRequired(true)
            .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
        )
        .addStringOption(option =>
          option.setName('title')
            .setDescription('Embed title')
            .setRequired(true)
            .setMaxLength(256)
        )
        .addStringOption(option =>
          option.setName('description')
            .setDescription('Embed description')
            .setRequired(true)
            .setMaxLength(2000)
        )
        .addIntegerOption(option =>
          option.setName('minutes')
            .setDescription('Minutes from now')
            .setRequired(true)
            .setMinValue(1)
            .setMaxValue(10080)
        )
        .addStringOption(option =>
          option.setName('color')
            .setDescription('Embed color')
            .setRequired(false)
            .addChoices(
              { name: '🟣 Purple', value: '7c3aed' },
              { name: '🟢 Green', value: '22c55e' },
              { name: '🔴 Red', value: 'ef4444' },
              { name: '🔵 Blue', value: '3b82f6' },
              { name: '🟡 Yellow', value: 'eab308' }
            )
        )
    )
    .addSubcommand(sub =>
      sub.setName('list')
        .setDescription('List scheduled messages')
    )
    .addSubcommand(sub =>
      sub.setName('cancel')
        .setDescription('Cancel a scheduled message')
        .addStringOption(option =>
          option.setName('id')
            .setDescription('Scheduled message ID')
            .setRequired(true)
        )
    ),

  async execute(interaction, supabase, client) {
    const subcommand = interaction.options.getSubcommand();

    if (subcommand === 'message') {
      await handleMessage(interaction, supabase, client);
    } else if (subcommand === 'embed') {
      await handleEmbed(interaction, supabase, client);
    } else if (subcommand === 'list') {
      await handleList(interaction, supabase);
    } else if (subcommand === 'cancel') {
      await handleCancel(interaction, supabase, client);
    }
  },
};

async function handleMessage(interaction, supabase, client) {
  await interaction.deferReply({ ephemeral: true });

  const channel = interaction.options.getChannel('channel');
  const content = interaction.options.getString('content');
  const minutes = interaction.options.getInteger('minutes');
  const pingEveryone = interaction.options.getBoolean('ping_everyone') || false;

  const sendTime = Date.now() + (minutes * 60 * 1000);
  const sendTimestamp = Math.floor(sendTime / 1000);

  const scheduleId = `sched_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

  try {
    const scheduleData = {
      id: scheduleId,
      type: 'message',
      channelId: channel.id,
      content: pingEveryone ? `@everyone ${content}` : content,
      sendTime: sendTime
    };

    client.scheduledMessages = client.scheduledMessages || new Map();
    const timeout = setTimeout(() => sendScheduledMessage(scheduleId, client, supabase), minutes * 60 * 1000);
    client.scheduledMessages.set(scheduleId, { ...scheduleData, timeout });

    if (supabase) {
      await supabase.from('scheduled_messages').insert({
        id: scheduleId,
        guild_id: interaction.guildId,
        channel_id: channel.id,
        type: 'message',
        content: scheduleData.content,
        send_time: new Date(sendTime).toISOString(),
        created_by: interaction.user.id,
        status: 'pending'
      });
    }

    const embed = new EmbedBuilder()
      .setColor(0x22c55e)
      .setTitle('✅ Message Scheduled')
      .setDescription(`Message will be sent to ${channel} <t:${sendTimestamp}:R>`)
      .addFields(
        { name: 'ID', value: `\`${scheduleId}\``, inline: true },
        { name: 'Send Time', value: `<t:${sendTimestamp}:f>`, inline: true }
      )
      .setTimestamp();

    await interaction.editReply({ embeds: [embed] });

  } catch (error) {
    console.error('Schedule message error:', error);
    await interaction.editReply({ content: 'Failed to schedule message.' });
  }
}

async function handleEmbed(interaction, supabase, client) {
  await interaction.deferReply({ ephemeral: true });

  const channel = interaction.options.getChannel('channel');
  const title = interaction.options.getString('title');
  const description = interaction.options.getString('description');
  const minutes = interaction.options.getInteger('minutes');
  const color = interaction.options.getString('color') || '7c3aed';

  const sendTime = Date.now() + (minutes * 60 * 1000);
  const sendTimestamp = Math.floor(sendTime / 1000);

  const scheduleId = `sched_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;

  try {
    const embedData = {
      title: title,
      description: description,
      color: parseInt(color, 16)
    };

    const scheduleData = {
      id: scheduleId,
      type: 'embed',
      channelId: channel.id,
      embedData: embedData,
      sendTime: sendTime
    };

    client.scheduledMessages = client.scheduledMessages || new Map();
    const timeout = setTimeout(() => sendScheduledMessage(scheduleId, client, supabase), minutes * 60 * 1000);
    client.scheduledMessages.set(scheduleId, { ...scheduleData, timeout });

    if (supabase) {
      await supabase.from('scheduled_messages').insert({
        id: scheduleId,
        guild_id: interaction.guildId,
        channel_id: channel.id,
        type: 'embed',
        embed_data: embedData,
        send_time: new Date(sendTime).toISOString(),
        created_by: interaction.user.id,
        status: 'pending'
      });
    }

    const embed = new EmbedBuilder()
      .setColor(0x22c55e)
      .setTitle('✅ Embed Scheduled')
      .setDescription(`Embed will be sent to ${channel} <t:${sendTimestamp}:R>`)
      .addFields(
        { name: 'ID', value: `\`${scheduleId}\``, inline: true },
        { name: 'Send Time', value: `<t:${sendTimestamp}:f>`, inline: true },
        { name: 'Embed Title', value: title, inline: false }
      )
      .setTimestamp();

    await interaction.editReply({ embeds: [embed] });

  } catch (error) {
    console.error('Schedule embed error:', error);
    await interaction.editReply({ content: 'Failed to schedule embed.' });
  }
}

async function handleList(interaction, supabase) {
  await interaction.deferReply({ ephemeral: true });

  if (!supabase) {
    return interaction.editReply({ content: 'Database not available.' });
  }

  try {
    const { data: scheduled, error } = await supabase
      .from('scheduled_messages')
      .select('*')
      .eq('guild_id', interaction.guildId)
      .eq('status', 'pending')
      .order('send_time', { ascending: true });

    if (error) throw error;

    if (!scheduled || scheduled.length === 0) {
      return interaction.editReply({ content: 'No scheduled messages.' });
    }

    const embed = new EmbedBuilder()
      .setColor(0x7c3aed)
      .setTitle('📅 Scheduled Messages')
      .setDescription(scheduled.map(s => {
        const sendTimestamp = Math.floor(new Date(s.send_time).getTime() / 1000);
        return `**ID:** \`${s.id}\`\nType: ${s.type}\nChannel: <#${s.channel_id}>\nSends: <t:${sendTimestamp}:R>`;
      }).join('\n\n'))
      .setFooter({ text: `${scheduled.length} scheduled` })
      .setTimestamp();

    await interaction.editReply({ embeds: [embed] });

  } catch (error) {
    console.error('Schedule list error:', error);
    await interaction.editReply({ content: 'Failed to fetch scheduled messages.' });
  }
}

async function handleCancel(interaction, supabase, client) {
  await interaction.deferReply({ ephemeral: true });

  const scheduleId = interaction.options.getString('id');

  try {
    const scheduled = client.scheduledMessages?.get(scheduleId);
    if (scheduled?.timeout) {
      clearTimeout(scheduled.timeout);
      client.scheduledMessages.delete(scheduleId);
    }

    if (supabase) {
      await supabase
        .from('scheduled_messages')
        .update({ status: 'cancelled' })
        .eq('id', scheduleId);
    }

    await interaction.editReply({ content: '✅ Scheduled message cancelled.' });

  } catch (error) {
    console.error('Schedule cancel error:', error);
    await interaction.editReply({ content: 'Failed to cancel.' });
  }
}

async function sendScheduledMessage(scheduleId, client, supabase) {
  try {
    const scheduled = client.scheduledMessages?.get(scheduleId);
    if (!scheduled) return;

    const channel = await client.channels.fetch(scheduled.channelId);
    if (!channel) return;

    if (scheduled.type === 'message') {
      await channel.send(scheduled.content);
    } else if (scheduled.type === 'embed') {
      const embed = new EmbedBuilder()
        .setColor(scheduled.embedData.color)
        .setTitle(scheduled.embedData.title)
        .setDescription(scheduled.embedData.description)
        .setTimestamp();

      await channel.send({ embeds: [embed] });
    }

    client.scheduledMessages.delete(scheduleId);

    if (supabase) {
      await supabase
        .from('scheduled_messages')
        .update({ status: 'sent' })
        .eq('id', scheduleId);
    }

  } catch (error) {
    console.error('Send scheduled message error:', error);
  }
}
