/**
 * Application Constants
 *
 * Centralized constants for the entire application
 */

import { ModuleType, TopicType, ExerciseType, ExerciseDifficulty } from '@prisma/client';

// ============================================
// MODULES & TOPICS
// ============================================

export const MODULES = {
  [ModuleType.FUNDAMENTOS]: {
    id: ModuleType.FUNDAMENTOS,
    name: 'Fundamentos de Álgebra Lineal',
    description: 'Introducción a vectores y matrices',
    order: 1,
    topics: [TopicType.VECTORES, TopicType.MATRICES],
    estimatedHours: 40,
  },
  [ModuleType.SISTEMAS_ESPACIOS]: {
    id: ModuleType.SISTEMAS_ESPACIOS,
    name: 'Sistemas y Espacios Vectoriales',
    description: 'Sistemas de ecuaciones y espacios vectoriales',
    order: 2,
    topics: [TopicType.SISTEMAS, TopicType.ESPACIOS_VECTORIALES],
    estimatedHours: 50,
  },
  [ModuleType.APLICACIONES]: {
    id: ModuleType.APLICACIONES,
    name: 'Aplicaciones y Optimización',
    description: 'Programación lineal y aplicaciones prácticas',
    order: 3,
    topics: [TopicType.PROGRAMACION_LINEAL],
    estimatedHours: 30,
  },
} as const;

export const TOPICS = {
  [TopicType.VECTORES]: {
    id: TopicType.VECTORES,
    name: 'Vectores',
    description: 'Operaciones con vectores, producto escalar y vectorial',
    module: ModuleType.FUNDAMENTOS,
  },
  [TopicType.MATRICES]: {
    id: TopicType.MATRICES,
    name: 'Matrices',
    description: 'Operaciones con matrices, determinantes e inversión',
    module: ModuleType.FUNDAMENTOS,
  },
  [TopicType.SISTEMAS]: {
    id: TopicType.SISTEMAS,
    name: 'Sistemas de Ecuaciones',
    description: 'Resolución de sistemas lineales, métodos de Gauss y Gauss-Jordan',
    module: ModuleType.SISTEMAS_ESPACIOS,
  },
  [TopicType.ESPACIOS_VECTORIALES]: {
    id: TopicType.ESPACIOS_VECTORIALES,
    name: 'Espacios Vectoriales',
    description: 'Bases, dimensión, transformaciones lineales',
    module: ModuleType.SISTEMAS_ESPACIOS,
  },
  [TopicType.PROGRAMACION_LINEAL]: {
    id: TopicType.PROGRAMACION_LINEAL,
    name: 'Programación Lineal',
    description: 'Optimización lineal, método simplex',
    module: ModuleType.APLICACIONES,
  },
} as const;

// ============================================
// EXERCISES
// ============================================

export const EXERCISE_POINTS = {
  [ExerciseDifficulty.BASIC]: 5,
  [ExerciseDifficulty.INTERMEDIATE]: 10,
  [ExerciseDifficulty.ADVANCED]: 20,
  [ExerciseDifficulty.EXPERT]: 30,
} as const;

export const EXERCISE_TIME_LIMITS = {
  [ExerciseDifficulty.BASIC]: 300, // 5 minutes
  [ExerciseDifficulty.INTERMEDIATE]: 600, // 10 minutes
  [ExerciseDifficulty.ADVANCED]: 1200, // 20 minutes
  [ExerciseDifficulty.EXPERT]: 2400, // 40 minutes
} as const;

export const EXERCISE_HINT_COST = 2; // Points deducted per hint

// ============================================
// ACHIEVEMENTS / BADGES
// ============================================

