import { EventEmitter } from 'events';

export interface ThemeConfig {
  name: string;
  primaryColor: string;
  secondaryColor: string;
  accentColor: string;
  backgroundColor: string;
  textColor: string;
  fontFamily: string;
  borderRadius: number;
  shadowIntensity: number;
}

export interface MechanicsConfig {
  speed: number; // 0.5 to 2.0
  complexity: number; // 1 to 5
  interactivity: number; // 1 to 5
  difficultyScaling: number; // 0.8 to 1.5
  rewardMultiplier: number; // 0.5 to 3.0
}

export interface RewardConfig {
  minWin: number;
  maxWin: number;
  jackpot: number;
  bonusChance: number; // 0 to 1
  freeSpinsChance: number;
  multiplierRange: [number, number];
}

export interface GameVariant {
  id: string;
  baseGameId: string;
  name: string;
  theme: ThemeConfig;
  mechanics: MechanicsConfig;
  rewards: RewardConfig;
  description: string;
  targetAudience: string;
  createdAt: Date;
}

/**
 * Game Customization Engine
 * Manages themes, mechanics, and reward configurations for games
 */
export class GameCustomizationEngine extends EventEmitter {
  private themes: Map<string, ThemeConfig> = new Map();
  private variants: Map<string, GameVariant> = new Map();

  constructor() {
    super();
    this.initializeDefaultThemes();
    console.log('[GameCustomization] Engine initialized');
  }

  /**
   * Initialize default themes
   */
  private initializeDefaultThemes(): void {
    const defaultThemes: ThemeConfig[] = [
      {
        name: 'Dark',
        primaryColor: '#1a1a2e',
        secondaryColor: '#16213e',
        accentColor: '#0f3460',
        backgroundColor: '#0f0f1e',
        textColor: '#ffffff',
        fontFamily: 'Arial, sans-serif',
        borderRadius: 8,
        shadowIntensity: 0.5,
      },
      {
        name: 'Neon',
        primaryColor: '#0a0e27',
        secondaryColor: '#1a1a2e',
        accentColor: '#00ff88',
        backgroundColor: '#000000',
        textColor: '#00ff88',
        fontFamily: 'Courier New, monospace',
        borderRadius: 4,
        shadowIntensity: 1,
      },
      {
        name: 'Gold',
        primaryColor: '#2d1810',
        secondaryColor: '#5a3a1a',
        accentColor: '#ffd700',
        backgroundColor: '#1a0f08',
        textColor: '#ffd700',
        fontFamily: 'Georgia, serif',
        borderRadius: 12,
        shadowIntensity: 0.7,
      },
      {
        name: 'Ocean',
        primaryColor: '#0a3d62',
        secondaryColor: '#1b6ca8',
        accentColor: '#00d4ff',
        backgroundColor: '#051e3e',
        textColor: '#ffffff',
        fontFamily: 'Verdana, sans-serif',
        borderRadius: 6,
        shadowIntensity: 0.4,
      },
      {
        name: 'Forest',
        primaryColor: '#1b4332',
        secondaryColor: '#2d6a4f',
        accentColor: '#52b788',
        backgroundColor: '#081c15',
        textColor: '#d8f3dc',
        fontFamily: 'Trebuchet MS, sans-serif',
        borderRadius: 10,
        shadowIntensity: 0.6,
      },
    ];

    for (const theme of defaultThemes) {
      this.themes.set(theme.name.toLowerCase(), theme);
    }

    console.log(`[GameCustomization] Loaded ${defaultThemes.length} default themes`);
  }

  /**
   * Get theme by name
   */
  getTheme(name: string): ThemeConfig | undefined {
    return this.themes.get(name.toLowerCase());
  }

  /**
   * Create custom theme
   */
  createTheme(config: ThemeConfig): ThemeConfig {
    this.themes.set(config.name.toLowerCase(), config);
    this.emit('themeCreated', config);
    console.log(`[GameCustomization] Theme created: ${config.name}`);
    return config;
  }

  /**
   * Get all available themes
   */
  getAllThemes(): ThemeConfig[] {
    return Array.from(this.themes.values());
  }

  /**
   * Create game variant
   */
  createVariant(baseGameId: string, config: Partial<GameVariant>): GameVariant {
    const variant: GameVariant = {
      id: `variant-${Date.now()}`,
      baseGameId,
      name: config.name || 'Unnamed Variant',
      theme: config.theme || this.themes.get('dark')!,
      mechanics: config.mechanics || this.getDefaultMechanics(),
      rewards: config.rewards || this.getDefaultRewards(),
      description: config.description || '',
      targetAudience: config.targetAudience || 'all',
      createdAt: new Date(),
    };

    this.variants.set(variant.id, variant);
    this.emit('variantCreated', variant);
    console.log(`[GameCustomization] Variant created: ${variant.id}`);

    return variant;
  }

  /**
   * Get default mechanics configuration
   */
  private getDefaultMechanics(): MechanicsConfig {
    return {
      speed: 1.0,
      complexity: 2,
      interactivity: 3,
      difficultyScaling: 1.0,
      rewardMultiplier: 1.0,
    };
  }

  /**
   * Get default rewards configuration
   */
  private getDefaultRewards(): RewardConfig {
    return {
      minWin: 10,
      maxWin: 1000,
      jackpot: 10000,
      bonusChance: 0.1,
      freeSpinsChance: 0.05,
      multiplierRange: [1, 5],
    };
  }

