import { Events, type Client } from 'discord.js';
import { t } from '@nexumi/shared';
import type { BotContext } from '../../types.js';
import { getGuildLocale } from '../../i18n.js';
import { logger } from '../../logger.js';
import {
  applyTagCooldown,
  buildTagReply,
  findTriggeredTag,
  getTagCooldownRemaining,
  memberCanUseTag,
  TagError
} from './service.js';

export function registerTagEvents(client: Client, context: BotContext): void {
  client.on(Events.MessageCreate, async (message) => {
    try {
      if (!message.guild || message.author.bot || !message.content.trim()) {
        return;
      }

      const tag = await findTriggeredTag(context, message.guild.id, message.content);
      if (!tag) {
        return;
      }

      const member = await message.guild.members.fetch(message.author.id).catch(() => null);
      if (!member) {
        return;
      }

      if (!memberCanUseTag(tag, member, message.channel.id)) {
        return;
      }

      // Channel-scoped cooldown: silent skip to avoid spam replies.
      if (tag.cooldownSeconds > 0) {
        const remaining = await getTagCooldownRemaining(
          message.guild.id,
          tag.id,
          message.channel.id
        );
        if (remaining > 0) {
          return;
        }
      }

      await context.prisma.tag.update({
        where: { id: tag.id },
        data: { useCount: { increment: 1 } }
      });

      const payload = buildTagReply(tag, member, message.guild, '');
      await message.reply(payload);
      await applyTagCooldown(message.guild.id, tag.id, message.channel.id, tag.cooldownSeconds);
    } catch (error) {
      if (error instanceof TagError) {
        const locale = await getGuildLocale(context.prisma, message.guild?.id ?? null);
        logger.debug({ code: error.code, tag: error.message }, t(locale, `tag.error.${error.code}`));
        return;
      }
      logger.error({ error, messageId: message.id }, 'Tag auto-responder failed');
    }
  });
}