export const ACHIEVEMENTS = {
  // Exercise achievements
  FIRST_EXERCISE: {
    code: 'FIRST_EXERCISE',
    name: 'Primer Paso',
    description: 'Completa tu primer ejercicio',
    category: 'EXERCISES',
    rarity: 'COMMON',
    icon: '🎯',
    requirementType: 'EXERCISES_COMPLETED',
    requirementValue: 1,
    points: 10,
  },
  TEN_EXERCISES: {
    code: 'TEN_EXERCISES',
    name: 'En Marcha',
    description: 'Completa 10 ejercicios',
    category: 'EXERCISES',
    rarity: 'COMMON',
    icon: '🚀',
    requirementType: 'EXERCISES_COMPLETED',
    requirementValue: 10,
    points: 50,
  },
  HUNDRED_EXERCISES: {
    code: 'HUNDRED_EXERCISES',
    name: 'Matemático Dedicado',
    description: 'Completa 100 ejercicios',
    category: 'EXERCISES',
    rarity: 'EPIC',
    icon: '🏆',
    requirementType: 'EXERCISES_COMPLETED',
    requirementValue: 100,
    points: 200,
  },
  FIVE_PERFECT: {
    code: 'FIVE_PERFECT',
    name: 'Perfeccionista',
    description: 'Completa 5 ejercicios sin errores',
    category: 'EXERCISES',
    rarity: 'RARE',
    icon: '💎',
    requirementType: 'PERFECT_SCORES',
    requirementValue: 5,
    points: 75,
  },

  // Module achievements
  FIRST_MODULE: {
    code: 'FIRST_MODULE',
    name: 'Primera Conquista',
    description: 'Completa tu primer módulo',
    category: 'MODULES',
    rarity: 'RARE',
    icon: '🎓',
    requirementType: 'MODULES_COMPLETED',
    requirementValue: 1,
    points: 100,
  },
  ALL_MODULES: {
    code: 'ALL_MODULES',
    name: 'Maestro del Álgebra',
    description: 'Completa todos los módulos',
    category: 'MODULES',
    rarity: 'LEGENDARY',
    icon: '👑',
    requirementType: 'MODULES_COMPLETED',
    requirementValue: 3,
    points: 500,
  },
  PERFECT_MODULE: {
    code: 'PERFECT_MODULE',
    name: 'Módulo Perfecto',
    description: 'Completa un módulo con 100% de puntuación',
    category: 'MODULES',
    rarity: 'EPIC',
    icon: '⭐',
    requirementType: 'PERFECT_MODULE',
    requirementValue: 1,
    points: 300,
  },

  // Streak achievements
  THREE_DAY_STREAK: {
    code: 'THREE_DAY_STREAK',
    name: 'En Racha',
    description: '3 días consecutivos de estudio',
    category: 'STREAKS',
    rarity: 'COMMON',
    icon: '🔥',
    requirementType: 'STREAK_DAYS',
    requirementValue: 3,
    points: 30,
  },
  WEEK_STREAK: {
    code: 'WEEK_STREAK',
    name: 'Semana Perfecta',
    description: '7 días consecutivos de estudio',
    category: 'STREAKS',
    rarity: 'RARE',
    icon: '📅',
    requirementType: 'STREAK_DAYS',
    requirementValue: 7,
    points: 100,
  },
  MONTH_STREAK: {
    code: 'MONTH_STREAK',
    name: 'Mensual',
    description: '30 días consecutivos de estudio',
    category: 'STREAKS',
    rarity: 'LEGENDARY',
    icon: '🌟',
    requirementType: 'STREAK_DAYS',
    requirementValue: 30,
    points: 500,
  },

  // Ranking achievements
  TOP_10: {
    code: 'TOP_10',
    name: 'Top 10',
    description: 'Alcanza el Top 10 del ranking global',
    category: 'RANKING',
    rarity: 'EPIC',
    icon: '🎖️',
    requirementType: 'RANKING_POSITION',
    requirementValue: 10,
    points: 200,
  },
  PODIUM: {
    code: 'PODIUM',
    name: 'Podium',
    description: 'Alcanza el Top 3 del ranking global',
    category: 'RANKING',
    rarity: 'LEGENDARY',
    icon: '🏅',
    requirementType: 'RANKING_POSITION',
    requirementValue: 3,
    points: 400,
  },
  CHAMPION: {
    code: 'CHAMPION',
    name: 'El Campeón',
    description: 'Alcanza el #1 del ranking global',
    category: 'RANKING',
    rarity: 'LEGENDARY',
    icon: '🥇',
    requirementType: 'RANKING_POSITION',
    requirementValue: 1,
    points: 1000,
  },

  // Special achievements
  EARLY_BIRD: {
    code: 'EARLY_BIRD',
    name: 'Madrugador',
    description: 'Completa un ejercicio antes de las 6 AM',
    category: 'SPECIAL',
    rarity: 'RARE',
    icon: '🌅',
    requirementType: 'EARLY_BIRD',
    requirementValue: 1,
    points: 50,
  },
  NIGHT_OWL: {
    code: 'NIGHT_OWL',
    name: 'Búho Nocturno',
    description: 'Completa un ejercicio después de medianoche',
    category: 'SPECIAL',
    rarity: 'RARE',
    icon: '🦉',
    requirementType: 'NIGHT_OWL',
    requirementValue: 1,
    points: 50,
  },
  AUTODIDACT: {
    code: 'AUTODIDACT',
    name: 'Autodidacta',
    description: 'Completa 10 ejercicios sin usar pistas',
    category: 'SPECIAL',
    rarity: 'EPIC',
    icon: '📚',
    requirementType: 'EXERCISES_WITHOUT_HINTS',
    requirementValue: 10,
    points: 150,
  },
} as const;

