import { PermissionFlagsBits } from 'discord.js';
import { t, tf } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { requirePermission } from '../../permissions.js';
import { invitesCommandData, statsCommandData } from './command-definitions.js';
import { getInviteLeaderboard, getInviteStatsForUser } from './invites.js';
import {
  getStatsConfig,
  refreshGuildStatsChannels,
  StatsSetupSchema,
  upsertStatsConfig
} from './service.js';

const statsCommand: SlashCommand = {
  data: statsCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    if (!interaction.inGuild()) {
      await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
      return;
    }

    const guildId = interaction.guildId!;
    const sub = interaction.options.getSubcommand();

    if (sub === 'setup') {
      if (!(await requirePermission(interaction, PermissionFlagsBits.ManageGuild, locale))) {
        return;
      }

      const membersChannel = interaction.options.getChannel('members_channel', true);
      const onlineChannel = interaction.options.getChannel('online_channel', true);
      const boostsChannel = interaction.options.getChannel('boosts_channel', true);
      const parsed = StatsSetupSchema.safeParse({
        membersChannelId: membersChannel.id,
        onlineChannelId: onlineChannel.id,
        boostsChannelId: boostsChannel.id,
        membersTemplate: interaction.options.getString('members_template') ?? undefined,
        onlineTemplate: interaction.options.getString('online_template') ?? undefined,
        boostsTemplate: interaction.options.getString('boosts_template') ?? undefined
      });

      if (!parsed.success) {
        await interaction.reply({ content: t(locale, 'stats.error.invalidSetup'), ephemeral: true });
        return;
      }

      await upsertStatsConfig(context.prisma, guildId, parsed.data);
      await refreshGuildStatsChannels(context, guildId);

      await interaction.reply({ content: t(locale, 'stats.setup.done'), ephemeral: true });
      return;
    }

    if (sub === 'refresh') {
      if (!(await requirePermission(interaction, PermissionFlagsBits.ManageGuild, locale))) {
        return;
      }

      const config = await getStatsConfig(context.prisma, guildId);
      if (!config?.enabled) {
        await interaction.reply({ content: t(locale, 'stats.notConfigured'), ephemeral: true });
        return;
      }

      await refreshGuildStatsChannels(context, guildId);
      await interaction.reply({ content: t(locale, 'stats.refresh.done'), ephemeral: true });
    }
  }
};

const invitesCommand: SlashCommand = {
  data: invitesCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    if (!interaction.inGuild()) {
      await interaction.reply({ content: t(locale, 'generic.guildOnly'), ephemeral: true });
      return;
    }

    const guildId = interaction.guildId!;
    const sub = interaction.options.getSubcommand();

    if (sub === 'view') {
      const targetUser = interaction.options.getUser('user') ?? interaction.user;
      const stats = await getInviteStatsForUser(context.prisma, guildId, targetUser.id);

      if (!stats || stats.joins === 0) {
        await interaction.reply({
          content: tf(locale, 'invites.view.empty', { user: `<@${targetUser.id}>` }),
          ephemeral: true
        });
        return;
      }

      const net = stats.joins - stats.leaves - stats.fakes;
      await interaction.reply({
        content: tf(locale, 'invites.view.result', {
          user: `<@${targetUser.id}>`,
          joins: stats.joins,
          leaves: stats.leaves,
          fakes: stats.fakes,
          net
        }),
        ephemeral: true
      });
      return;
    }

    if (sub === 'leaderboard') {
      const entries = await getInviteLeaderboard(context.prisma, guildId, 10);
      if (entries.length === 0) {
        await interaction.reply({ content: t(locale, 'invites.leaderboard.empty'), ephemeral: true });
        return;
      }

      const lines = entries.map((entry, index) => {
        const net = entry.joins - entry.leaves - entry.fakes;
        return tf(locale, 'invites.leaderboard.line', {
          rank: index + 1,
          user: `<@${entry.inviterId}>`,
          joins: entry.joins,
          leaves: entry.leaves,
          fakes: entry.fakes,
          net
        });
      });

      await interaction.reply({
        content: `${t(locale, 'invites.leaderboard.header')}\n${lines.join('\n')}`,
        ephemeral: true
      });
    }
  }
};

export const statsCommands: SlashCommand[] = [statsCommand, invitesCommand];
