const { PermissionFlagsBits, ApplicationCommandOptionType, ChannelType } = require('discord.js')
const cron = require('node-cron')

const scheduledMessages = require('../../model/scheduledMessages')
const scheduler = require('../../scheduler/scheduler')
const { parseDuration } = require('../../utils/duration')

// Per-subcommand handlers, split out of execute() so the dispatch stays flat.
async function handleRecurring(interaction) {
  const channel = interaction.options.getChannel('channel', true)
  const cronExpr = interaction.options.getString('cron', true)
  const message = interaction.options.getString('message', true)
  if (!cron.validate(cronExpr)) {
    await interaction.reply({ content: `"${cronExpr}" isn't a valid cron expression.`, ephemeral: true })
    return
  }
  const id = await scheduledMessages.addRecurring({
    guildId: interaction.guildId,
    channelId: channel.id,
    content: message,
    cronExpression: cronExpr,
    createdBy: interaction.user.id,
    createdByTag: interaction.user.tag,
  })
  await scheduler.refresh()
  await interaction.reply({ content: `Scheduled recurring message #${id} in ${channel} on \`${cronExpr}\`.`, ephemeral: true })
}

async function handleOnce(interaction) {
  const channel = interaction.options.getChannel('channel', true)
  const inInput = interaction.options.getString('in', true)
  const message = interaction.options.getString('message', true)
  const ms = parseDuration(inInput)
  if (!ms) {
    await interaction.reply({ content: 'Invalid time — use a number plus s/m/h/d, e.g. `30m`, `2h`, `1d`.', ephemeral: true })
    return
  }
  const runAt = new Date(Date.now() + ms)
  const id = await scheduledMessages.addOnce({
    guildId: interaction.guildId,
    channelId: channel.id,
    content: message,
    runAt,
    createdBy: interaction.user.id,
    createdByTag: interaction.user.tag,
  })
  await interaction.reply({ content: `Scheduled one-off message #${id} in ${channel} for ${runAt.toLocaleString()}.`, ephemeral: true })
}

async function handleRemove(interaction) {
  const id = interaction.options.getInteger('id', true)
  const removed = await scheduledMessages.remove(interaction.guildId, id)
  await scheduler.refresh()
  await interaction.reply({ content: removed ? `Removed scheduled message #${id}.` : `No scheduled message #${id} found.`, ephemeral: true })
}

async function handleList(interaction) {
  const rows = await scheduledMessages.list(interaction.guildId)
  if (rows.length === 0) {
    await interaction.reply({ content: 'No scheduled messages.', ephemeral: true })
    return
  }
  const lines = rows.map((r) => {
    let kind
    if (r.cron_expression) kind = `cron \`${r.cron_expression}\``
    else if (r.sent_at) kind = `sent ${new Date(r.sent_at).toLocaleString()}`
    else kind = `due ${new Date(r.run_at).toLocaleString()}`
    const suffix = r.enabled ? '' : ' (disabled)'
    return `**#${r.id}** <#${r.channel_id}> — ${kind}${suffix}`
  })
  await interaction.reply({ content: lines.join('\n'), ephemeral: true })
}

module.exports = {
  data: {
    name: 'schedule',
    description: 'Manage recurring and one-off scheduled channel messages.',
    default_member_permissions: PermissionFlagsBits.ManageGuild.toString(),
    options: [
      {
        name: 'recurring',
        description: 'Schedule a recurring message on a cron schedule.',
        type: ApplicationCommandOptionType.Subcommand,
        options: [
          { name: 'channel', description: 'Channel to post in', type: ApplicationCommandOptionType.Channel, channel_types: [ChannelType.GuildText], required: true },
          { name: 'cron', description: 'Cron expression, e.g. "0 9 * * 5" (Fridays 9am)', type: ApplicationCommandOptionType.String, required: true },
          { name: 'message', description: 'Message content to post', type: ApplicationCommandOptionType.String, required: true },
        ],
      },
      {
        name: 'once',
        description: 'Schedule a one-off message for a future time.',
        type: ApplicationCommandOptionType.Subcommand,
        options: [
          { name: 'channel', description: 'Channel to post in', type: ApplicationCommandOptionType.Channel, channel_types: [ChannelType.GuildText], required: true },
          { name: 'in', description: 'When to post, e.g. 30m, 2h, 1d', type: ApplicationCommandOptionType.String, required: true },
          { name: 'message', description: 'Message content to post', type: ApplicationCommandOptionType.String, required: true },
        ],
      },
      {
        name: 'remove',
        description: 'Remove a scheduled message by id.',
        type: ApplicationCommandOptionType.Subcommand,
        options: [{ name: 'id', description: 'Scheduled message id (see /schedule list)', type: ApplicationCommandOptionType.Integer, required: true }],
      },
      {
        name: 'list',
        description: 'List all scheduled messages.',
        type: ApplicationCommandOptionType.Subcommand,
        options: [],
      },
    ],
  },
  async execute(interaction) {
    const sub = interaction.options.getSubcommand()
    if (sub === 'recurring') return handleRecurring(interaction)
    if (sub === 'once') return handleOnce(interaction)
    if (sub === 'remove') return handleRemove(interaction)
    if (sub === 'list') return handleList(interaction)
  },
}
