import { BotError, ErrorCategory } from './BotError';

/**
 * Error code definitions — thin objects holding only the code, category, and i18n key.
 * Actual user-facing messages live in src/i18n/locales/*.ts.
 *
 * Error codes are prefixed by category:
 *   E1xxx = USER_INPUT
 *   E2xxx = PERMISSION
 *   E3xxx = BOT_INTERNAL
 *   E4xxx = DISCORD_API
 *
 * These codes are logged server-side only and NEVER exposed to end users.
 */

/** Error definition template (not a live BotError — used as factory input) */
interface ErrorDef {
  code: string;
  category: ErrorCategory;
  messageKey: string;
}

export const ErrorDefs = {
  // ── USER_INPUT (E1xxx) ──────────────────────────────────
  INVALID_USER_LIMIT: {
    code: 'E1001',
    category: ErrorCategory.USER_INPUT,
    messageKey: 'errors.E1001',
  },
  INVALID_CHANNEL_NAME: {
    code: 'E1002',
    category: ErrorCategory.USER_INPUT,
    messageKey: 'errors.E1002',
  },
  SELF_TARGET_NOT_ALLOWED: {
    code: 'E1003',
    category: ErrorCategory.USER_INPUT,
    messageKey: 'errors.E1003',
  },
  USER_NOT_IN_CHANNEL: {
    code: 'E1004',
    category: ErrorCategory.USER_INPUT,
    messageKey: 'errors.E1004',
  },

  // ── PERMISSION (E2xxx) ──────────────────────────────────
  BOT_MISSING_MANAGE_CHANNELS: {
    code: 'E2001',
    category: ErrorCategory.PERMISSION,
    messageKey: 'errors.E2001',
  },
  BOT_MISSING_VOICE_PERMISSIONS: {
    code: 'E2002',
    category: ErrorCategory.PERMISSION,
    messageKey: 'errors.E2002',
  },
  USER_NOT_ADMIN: {
    code: 'E2003',
    category: ErrorCategory.PERMISSION,
    messageKey: 'errors.E2003',
  },
  NOT_CHANNEL_OWNER: {
    code: 'E2004',
    category: ErrorCategory.PERMISSION,
    messageKey: 'errors.E2004',
  },
  MUST_BE_IN_VOICE_CHANNEL: {
    code: 'E2005',
    category: ErrorCategory.PERMISSION,
    messageKey: 'errors.E2005',
  },

  // ── BOT_INTERNAL (E3xxx) ────────────────────────────────
  DATABASE_ERROR: {
    code: 'E3001',
    category: ErrorCategory.BOT_INTERNAL,
    messageKey: 'errors.E3001',
  },
  CACHE_ERROR: {
    code: 'E3002',
    category: ErrorCategory.BOT_INTERNAL,
    messageKey: 'errors.E3002',
  },
  COMMAND_EXECUTION_FAILED: {
    code: 'E3003',
    category: ErrorCategory.BOT_INTERNAL,
    messageKey: 'errors.E3003',
  },
  UNKNOWN_ERROR: {
    code: 'E3999',
    category: ErrorCategory.BOT_INTERNAL,
    messageKey: 'errors.E3999',
  },

  // ── DISCORD_API (E4xxx) ─────────────────────────────────
  DISCORD_RATE_LIMITED: {
    code: 'E4001',
    category: ErrorCategory.DISCORD_API,
    messageKey: 'errors.E4001',
  },
  DISCORD_MISSING_PERMISSIONS: {
    code: 'E4002',
    category: ErrorCategory.DISCORD_API,
    messageKey: 'errors.E4002',
  },
  DISCORD_API_ERROR: {
    code: 'E4003',
    category: ErrorCategory.DISCORD_API,
    messageKey: 'errors.E4003',
  },
} as const satisfies Record<string, ErrorDef>;

/**
 * Backward-compatible alias.
 * @deprecated Use ErrorDefs instead.
 */
export const ErrorCodes = ErrorDefs;

/**
 * Creates a new BotError from a predefined error definition,
 * with an optional original cause error.
 */
export function createBotError(
  def: ErrorDef,
  cause?: Error,
): BotError {
  return new BotError({
    code: def.code,
    category: def.category,
    messageKey: def.messageKey,
    cause,
  });
}
