import { EventEmitter } from 'events';

export interface GameTemplate {
  id: string;
  name: string;
  genre: 'slot' | 'puzzle' | 'action' | 'strategy' | 'arcade' | 'card';
  description: string;
  htmlTemplate: string;
  cssTemplate: string;
  jsTemplate: string;
  variables: TemplateVariable[];
  metadata: {
    author: string;
    version: string;
    createdAt: Date;
    updatedAt: Date;
    downloads: number;
    rating: number;
    tags: string[];
  };
  performance: {
    avgLoadTime: number;
    avgEngagement: number;
    successRate: number;
  };
}

export interface TemplateVariable {
  name: string;
  type: 'string' | 'number' | 'color' | 'boolean';
  defaultValue: any;
  description: string;
  options?: any[];
}

/**
 * Game Template Library Service
 * Manages reusable game templates for faster AI game generation
 */
export class GameTemplateLibraryService extends EventEmitter {
  private templates: Map<string, GameTemplate> = new Map();
  private genreTemplates: Map<string, GameTemplate[]> = new Map();

  constructor() {
    super();
    this.initializeDefaultTemplates();
    console.log('[GameTemplateLibrary] Service initialized');
  }

  /**
   * Initialize default templates
   */
  private initializeDefaultTemplates(): void {
    const templates: GameTemplate[] = [
      {
        id: 'template-slot-classic',
        name: 'Classic Slot Machine',
        genre: 'slot',
        description: 'Traditional 3-reel slot machine with paylines',
        htmlTemplate: `
<div id="slot-machine">
  <div class="reels">
    <div class="reel" id="reel-1"></div>
    <div class="reel" id="reel-2"></div>
    <div class="reel" id="reel-3"></div>
  </div>
  <div class="controls">
    <button id="spin-btn">SPIN</button>
    <input type="number" id="bet-input" placeholder="Bet amount">
    <div id="balance">Balance: {{balance}}</div>
  </div>
</div>
        `,
        cssTemplate: `
#slot-machine {
  background: linear-gradient(135deg, {{primaryColor}}, {{secondaryColor}});
  padding: 20px;
  border-radius: 10px;
}

.reels {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
}

.reel {
  width: 100px;
  height: 100px;
  background: {{accentColor}};
  border-radius: 5px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  font-weight: bold;
}

.controls {
  display: flex;
  gap: 10px;
  align-items: center;
}

button {
  padding: 10px 20px;
  background: {{accentColor}};
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
        `,
        jsTemplate: `
const symbols = ['🍎', '🍊', '🍋', '🍌', '🍉'];
let balance = {{initialBalance}};
let isSpinning = false;

document.getElementById('spin-btn').addEventListener('click', spin);

function spin() {
  if (isSpinning) return;
  
  const bet = parseFloat(document.getElementById('bet-input').value) || 1;
  if (bet > balance) {
    alert('Insufficient balance');
    return;
  }
  
  isSpinning = true;
  balance -= bet;
  
  const results = [
    symbols[Math.floor(Math.random() * symbols.length)],
    symbols[Math.floor(Math.random() * symbols.length)],
    symbols[Math.floor(Math.random() * symbols.length)]
  ];
  
  animateReels(results, bet);
}

function animateReels(results, bet) {
  setTimeout(() => {
    document.getElementById('reel-1').textContent = results[0];
    document.getElementById('reel-2').textContent = results[1];
    document.getElementById('reel-3').textContent = results[2];
    
    if (results[0] === results[1] && results[1] === results[2]) {
      const win = bet * {{winMultiplier}};
      balance += win;
      alert('WIN! +' + win);
    }
    
    updateBalance();
    isSpinning = false;
  }, 1000);
}

function updateBalance() {
  document.getElementById('balance').textContent = 'Balance: ' + balance.toFixed(2);
}
        `,
        variables: [
          { name: 'primaryColor', type: 'color', defaultValue: '#1a1a2e', description: 'Primary background color' },
          { name: 'secondaryColor', type: 'color', defaultValue: '#16213e', description: 'Secondary background color' },
          { name: 'accentColor', type: 'color', defaultValue: '#0f3460', description: 'Accent color' },
          { name: 'initialBalance', type: 'number', defaultValue: 1000, description: 'Starting balance' },
          { name: 'winMultiplier', type: 'number', defaultValue: 5, description: 'Win multiplier' },
        ],
        metadata: {
          author: 'CoinKrazy',
          version: '1.0.0',
          createdAt: new Date(),
          updatedAt: new Date(),
          downloads: 0,
          rating: 4.5,
          tags: ['slot', 'classic', 'simple'],
        },
        performance: {
          avgLoadTime: 0.5,
          avgEngagement: 8.2,
          successRate: 0.95,
        },
      },
      {
        id: 'template-puzzle-match3',
        name: 'Match-3 Puzzle',
        genre: 'puzzle',
        description: 'Match 3 or more tiles to clear them',
        htmlTemplate: `<div id="puzzle-game"><div class="grid" id="grid"></div></div>`,
        cssTemplate: `#puzzle-game { background: {{primaryColor}}; padding: 20px; }`,
        jsTemplate: `// Match-3 game logic`,
        variables: [
          { name: 'gridSize', type: 'number', defaultValue: 4, description: 'Grid size (4x4, 5x5, etc)' },
          { name: 'primaryColor', type: 'color', defaultValue: '#1a1a2e', description: 'Background color' },
        ],
        metadata: {
          author: 'CoinKrazy',
          version: '1.0.0',
          createdAt: new Date(),
          updatedAt: new Date(),
          downloads: 0,
          rating: 4.3,
          tags: ['puzzle', 'match3', 'casual'],
        },
        performance: {
          avgLoadTime: 0.8,
          avgEngagement: 7.8,
          successRate: 0.92,
        },
      },
    ];

    for (const template of templates) {
      this.templates.set(template.id, template);

      if (!this.genreTemplates.has(template.genre)) {
        this.genreTemplates.set(template.genre, []);
      }
      this.genreTemplates.get(template.genre)!.push(template);
    }

    console.log(`[GameTemplateLibrary] Loaded ${templates.length} default templates`);
  }

