import { PermissionFlagsBits } from 'discord.js';
import { SocialFeedTypeSchema, t, tf } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { requirePermission } from '../../permissions.js';
import { feedsCommandData } from './command-definitions.js';
import {
  addFeed,
  FeedAddSchema,
  FeedError,
  getFeedById,
  listFeeds,
  removeFeed,
  testFeed
} from './service.js';

const feedsCommand: SlashCommand = {
  data: feedsCommandData,
  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 sub = interaction.options.getSubcommand(true);
    const guildId = interaction.guildId!;

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

    try {
      if (sub === 'add') {
        const input = FeedAddSchema.parse({
          type: SocialFeedTypeSchema.parse(interaction.options.getString('type', true)),
          source: interaction.options.getString('source', true),
          channelId: interaction.options.getChannel('channel', true).id,
          rolePingId: interaction.options.getRole('role')?.id,
          template: interaction.options.getString('template') ?? undefined
        });

        const feed = await addFeed(context.prisma, guildId, input);
        await interaction.reply({
          content: tf(locale, 'feeds.added', { id: feed.id, type: feed.type }),
          ephemeral: true
        });
        return;
      }

      if (sub === 'remove') {
        const feedId = interaction.options.getString('id', true);
        const removed = await removeFeed(context.prisma, guildId, feedId);
        if (!removed) {
          await interaction.reply({ content: t(locale, 'feeds.error.not_found'), ephemeral: true });
          return;
        }

        await interaction.reply({
          content: tf(locale, 'feeds.removed', { id: removed.id }),
          ephemeral: true
        });
        return;
      }

      if (sub === 'list') {
        const feeds = await listFeeds(context.prisma, guildId);
        if (feeds.length === 0) {
          await interaction.reply({ content: t(locale, 'feeds.list.empty'), ephemeral: true });
          return;
        }

        const lines = feeds.map((feed) =>
          tf(locale, 'feeds.list.line', {
            id: feed.id,
            type: feed.type,
            source: feed.sourceId,
            channel: `<#${feed.channelId}>`
          })
        );

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

      if (sub === 'test') {
        const feedId = interaction.options.getString('id', true);
        const feed = await getFeedById(context.prisma, guildId, feedId);
        if (!feed) {
          await interaction.reply({ content: t(locale, 'feeds.error.not_found'), ephemeral: true });
          return;
        }

        const result = await testFeed(context, feed);
        if (result.skipped) {
          const skipKey =
            result.message === 'twitch_credentials_missing'
              ? 'feeds.test.twitchSkipped'
              : 'feeds.test.skipped';
          await interaction.reply({
            content: t(locale, skipKey),
            ephemeral: true
          });
          return;
        }

        if (result.message && result.posted === 0) {
          await interaction.reply({
            content: tf(locale, 'feeds.test.failed', { reason: result.message }),
            ephemeral: true
          });
          return;
        }

        if (result.posted === 0) {
          await interaction.reply({ content: t(locale, 'feeds.test.noItems'), ephemeral: true });
          return;
        }

        await interaction.reply({
          content: tf(locale, 'feeds.test.posted', { count: result.posted }),
          ephemeral: true
        });
      }
    } catch (error) {
      if (error instanceof FeedError) {
        await interaction.reply({
          content: t(locale, `feeds.error.${error.code}`),
          ephemeral: true
        });
        return;
      }
      throw error;
    }
  }
};

export const feedsCommands: SlashCommand[] = [feedsCommand];
