#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Quick Add Script für neue Minecraft Chat Logs
Filtert rohe Server-Logs und fügt sie automatisch zur chat-index.json hinzu
"""

import os
import json
import re
import sys
from datetime import datetime

# Set UTF-8 encoding for console output
if sys.platform == "win32":
    import codecs
    sys.stdout = codecs.getwriter("utf-8")(sys.stdout.detach())
    sys.stderr = codecs.getwriter("utf-8")(sys.stderr.detach())

def detect_gamemode_from_path(filepath):
    """Erkennt den Gamemode basierend auf dem Ordnernamen oder Dateinamen"""
    # Zuerst schauen wir in den Ordnernamen
    path_parts = filepath.replace('\\', '/').split('/')
    
    for part in reversed(path_parts):  # Von hinten nach vorne durch die Pfad-Teile
        part_lower = part.lower()
        
        # Direkte Gamemode-Erkennung aus Ordnernamen
        if part_lower in ['crea-1', 'creative-1', 'creative']:
            return 'crea-1'
        elif part_lower in ['survival-1', 'surv-1', 'survival']:
            return 'survival-1'
        elif part_lower in ['event', 'events', 'special']:
            return 'event'
        elif part_lower in ['test', 'testing', 'dev']:
            return 'test'
        
        # Pattern-basierte Erkennung
        if 'crea' in part_lower or 'creative' in part_lower:
            return 'crea-1'
        elif 'survival' in part_lower or 'surv' in part_lower:
            return 'survival-1'
        elif 'event' in part_lower or 'special' in part_lower:
            return 'event'
        elif 'test' in part_lower:
            return 'test'
    
    # Fallback: Dateiname analysieren
    filename = os.path.basename(filepath).lower()
    if 'crea' in filename or 'creative' in filename:
        return 'crea-1'
    elif 'survival' in filename or 'surv' in filename:
        return 'survival-1'
    elif 'event' in filename or 'special' in filename:
        return 'event'
    elif 'test' in filename:
        return 'test'
    
    return 'crea-1'  # Default

def detect_gamemode_from_filename(filename):
    """Legacy function - verwendet jetzt detect_gamemode_from_path"""
    return detect_gamemode_from_path(filename)

def extract_date_from_filename(filename):
    """Extrahiert das Datum aus dem Dateinamen"""
    # Pattern: DD.MM.YYYY oder DD-MM-YYYY oder YYYY-MM-DD
    date_patterns = [
        r'(\d{2})\.(\d{2})\.(\d{4})',  # DD.MM.YYYY
        r'(\d{2})-(\d{2})-(\d{4})',   # DD-MM-YYYY
        r'(\d{4})-(\d{2})-(\d{2})',   # YYYY-MM-DD
    ]
    
    for pattern in date_patterns:
        match = re.search(pattern, filename)
        if match:
            if pattern == date_patterns[2]:  # YYYY-MM-DD
                year, month, day = match.groups()
            else:  # DD.MM.YYYY or DD-MM-YYYY
                day, month, year = match.groups()
            
            try:
                date_obj = datetime(int(year), int(month), int(day))
                return date_obj.strftime('%Y-%m-%d')
            except ValueError:
                continue
    
    return datetime.now().strftime('%Y-%m-%d')

def analyze_filtered_log(filepath):
    """Analysiert eine gefilterte Log-Datei"""
    participants = set()
    message_count = 0
    
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                
                message_count += 1
                
                # Extrahiere Spielernamen aus verschiedenen Formaten
                # Chat: [Async Chat Thread - #0/INFO]: Admin ▎ SimolZimol : message
                chat_match = re.search(r': (?:Admin|Mod|Member) ▎ ([^:]+) :', line)
                if chat_match:
                    participants.add(chat_match.group(1).strip())
                
                # Join/Leave: Admin ▎ SimolZimol joined the game
                join_match = re.search(r': (?:Admin|Mod|Member) ▎ ([^j]+) joined', line)
                if join_match:
                    participants.add(join_match.group(1).strip())
                
                # Einfache Join/Leave: SimolZimol joined the game
                simple_join = re.search(r': ([^j]+) joined the game', line)
                if simple_join and '▎' not in line:
                    participants.add(simple_join.group(1).strip())
    
    except Exception as e:
        try:
            print(f"❌ Fehler beim Analysieren der Datei: {e}")
        except UnicodeEncodeError:
            print(f">> Fehler beim Analysieren der Datei: {e}")
        return [], 0
    
    return list(participants), message_count

def add_to_chat_index(chat_entry):
    """Fügt einen neuen Chat-Eintrag zur chat-index.json hinzu"""
    index_path = 'chat-logs/chat-index.json'
    
    try:
        with open(index_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
        
        # Handle both old and new format
        if isinstance(data, list):
            # Old format - convert to new
            chats = data
            categories = {
                "crea-1": {
                    "name": "🏰 Creative Mode",
                    "description": "Creative building sessions on the main server",
                    "color": "#4CAF50"
                },
                "survival-1": {
                    "name": "⛏️ Survival Mode", 
                    "description": "Survival adventures and base building",
                    "color": "#FF9800"
                },
                "event": {
                    "name": "🎉 Special Events",
                    "description": "Special events and community gatherings", 
                    "color": "#9C27B0"
                },
                "test": {
                    "name": "🔧 Testing & Setup",
                    "description": "Server testing and configuration sessions",
                    "color": "#607D8B"
                }
            }
            data = {
                "categories": categories,
                "chats": chats
            }
        
        # Add new chat
        data["chats"].append(chat_entry)
        
        # Save back
        with open(index_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=4, ensure_ascii=False)
            
        try:
            print(f"✅ Chat erfolgreich zur Index-Datei hinzugefügt!")
        except UnicodeEncodeError:
            print(f">> Chat erfolgreich zur Index-Datei hinzugefügt!")
        return True
        
    except Exception as e:
        try:
            print(f"❌ Fehler beim Aktualisieren der Index-Datei: {e}")
        except UnicodeEncodeError:
            print(f">> Fehler beim Aktualisieren der Index-Datei: {e}")
        return False

def is_already_filtered(filepath):
    """Prüft ob eine Datei bereits gefiltert ist (wenige Server-Logs)"""
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            
        if len(lines) == 0:
            return False
            
        # Zähle Server-Log-Zeilen vs Chat-Zeilen
        server_log_count = 0
        chat_count = 0
        
        for line in lines[:100]:  # Schaue nur erste 100 Zeilen an
            line = line.strip()
            if not line:
                continue
                
            # Server-spezifische Patterns
            if any(pattern in line for pattern in [
                'Server thread/INFO', 'main/INFO', 'ThreadedAnvilChunkStorage', 
                'Reloading ResourceManager', 'Starting minecraft server'
            ]):
                server_log_count += 1
            elif '[Async Chat Thread' in line or '] : ' in line:
                chat_count += 1
        
        # Wenn mehr Chat als Server-Logs, ist es wahrscheinlich schon gefiltert
        return chat_count > server_log_count
        
    except Exception:
        return False

def needs_filtering(filepath):
    """Bestimmt ob eine Datei gefiltert werden muss"""
    # Bereits gefilterte Dateien
    if '-filtered' in filepath or 'filtered' in filepath.lower():
        return False
    
    return not is_already_filtered(filepath)

def main():
    try:
        print(">> Quick Add - Minecraft Chat Log")
    except UnicodeEncodeError:
        print(">> Quick Add - Minecraft Chat Log")
    print("=" * 40)
    
    # Check for auto mode
    auto_mode = '--auto' in sys.argv
    if auto_mode:
        sys.argv.remove('--auto')
    
    if len(sys.argv) != 2:
        print("Usage: python quick_add.py <log_file> [--auto]")
        print("Beispiel: python quick_add.py raw-logs/crea-1/2020-07-25-1.log")
        print("         python quick_add.py chat-logs/bereits-gefiltert.txt")
        print("         python quick_add.py raw-logs/crea-1/2020-07-25-1.log --auto")
        return
    
    input_file = sys.argv[1]
    
    if not os.path.exists(input_file):
        try:
            print(f"❌ Datei '{input_file}' existiert nicht!")
        except UnicodeEncodeError:
            print(f">> Datei '{input_file}' existiert nicht!")
        return
    
    # Erkenne Gamemode aus dem vollständigen Pfad
    gamemode = detect_gamemode_from_path(input_file)
    try:
        print(f"🎮 Erkannter Gamemode: {gamemode}")
    except UnicodeEncodeError:
        print(f">> Erkannter Gamemode: {gamemode}")
    
    # Bestimme ob Filterung nötig ist
    needs_filter = needs_filtering(input_file)
    
    if needs_filter:
        try:
            print("🔄 Raw Log erkannt - wird gefiltert...")
        except UnicodeEncodeError:
            print(">> Raw Log erkannt - wird gefiltert...")
        
        # Generate filtered filename
        base_name = os.path.splitext(os.path.basename(input_file))[0]
        filtered_file = f"chat-logs/{gamemode}-{base_name}-filtered.txt"
        
        print(f"📥 Input: {input_file}")
        print(f"📤 Output: {filtered_file}")
        
        # Filter the raw log
        filter_result = os.system(f'python filter_raw_logs.py "{input_file}" "{filtered_file}"')
        
        if filter_result != 0 or not os.path.exists(filtered_file):
            try:
                print("❌ Filterung fehlgeschlagen!")
            except UnicodeEncodeError:
                print(">> Filterung fehlgeschlagen!")
            return
            
        process_file = filtered_file
    else:
        try:
            print("✅ Bereits gefilterte Datei erkannt - überspringe Filterung")
        except UnicodeEncodeError:
            print(">> Bereits gefilterte Datei erkannt - überspringe Filterung")
        process_file = input_file
    
    # Analyze the filtered log
    try:
        print("\n🔍 Analysiere Chat-Datei...")
    except UnicodeEncodeError:
        print("\n>> Analysiere Chat-Datei...")
    participants, message_count = analyze_filtered_log(process_file)
    
    # Extract metadata
    date = extract_date_from_filename(os.path.basename(process_file))
    
    # Generate chat entry
    gamemode_titles = {
        'crea-1': 'Creative Session',
        'survival-1': 'Survival Session',
        'event': 'Special Event',
        'test': 'Test Session'
    }
    
    # Verbesserte ID-Generierung
    date_parts = date.split('-')
    date_short = f"{date_parts[2]}.{date_parts[1]}.{date_parts[0]}"  # DD.MM.YYYY
    chat_id = f"{gamemode}-{date_short}"
    
    title = f"{gamemode_titles.get(gamemode, '📝 Session')} - {datetime.strptime(date, '%Y-%m-%d').strftime('%B %d, %Y')}"
    
    chat_entry = {
        "id": chat_id,
        "title": title,
        "description": f"Session with {len(participants)} players and {message_count} messages",
        "date": date,
        "category": gamemode,
        "participants": participants,
        "messages": message_count,
        "filename": os.path.basename(process_file),
        "mapDownload": {
            "available": False
        }
    }
    
    try:
        print(f"\n📊 Session Details:")
        print(f"   🆔 ID: {chat_id}")
        print(f"   📅 Datum: {date}")
        print(f"   🎮 Kategorie: {gamemode}")
        print(f"   💬 Nachrichten: {message_count}")
        print(f"   👥 Spieler: {', '.join(participants)}")
    except UnicodeEncodeError:
        print(f"\n>> Session Details:")
        print(f"   ID: {chat_id}")
        print(f"   Datum: {date}")
        print(f"   Kategorie: {gamemode}")
        print(f"   Nachrichten: {message_count}")
        print(f"   Spieler: {', '.join(participants)}")
    
    # Ask for confirmation
    if auto_mode:
        try:
            print(f"\n🤖 Automatischer Modus - füge zur chat-index.json hinzu...")
        except UnicodeEncodeError:
            print(f"\n>> Automatischer Modus - füge zur chat-index.json hinzu...")
        response = 'y'
    else:
        try:
            response = input(f"\n❓ Zur chat-index.json hinzufügen? (y/N): ")
        except UnicodeEncodeError:
            response = input(f"\n>> Zur chat-index.json hinzufügen? (y/N): ")
        
    if response.lower() in ['y', 'yes', 'j', 'ja']:
        if add_to_chat_index(chat_entry):
            try:
                print(f"\n🎉 Erfolgreich hinzugefügt! Die Webseite zeigt jetzt {len(participants)} Spieler und {message_count} Nachrichten an.")
            except UnicodeEncodeError:
                print(f"\n>> Erfolgreich hinzugefügt! Die Webseite zeigt jetzt {len(participants)} Spieler und {message_count} Nachrichten an.")
        else:
            try:
                print(f"\n❌ Fehler beim Hinzufügen!")
            except UnicodeEncodeError:
                print(f"\n>> Fehler beim Hinzufügen!")
    else:
        if needs_filter:
            try:
                print(f"\n📝 Abgebrochen. Die gefilterte Datei '{process_file}' wurde erstellt, aber nicht zur Index hinzugefügt.")
            except UnicodeEncodeError:
                print(f"\n>> Abgebrochen. Die gefilterte Datei '{process_file}' wurde erstellt, aber nicht zur Index hinzugefügt.")
        else:
            try:
                print(f"\n📝 Abgebrochen. Keine Änderungen vorgenommen.")
            except UnicodeEncodeError:
                print(f"\n>> Abgebrochen. Keine Änderungen vorgenommen.")

if __name__ == "__main__":
    main()
