import { EmbedBuilder } from 'discord.js';
import { t, tf } from '@nexumi/shared';
import type { SlashCommand } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { buildBotInviteUrl, env } from '../../env.js';
import {
  helpCommandData,
  infoCommandData,
  aboutCommandData,
  inviteCommandData,
  supportCommandData
} from './command-definitions.js';
import { HELP_MODULES } from './help-catalog.js';
import { buildAboutReply } from './about.js';

const NEXUMI_COLOR = 0x6366f1;
const PACKAGE_VERSION = '0.1.0';

function formatUptime(seconds: number): string {
  const h = Math.floor(seconds / 3600);
  const m = Math.floor((seconds % 3600) / 60);
  const s = Math.floor(seconds % 60);
  return `${h}h ${m}m ${s}s`;
}

function webuiBase(): string {
  return env.WEBUI_URL ?? env.PUBLIC_BASE_URL;
}

const helpCommand: SlashCommand = {
  data: helpCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    const filter = interaction.options.getString('module')?.trim().toLowerCase() ?? null;
    const modules = filter
      ? HELP_MODULES.filter((module) => module.id === filter)
      : HELP_MODULES;

    if (modules.length === 0) {
      await interaction.reply({
        content: tf(locale, 'core.help.unknownModule', {
          modules: HELP_MODULES.map((module) => module.id).join(', ')
        }),
        ephemeral: true
      });
      return;
    }

    const lines = modules.map((module) =>
      tf(locale, 'core.help.moduleLine', {
        module: t(locale, `core.module.${module.id}`),
        commands: module.commands.map((name) => `\`/${name}\``).join(', ')
      })
    );

    // Discord embed description limit is 4096; split across fields if needed.
    const embed = new EmbedBuilder()
      .setTitle(t(locale, 'core.help.title'))
      .setDescription(t(locale, 'core.help.subtitle'))
      .setColor(NEXUMI_COLOR)
      .setFooter({
        text: tf(locale, 'core.help.footer', { webui: webuiBase() })
      });

    const chunkSize = 8;
    for (let i = 0; i < lines.length; i += chunkSize) {
      const chunk = lines.slice(i, i + chunkSize);
      embed.addFields({
        name: '\u200b',
        value: chunk.join('\n')
      });
    }

    await interaction.reply({ embeds: [embed], ephemeral: true });
  }
};

const infoCommand: SlashCommand = {
  data: infoCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    const shardId = context.client.shard?.ids[0] ?? 0;
    const inviteUrl = buildBotInviteUrl();
    const base = webuiBase();
    const linkLines = [
      `[${t(locale, 'core.info.link.dashboard')}](${base})`,
      `[${t(locale, 'core.info.link.invite')}](${inviteUrl})`,
      `[${t(locale, 'core.info.link.status')}](${base.replace(/\/$/, '')}/status)`
    ];
    if (env.SUPPORT_SERVER_URL) {
      linkLines.push(`[${t(locale, 'core.info.link.support')}](${env.SUPPORT_SERVER_URL})`);
    }

    const embed = new EmbedBuilder()
      .setTitle(t(locale, 'core.info.title'))
      .setColor(NEXUMI_COLOR)
      .addFields(
        { name: t(locale, 'core.info.version'), value: PACKAGE_VERSION, inline: true },
        {
          name: t(locale, 'core.info.uptime'),
          value: formatUptime(process.uptime()),
          inline: true
        },
        { name: t(locale, 'core.info.shard'), value: String(shardId), inline: true },
        {
          name: t(locale, 'core.info.guilds'),
          value: String(context.client.guilds.cache.size),
          inline: true
        },
        {
          name: t(locale, 'core.info.latency'),
          value: `${context.client.ws.ping} ms`,
          inline: true
        },
        { name: t(locale, 'core.info.links'), value: linkLines.join('\n') }
      )
      .setFooter({ text: 'Nexumi' });

    await interaction.reply({ embeds: [embed], ephemeral: true });
  }
};

const aboutCommand: SlashCommand = {
  data: aboutCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    const reply = await buildAboutReply(context, locale);
    await interaction.reply(reply as import('discord.js').InteractionReplyOptions);
  }
};

const inviteCommand: SlashCommand = {
  data: inviteCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    const inviteUrl = buildBotInviteUrl();
    const embed = new EmbedBuilder()
      .setTitle(t(locale, 'core.invite.title'))
      .setDescription(`${t(locale, 'core.invite.body')}\n${inviteUrl}`)
      .setColor(NEXUMI_COLOR);
    await interaction.reply({ embeds: [embed], ephemeral: true });
  }
};

const supportCommand: SlashCommand = {
  data: supportCommandData,
  async execute(interaction, context) {
    const locale = await getGuildLocale(context.prisma, interaction.guildId);
    if (!env.SUPPORT_SERVER_URL) {
      await interaction.reply({
        content: t(locale, 'core.support.missing'),
        ephemeral: true
      });
      return;
    }
    const embed = new EmbedBuilder()
      .setTitle(t(locale, 'core.support.title'))
      .setDescription(`${t(locale, 'core.support.body')}\n${env.SUPPORT_SERVER_URL}`)
      .setColor(NEXUMI_COLOR);
    await interaction.reply({ embeds: [embed], ephemeral: true });
  }
};

export const coreCommands: SlashCommand[] = [
  helpCommand,
  infoCommand,
  aboutCommand,
  inviteCommand,
  supportCommand
];
