import { z } from 'zod';

export const AutoModRuleTypeSchema = z.enum([
  'SPAM',
  'MASS_MENTION',
  'CAPS',
  'INVITE_LINK',
  'EXTERNAL_LINK',
  'WORD_FILTER',
  'DUPLICATE',
  'EMOJI_SPAM',
  'ZALGO',
  'PHISHING'
]);
export type AutoModRuleType = z.infer<typeof AutoModRuleTypeSchema>;

export const AutoModActionSchema = z.enum(['DELETE', 'WARN', 'TIMEOUT', 'KICK', 'BAN']);
export type AutoModAction = z.infer<typeof AutoModActionSchema>;

export const AutoModExceptionsSchema = z.object({
  roleIds: z.array(z.string()).default([]),
  channelIds: z.array(z.string()).default([])
});
export type AutoModExceptions = z.infer<typeof AutoModExceptionsSchema>;

export const AutoModThresholdSchema = z.object({
  maxMentions: z.number().int().positive().optional(),
  capsPercent: z.number().min(0).max(100).optional(),
  minLength: z.number().int().nonnegative().optional(),
  maxMessages: z.number().int().positive().optional(),
  windowSeconds: z.number().int().positive().optional(),
  maxEmojis: z.number().int().positive().optional(),
  duplicateCount: z.number().int().positive().optional(),
  linkWhitelist: z.array(z.string()).optional(),
  linkBlacklist: z.array(z.string()).optional()
});
export type AutoModThreshold = z.infer<typeof AutoModThresholdSchema>;

export const AutoModWordListSchema = z.object({
  words: z.array(z.string()).default([]),
  regexPatterns: z.array(z.string()).default([])
});
export type AutoModWordList = z.infer<typeof AutoModWordListSchema>;

export const DEFAULT_AUTOMOD_RULES: Array<{
  ruleType: AutoModRuleType;
  action: AutoModAction;
  threshold?: AutoModThreshold;
  wordList?: AutoModWordList;
}> = [
  {
    ruleType: 'SPAM',
    action: 'DELETE',
    threshold: { maxMessages: 5, windowSeconds: 5 }
  },
  {
    ruleType: 'MASS_MENTION',
    action: 'DELETE',
    threshold: { maxMentions: 5 }
  },
  {
    ruleType: 'CAPS',
    action: 'DELETE',
    threshold: { capsPercent: 70, minLength: 10 }
  },
  {
    ruleType: 'INVITE_LINK',
    action: 'DELETE'
  },
  {
    ruleType: 'EXTERNAL_LINK',
    action: 'DELETE',
    threshold: { linkWhitelist: ['discord.com', 'discord.gg'] }
  },
  {
    ruleType: 'WORD_FILTER',
    action: 'DELETE',
    wordList: { words: [], regexPatterns: [] }
  },
  {
    ruleType: 'DUPLICATE',
    action: 'DELETE',
    threshold: { duplicateCount: 3, windowSeconds: 30 }
  },
  {
    ruleType: 'EMOJI_SPAM',
    action: 'DELETE',
    threshold: { maxEmojis: 10 }
  },
  {
    ruleType: 'ZALGO',
    action: 'DELETE'
  },
  {
    ruleType: 'PHISHING',
    action: 'DELETE'
  }
];

export const LogEventTypeSchema = z.enum([
  'MESSAGE_EDIT',
  'MESSAGE_DELETE',
  'MESSAGE_BULK_DELETE',
  'MEMBER_JOIN',
  'MEMBER_LEAVE',
  'MEMBER_BAN',
  'MEMBER_UNBAN',
  'MEMBER_UPDATE',
  'CHANNEL_CREATE',
  'CHANNEL_DELETE',
  'CHANNEL_UPDATE',
  'VOICE_JOIN',
  'VOICE_LEAVE',
  'VOICE_MOVE',
  'INVITE_CREATE',
  'EMOJI_CREATE',
  'EMOJI_UPDATE',
  'EMOJI_DELETE',
  'STICKER_CREATE',
  'STICKER_UPDATE',
  'STICKER_DELETE',
  'THREAD_CREATE',
  'THREAD_UPDATE',
  'THREAD_DELETE',
  'GUILD_UPDATE',
  'MOD_ACTION'
]);
export type LogEventType = z.infer<typeof LogEventTypeSchema>;

export const WelcomeMessageTypeSchema = z.enum(['TEXT', 'EMBED', 'IMAGE']);
export type WelcomeMessageType = z.infer<typeof WelcomeMessageTypeSchema>;

export const WelcomeEmbedSchema = z.object({
  title: z.string().optional(),
  description: z.string().optional(),
  color: z.number().int().optional()
});
export type WelcomeEmbed = z.infer<typeof WelcomeEmbedSchema>;

export const VerificationModeSchema = z.enum(['BUTTON', 'CAPTCHA']);
export type VerificationMode = z.infer<typeof VerificationModeSchema>;

export const VerificationFailActionSchema = z.enum(['KICK', 'BAN', 'NONE']);
export type VerificationFailAction = z.infer<typeof VerificationFailActionSchema>;

export const VerificationSetupSchema = z.object({
  channel: z.string().min(1),
  verifiedRole: z.string().min(1),
  unverifiedRole: z.string().optional(),
  mode: VerificationModeSchema.default('BUTTON'),
  minAccountAgeDays: z.number().int().nonnegative().default(0),
  failAction: VerificationFailActionSchema.default('KICK')
});
export type VerificationSetup = z.infer<typeof VerificationSetupSchema>;

export const WELCOME_PLACEHOLDERS = [
  '{user}',
  '{user.name}',
  '{user.tag}',
  '{user.id}',
  '{server}',
  '{memberCount}'
] as const;

export function applyWelcomePlaceholders(
  template: string,
  vars: Record<string, string | number>
): string {
  return Object.entries(vars).reduce(
    (acc, [name, value]) => acc.replaceAll(`{${name}}`, String(value)),
    template
  );
}

export function countEmojis(content: string): number {
  const emojiRegex =
    /(\p{Extended_Pictographic}|\p{Emoji_Presentation}|<a?:\w+:\d+>)/gu;
  return content.match(emojiRegex)?.length ?? 0;
}

export function capsRatio(content: string): number {
  const letters = content.replace(/[^a-zA-Z]/g, '');
  if (letters.length === 0) {
    return 0;
  }
  const caps = letters.replace(/[^A-Z]/g, '').length;
  return (caps / letters.length) * 100;
}

export function hasZalgo(text: string): boolean {
  return /[\u0300-\u036f\u0489]/.test(text);
}

export function extractUrls(content: string): string[] {
  const urlRegex = /https?:\/\/[^\s<>]+/gi;
  return content.match(urlRegex) ?? [];
}

export function isDiscordInvite(content: string): boolean {
  return /(?:https?:\/\/)?(?:www\.)?(?:discord\.(?:gg|io|me|li)|discordapp\.com\/invite|discord\.com\/invite)\/[^\s]+/i.test(
    content
  );
}

export function normalizeHost(url: string): string | null {
  try {
    return new URL(url).hostname.replace(/^www\./, '').toLowerCase();
  } catch {
    return null;
  }
}