  /**
   * Get template by ID
   */
  getTemplate(templateId: string): GameTemplate | undefined {
    return this.templates.get(templateId);
  }

  /**
   * Get templates by genre
   */
  getTemplatesByGenre(genre: string): GameTemplate[] {
    return this.genreTemplates.get(genre) || [];
  }

  /**
   * Get all templates
   */
  getAllTemplates(): GameTemplate[] {
    return Array.from(this.templates.values());
  }

  /**
   * Create custom template
   */
  createTemplate(template: Partial<GameTemplate>): GameTemplate {
    const newTemplate: GameTemplate = {
      id: `template-${Date.now()}`,
      name: template.name || 'Untitled Template',
      genre: template.genre || 'slot',
      description: template.description || '',
      htmlTemplate: template.htmlTemplate || '',
      cssTemplate: template.cssTemplate || '',
      jsTemplate: template.jsTemplate || '',
      variables: template.variables || [],
      metadata: {
        author: 'Custom',
        version: '1.0.0',
        createdAt: new Date(),
        updatedAt: new Date(),
        downloads: 0,
        rating: 0,
        tags: template.metadata?.tags || [],
      },
      performance: {
        avgLoadTime: 0,
        avgEngagement: 0,
        successRate: 0,
      },
    };

    this.templates.set(newTemplate.id, newTemplate);

    if (!this.genreTemplates.has(newTemplate.genre)) {
      this.genreTemplates.set(newTemplate.genre, []);
    }
    this.genreTemplates.get(newTemplate.genre)!.push(newTemplate);

    this.emit('templateCreated', newTemplate);
    console.log(`[GameTemplateLibrary] Template created: ${newTemplate.id}`);

    return newTemplate;
  }

  /**
   * Update template
   */
  updateTemplate(templateId: string, updates: Partial<GameTemplate>): GameTemplate | undefined {
    const template = this.templates.get(templateId);
    if (!template) return undefined;

    Object.assign(template, updates);
    template.metadata.updatedAt = new Date();

    this.emit('templateUpdated', template);
    console.log(`[GameTemplateLibrary] Template updated: ${templateId}`);

    return template;
  }

  /**
   * Render template with variables
   */
  renderTemplate(templateId: string, variables: Record<string, any>): string {
    const template = this.templates.get(templateId);
    if (!template) return '';

    let html = template.htmlTemplate;
    let css = template.cssTemplate;
    let js = template.jsTemplate;

    // Replace variables
    for (const [key, value] of Object.entries(variables)) {
      const regex = new RegExp(`{{${key}}}`, 'g');
      html = html.replace(regex, String(value));
      css = css.replace(regex, String(value));
      js = js.replace(regex, String(value));
    }

    return `
<html>
<head>
<style>${css}</style>
</head>
<body>
${html}
<script>${js}</script>
</body>
</html>
    `;
  }

  /**
   * Get template statistics
   */
  getTemplateStats() {
    const allTemplates = Array.from(this.templates.values());

    return {
      totalTemplates: allTemplates.length,
      byGenre: {
        slot: this.genreTemplates.get('slot')?.length || 0,
        puzzle: this.genreTemplates.get('puzzle')?.length || 0,
        action: this.genreTemplates.get('action')?.length || 0,
        strategy: this.genreTemplates.get('strategy')?.length || 0,
        arcade: this.genreTemplates.get('arcade')?.length || 0,
        card: this.genreTemplates.get('card')?.length || 0,
      },
      avgRating: allTemplates.reduce((sum, t) => sum + t.metadata.rating, 0) / allTemplates.length,
      mostDownloaded: allTemplates.sort((a, b) => b.metadata.downloads - a.metadata.downloads)[0],
      topPerformer: allTemplates.sort((a, b) => b.performance.avgEngagement - a.performance.avgEngagement)[0],
    };
  }

  /**
   * Search templates
   */
  searchTemplates(query: string): GameTemplate[] {
    const lowerQuery = query.toLowerCase();

    return Array.from(this.templates.values()).filter(
      (t) =>
        t.name.toLowerCase().includes(lowerQuery) ||
        t.description.toLowerCase().includes(lowerQuery) ||
        t.metadata.tags.some((tag) => tag.toLowerCase().includes(lowerQuery))
    );
  }

  /**
   * Clear all data
   */
  clear(): void {
    this.templates.clear();
    this.genreTemplates.clear();
    console.log('[GameTemplateLibrary] Service cleared');
  }
}

export const gameTemplateLibraryService = new GameTemplateLibraryService();