// ============================================
// NOTIFICATIONS
// ============================================

export const NOTIFICATION_TYPES = {
  NEW_USER: 'new_user',
  EXERCISE_COMPLETED: 'exercise_completed',
  MODULE_COMPLETED: 'module_completed',
  ACHIEVEMENT_UNLOCKED: 'achievement_unlocked',
  SYSTEM_ERROR: 'system_error',
  DAILY_SUMMARY: 'daily_summary',
  RANKING_CHANGED: 'ranking_changed',
} as const;

export const NOTIFICATION_TEMPLATES = {
  [NOTIFICATION_TYPES.NEW_USER]: (username: string) => ({
    title: '🎉 Nuevo Usuario Registrado',
    message: `El usuario ${username} se ha registrado en la plataforma.`,
  }),
  [NOTIFICATION_TYPES.EXERCISE_COMPLETED]: (exerciseTitle: string, points: number) => ({
    title: '✅ Ejercicio Completado',
    message: `Ejercicio "${exerciseTitle}" completado. +${points} puntos`,
  }),
  [NOTIFICATION_TYPES.MODULE_COMPLETED]: (moduleName: string) => ({
    title: '🎓 Módulo Completado',
    message: `¡Felicidades! Has completado el módulo "${moduleName}".`,
  }),
  [NOTIFICATION_TYPES.ACHIEVEMENT_UNLOCKED]: (achievementName: string, icon: string) => ({
    title: `${icon} Logro Desbloqueado`,
    message: `Has desbloqueado el logro "${achievementName}".`,
  }),
  [NOTIFICATION_TYPES.SYSTEM_ERROR]: (error: string) => ({
    title: '⚠️ Error del Sistema',
    message: `Se ha producido un error: ${error}`,
  }),
  [NOTIFICATION_TYPES.DAILY_SUMMARY]: (stats: { exercises: number; points: number; rank: number }) => ({
    title: '📊 Resumen Diario',
    message: `Hoy completaste ${stats.exercises} ejercicios, ganaste ${stats.points} puntos. Posición: #${stats.rank}`,
  }),
  [NOTIFICATION_TYPES.RANKING_CHANGED]: (newPosition: number, change: number) => ({
    title: '📈 Cambio de Ranking',
    message: change > 0
      ? `¡Has subido ${change} posiciones! Nueva posición: #${newPosition}`
      : `Has bajado ${Math.abs(change)} posiciones. Nueva posición: #${newPosition}`,
  }),
} as const;