  /**
   * Adjust difficulty level
   */
  adjustDifficulty(variantId: string, level: 'easy' | 'medium' | 'hard' | 'extreme'): GameVariant | undefined {
    const variant = this.variants.get(variantId);
    if (!variant) return undefined;

    const difficultyMap = {
      easy: { speed: 0.7, complexity: 1, rewardMultiplier: 1.5 },
      medium: { speed: 1.0, complexity: 2, rewardMultiplier: 1.0 },
      hard: { speed: 1.3, complexity: 4, rewardMultiplier: 0.8 },
      extreme: { speed: 1.8, complexity: 5, rewardMultiplier: 0.5 },
    };

    const settings = difficultyMap[level];
    variant.mechanics.speed = settings.speed;
    variant.mechanics.complexity = settings.complexity;
    variant.rewards.rewardMultiplier = settings.rewardMultiplier;

    this.emit('difficultyAdjusted', { variantId, level });
    console.log(`[GameCustomization] Difficulty adjusted: ${variantId} -> ${level}`);

    return variant;
  }

  /**
   * Adjust reward configuration
   */
  adjustRewards(variantId: string, rewards: Partial<RewardConfig>): GameVariant | undefined {
    const variant = this.variants.get(variantId);
    if (!variant) return undefined;

    variant.rewards = { ...variant.rewards, ...rewards };

    this.emit('rewardsAdjusted', { variantId, rewards });
    console.log(`[GameCustomization] Rewards adjusted: ${variantId}`);

    return variant;
  }

  /**
   * Adjust game mechanics
   */
  adjustMechanics(variantId: string, mechanics: Partial<MechanicsConfig>): GameVariant | undefined {
    const variant = this.variants.get(variantId);
    if (!variant) return undefined;

    // Validate ranges
    if (mechanics.speed !== undefined) {
      mechanics.speed = Math.max(0.5, Math.min(2.0, mechanics.speed));
    }
    if (mechanics.complexity !== undefined) {
      mechanics.complexity = Math.max(1, Math.min(5, mechanics.complexity));
    }
    if (mechanics.interactivity !== undefined) {
      mechanics.interactivity = Math.max(1, Math.min(5, mechanics.interactivity));
    }

    variant.mechanics = { ...variant.mechanics, ...mechanics };

    this.emit('mechanicsAdjusted', { variantId, mechanics });
    console.log(`[GameCustomization] Mechanics adjusted: ${variantId}`);

    return variant;
  }

  /**
   * Get variant by ID
   */
  getVariant(variantId: string): GameVariant | undefined {
    return this.variants.get(variantId);
  }

  /**
   * Get all variants for a game
   */
  getVariantsForGame(baseGameId: string): GameVariant[] {
    return Array.from(this.variants.values()).filter((v) => v.baseGameId === baseGameId);
  }

  /**
   * Generate CSS from theme
   */
  generateThemeCSS(theme: ThemeConfig): string {
    return `
:root {
  --primary-color: ${theme.primaryColor};
  --secondary-color: ${theme.secondaryColor};
  --accent-color: ${theme.accentColor};
  --bg-color: ${theme.backgroundColor};
  --text-color: ${theme.textColor};
  --border-radius: ${theme.borderRadius}px;
  --shadow-intensity: ${theme.shadowIntensity};
}

* {
  font-family: ${theme.fontFamily};
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

button, .btn {
  background-color: var(--accent-color);
  color: var(--text-color);
  border-radius: var(--border-radius);
  box-shadow: 0 4px 8px rgba(0, 0, 0, var(--shadow-intensity));
}

.card, .panel {
  background-color: var(--primary-color);
  border-radius: var(--border-radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, var(--shadow-intensity));
}

.accent {
  color: var(--accent-color);
}
    `.trim();
  }

  /**
   * Export variant configuration
   */
  exportVariant(variantId: string): string {
    const variant = this.variants.get(variantId);
    if (!variant) return '';

    return JSON.stringify(variant, null, 2);
  }

  /**
   * Import variant configuration
   */
  importVariant(config: string): GameVariant | null {
    try {
      const parsed = JSON.parse(config);
      const variant: GameVariant = {
        ...parsed,
        id: `variant-${Date.now()}`,
        createdAt: new Date(),
      };

      this.variants.set(variant.id, variant);
      this.emit('variantImported', variant);
      console.log(`[GameCustomization] Variant imported: ${variant.id}`);

      return variant;
    } catch (error) {
      console.error('[GameCustomization] Import failed:', error);
      return null;
    }
  }

  /**
   * Get variant statistics
   */
  getVariantStats() {
    return {
      totalVariants: this.variants.size,
      totalThemes: this.themes.size,
      variantsByDifficulty: {
        easy: Array.from(this.variants.values()).filter((v) => v.mechanics.complexity <= 2).length,
        medium: Array.from(this.variants.values()).filter((v) => v.mechanics.complexity === 3).length,
        hard: Array.from(this.variants.values()).filter((v) => v.mechanics.complexity >= 4).length,
      },
    };
  }

  /**
   * Clear all data
   */
  clear(): void {
    this.variants.clear();
    console.log('[GameCustomization] Engine cleared');
  }
}

export const gameCustomizationEngine = new GameCustomizationEngine();
