#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
C&C Remastered Match API Poller - MIT ECHTEN NEXUSCONTROL SPIELERN
Verwendet deine vorhandenen Spieler aus der Datenbank
"""

import time
import json
import logging
import random
from datetime import datetime, timedelta
from typing import Dict, List
import mysql.connector
from mysql.connector import Error

# Logging konfigurieren
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('match_poller.log'),
        logging.StreamHandler()
    ]
)

class CNCMatchPollerRealPlayers:
    def __init__(self, db_config: Dict):
        self.db_config = db_config
        
    def connect_db(self):
        """Stellt Verbindung zur Datenbank her"""
        try:
            conn = mysql.connector.connect(**self.db_config)
            return conn
        except Error as e:
            logging.error(f"Datenbankverbindung fehlgeschlagen: {e}")
            return None
    
    def get_real_players(self) -> List[Dict]:
        """Holt echte Spieler aus der NexusControl Datenbank"""
        conn = self.connect_db()
        if not conn:
            return []
        
        try:
            cursor = conn.cursor(dictionary=True)
            
            # Aktive Spieler aus der Datenbank holen
            cursor.execute("""
                SELECT SpielerID as player_id, Name as name 
                FROM Spieler 
                WHERE is_active = 1 
                AND Name IS NOT NULL 
                AND Name != ''
                ORDER BY RAND()
                LIMIT 20
            """)
            
            players = cursor.fetchall()
            logging.info(f"{len(players)} echte Spieler aus der Datenbank geladen")
            
            return players
            
        except Error as e:
            logging.error(f"Fehler beim Laden der Spieler: {e}")
            return []
        finally:
            cursor.close()
            conn.close()
    
    def generate_real_matches(self, game: str) -> List[Dict]:
        """Generiert Demo-Matches mit echten Spielern"""
        players = self.get_real_players()
        if len(players) < 2:
            logging.error("Nicht genug Spieler in der Datenbank!")
            return []
        
        matches = []
        
        # Maps für beide Spiele
        if game == "tiberian-dawn":
            maps = ["Canyon River", "Green Acres", "Tiberium Garden", "Desert Strike", "Siberian Conflict"]
        else:  # red-alert
            maps = ["Island Warfare", "Soviet Base", "Allies Fortress", "Winter Conflict", "Volcano Ridge"]
        
        # 5-8 Matches pro Spiel generieren
        num_matches = random.randint(5, 8)
        
        for i in range(num_matches):
            # Zufällige Spieler auswählen
            player1 = random.choice(players)
            player2 = random.choice([p for p in players if p['player_id'] != player1['player_id']])
            
            # Zufällige Faktionen wählen
            player1_faction = random.choice(['Allies', 'Soviet'])
            player2_faction = 'Soviet' if player1_faction == 'Allies' else 'Allies'
            
            # Zufällige Ergebnisse wählen
            player1_result = random.choice(['win', 'loss'])
            player2_result = 'loss' if player1_result == 'win' else 'win'
            
            # Realistische Spiel-Daten
            duration = random.randint(1200, 2400)  # 20-40 Minuten
            start_time = datetime.now() - timedelta(minutes=random.randint(10, 120))
            end_time = start_time + timedelta(seconds=duration)
            
            match = {
                'match_id': f"{game}_real_{int(time.time())}_{i}",
                'map_name': random.choice(maps),
                'duration_seconds': duration,
                'started_at': start_time,
                'ended_at': end_time,
                'match_type': random.choice(['ranked', 'custom']),
                'has_replay': random.choice([True, False]),
                'replay_url': f"https://replays.cnc.community/{game}_{i}.rep" if random.choice([True, False]) else None,
                'players': [
                    {
                        'player_id': str(player1['player_id']),
                        'name': player1['name'],
                        'faction': player1_faction,
                        'result': player1_result,
                        'final_score': random.randint(1000, 5000),
                        'resources_collected': random.randint(8000, 25000)
                    },
                    {
                        'player_id': str(player2['player_id']),
                        'name': player2['name'],
                        'faction': player2_faction,
                        'result': player2_result,
                        'final_score': random.randint(1000, 5000),
                        'resources_collected': random.randint(8000, 25000)
                    }
                ]
            }
            matches.append(match)
        
        return matches
    
    def save_match(self, conn, match: Dict) -> bool:
        """Speichert Match in Datenbank"""
        try:
            cursor = conn.cursor()
            
            match_id = match.get('match_id')
            if not match_id:
                return False
                
            # Prüfen ob Match schon existiert
            cursor.execute("SELECT match_id FROM matches WHERE match_id = %s", (match_id,))
            if cursor.fetchone():
                return False  # Bereits vorhanden
            
            # Match einfügen
            insert_match = """
                INSERT INTO matches (
                    match_id, map_name, duration_seconds, started_at, ended_at, 
                    match_type, has_replay, replay_url, api_source, created_at
                ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, NOW())
            """
            
            cursor.execute(insert_match, (
                match_id,
                match.get('map_name'),
                match.get('duration_seconds'),
                match.get('started_at'),
                match.get('ended_at'),
                match.get('match_type'),
                match.get('has_replay'),
                match.get('replay_url'),
                'nexus_control'  # API-Source
            ))
            
            # Alle Spieler speichern
            for player in match.get('players', []):
                player_id = player.get('player_id')
                player_name = player.get('name')
                
                if not player_id or not player_name:
                    continue
                
                # In players Tabelle speichern
                cursor.execute("""
                    INSERT INTO players (player_id, name, created_at, updated_at)
                    VALUES (%s, %s, NOW(), NOW())
                    ON DUPLICATE KEY UPDATE name = VALUES(name), updated_at = NOW()
                """, (player_id, player_name))
                
                # Match-Zuordnung speichern
                cursor.execute("""
                    INSERT INTO match_players (match_id, player_id, faction, result, created_at)
                    VALUES (%s, %s, %s, %s, NOW())
                """, (
                    match_id,
                    player_id,
                    player.get('faction', 'Unknown'),
                    player.get('result', 'unknown')
                ))
            
            conn.commit()
            logging.info(f"Real-Match gespeichert: {match_id} - {match.get('players', [{}])[0].get('name', 'Unknown')}")
            return True
            
        except Error as e:
            conn.rollback()
            logging.error(f"Fehler beim Speichern: {e}")
            return False
        finally:
            cursor.close()
    
    def run_polling_cycle(self):
        """Führt einen kompletten Polling-Zyklus durch"""
        logging.info("Starte Real-Polling-Zyklus...")
        
        conn = self.connect_db()
        if not conn:
            return
        
        try:
            # Beide Spiele abfragen
            games = ["tiberian-dawn", "red-alert"]
            total_saved = 0
            
            for game in games:
                matches = self.generate_real_matches(game)
                logging.info(f"{len(matches)} Real-Matches generiert für {game}")
                
                for match in matches:
                    if self.save_match(conn, match):
                        total_saved += 1
                
                # Kurze Pause zwischen Spielen
                time.sleep(1)
            
            logging.info(f"Real-Polling-Zyklus abgeschlossen: {total_saved} neue Matches")
            
        except Exception as e:
            logging.error(f"Fehler im Real-Polling-Zyklus: {e}")
        finally:
            conn.close()
    
    def run_daemon(self, interval: int = 300):
        """Startet den Daemon für kontinuierliches Polling"""
        logging.info(f"Starte CNC Match Poller Real Players Daemon (Intervall: {interval}s)")
        
        while True:
            try:
                self.run_polling_cycle()
                logging.info(f"Warte {interval} Sekunden bis zum nächsten Zyklus...")
                time.sleep(interval)
                
            except KeyboardInterrupt:
                logging.info("Real Players Daemon wird beendet...")
                break
            except Exception as e:
                logging.error(f"Unerwarteter Fehler: {e}")
                time.sleep(60)


def main():
    """Hauptfunktion"""
    # Datenbank-Konfiguration
    db_config = {
        'host': 'localhost',
        'database': 'NexusControl',
        'user': 'root',
        'password': 'HOk~k5$!0q',
        'charset': 'utf8mb4'
    }
    
    poller = CNCMatchPollerRealPlayers(db_config)
    
    # Einmaliger Testlauf
    print("=== Real Players Test-Lauf ===")
    poller.run_polling_cycle()
    
    # Fragen ob Daemon gestartet werden soll
    response = input("\nReal Players Daemon starten für kontinuierliches Polling? (y/n): ")
    if response.lower() == 'y':
        poller.run_daemon(interval=300)  # Alle 5 Minuten


if __name__ == "__main__":
    main()