// ============================================
// RANKING
// ============================================

export const RANKING_UPDATE_INTERVAL = 60000; // 1 minute
export const RANKING_CACHE_TTL = 300; // 5 minutes
export const LEADERBOARD_SIZE = 100;

// ============================================
// RATE LIMITING
// ============================================

export const RATE_LIMITS = {
  STANDARD: {
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 100,
  },
  AUTH: {
    windowMs: 15 * 60 * 1000, // 15 minutes
    max: 5,
  },
  EXERCISE: {
    windowMs: 60 * 1000, // 1 minute
    max: 20,
  },
  AI: {
    windowMs: 60 * 60 * 1000, // 1 hour
    max: 50,
  },
} as const;

// ============================================
// CACHE
// ============================================

export const CACHE_KEYS = {
  MODULE: (id: string) => `module:${id}`,
  TOPIC: (id: string) => `topic:${id}`,
  EXERCISE: (id: string) => `exercise:${id}`,
  USER_PROGRESS: (userId: string) => `user:${userId}:progress`,
  USER_RANKING: (userId: string) => `user:${userId}:ranking`,
  GLOBAL_RANKING: 'ranking:global',
  MODULE_RANKING: (moduleId: string) => `ranking:module:${moduleId}`,
  USER_ACHIEVEMENTS: (userId: string) => `user:${userId}:achievements`,
} as const;

export const CACHE_TTL = {
  SHORT: 300, // 5 minutes
  MEDIUM: 1800, // 30 minutes
  LONG: 3600, // 1 hour
  VERY_LONG: 86400, // 24 hours
} as const;

// ============================================
// PDF PROCESSING
// ============================================

export const PDF_TYPES = {
  TEXTBOOK: 'TEXTBOOK',
  PRACTICE: 'PRACTICE',
  PRACTICE_ANSWERS: 'PRACTICE_ANSWERS',
  EXAM: 'EXAM',
  ADDITIONAL_MATERIAL: 'ADDITIONAL_MATERIAL',
} as const;

// ============================================
// VALIDATION
// ============================================

export const VALIDATION = {
  PASSWORD_MIN_LENGTH: 8,
  PASSWORD_MAX_LENGTH: 128,
  USERNAME_MIN_LENGTH: 3,
  USERNAME_MAX_LENGTH: 30,
  USERNAME_PATTERN: /^[a-zA-Z0-9_-]+$/,
  EMAIL_PATTERN: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
} as const;

// ============================================
// API
// ============================================

export const API = {
  VERSION: 'v1',
  PREFIX: '/api',
  DEFAULT_PAGE_SIZE: 20,
  MAX_PAGE_SIZE: 100,
} as const;

// ============================================
// MATH NOTATION
// ============================================

export const MATH_NOTATION = {
  VECTOR: {
    BOLD: 'bold', // **v**, **A**
    ARROW: 'arrow', // \\vec{v}, \\vec{AB}
    HAT: 'hat', // \\hat{v}, \\hat{i}
  },
  MATRIX: {
    BOLD: 'bold', // **A**, **B**
    UPPERCASE: 'uppercase', // A, B
    BRACKET: 'bracket', // [A], [B]
  },
  SCALAR: {
    LOWERCASE: 'lowercase', // a, b, c
    GREEK: 'greek', // \\alpha, \\beta, \\lambda
  },
} as const;

export const LATEX_COMMANDS = {
  VECTOR: ['\\vec', '\\mathbf', '\\hat'],
  MATRIX: ['\\begin', '\\end', '\\mathbf'],
  FRACTION: ['\\frac'],
  OPERATORS: ['\\times', '\\cdot', '\\oplus'],
  SPACES: ['\\mathbb{R}', '\\mathbb{C}', '\\mathbb{Z}'],
  GREEK: ['\\alpha', '\\beta', '\\gamma', '\\delta', '\\lambda', '\\mu', '\\sigma'],
} as const;
