#!/usr/bin/env python3
"""
KI-Einstiegsscript für EspoCRM Projekt
======================================
Gibt einen vollständigen Überblick über das Projekt aus:
- README.md Inhalt
- Automatisch ermittelte Projektstruktur
- Entitäten und ihre Felder
- Beziehungen zwischen Entitäten
- Custom PHP Klassen
- Workflows
- Frontend Anpassungen

Ziel: KI erhält aktuellen Informationsstand für die Programmierung
"""

import json
import os
from pathlib import Path
from collections import defaultdict
from typing import Dict, List, Set

# Basis-Pfad des Projekts
BASE_PATH = Path("/var/lib/docker/volumes/vmh-espocrm_espocrm/_data")
CUSTOM_PATH = BASE_PATH / "custom/Espo/Custom"
README_PATH = BASE_PATH / "README.md"


def print_section(title: str, symbol: str = "="):
    """Gibt eine formatierte Section-Überschrift aus."""
    print(f"\n{symbol * 80}")
    print(f"{title.center(80)}")
    print(f"{symbol * 80}\n")


def print_subsection(title: str):
    """Gibt eine Unterüberschrift aus."""
    print(f"\n{'─' * 80}")
    print(f"► {title}")
    print(f"{'─' * 80}")


def read_readme():
    """Hinweis auf README.md - wird nicht direkt ausgegeben."""
    # README.md wird nicht ausgegeben - zu lang für direkte Ausgabe
    # Hinweis erfolgt am Ende des Scripts
    pass


def analyze_entities():
    """Analysiert alle Custom Entitäten und ihre Definitionen."""
    print_section("ENTITÄTEN ANALYSE", "=")
    
    entity_defs_path = CUSTOM_PATH / "Resources/metadata/entityDefs"
    scopes_path = CUSTOM_PATH / "Resources/metadata/scopes"
    
    if not entity_defs_path.exists():
        print("⚠️  Keine Custom Entitäten gefunden!")
        return {}
    
    entities = {}
    
    # Alle entityDefs Dateien durchgehen
    for entity_file in sorted(entity_defs_path.glob("*.json")):
        entity_name = entity_file.stem
        
        try:
            with open(entity_file, 'r', encoding='utf-8') as f:
                entity_def = json.load(f)
            
            # Scope-Informationen laden
            scope_info = {}
            scope_file = scopes_path / f"{entity_name}.json"
            if scope_file.exists():
                with open(scope_file, 'r', encoding='utf-8') as f:
                    scope_info = json.load(f)
            
            entities[entity_name] = {
                'def': entity_def,
                'scope': scope_info,
                'file': entity_file
            }
            
            print_subsection(f"Entität: {entity_name}")
            
            # Scope Informationen
            if scope_info:
                print("\n📋 Scope:")
                for key, value in scope_info.items():
                    if key in ['entity', 'module', 'object', 'tab', 'acl', 'customizable', 
                               'stream', 'disabled', 'type', 'isCustom']:
                        print(f"   • {key}: {value}")
            
            # Felder
            if 'fields' in entity_def and entity_def['fields']:
                print(f"\n🔧 Felder ({len(entity_def['fields'])}):")
                for field_name, field_def in sorted(entity_def['fields'].items()):
                    field_type = field_def.get('type', 'unknown')
                    required = " [REQUIRED]" if field_def.get('required') else ""
                    disabled = " [DISABLED]" if field_def.get('disabled') else ""
                    isCustom = " [CUSTOM]" if field_def.get('isCustom') else ""
                    
                    extra_info = []
                    if field_type == 'enum':
                        options = field_def.get('options', [])
                        extra_info.append(f"options: {len(options)}")
                    elif field_type == 'link':
                        entity = field_def.get('entity', 'unknown')
                        extra_info.append(f"→ {entity}")
                    elif field_type in ['varchar', 'text']:
                        if 'maxLength' in field_def:
                            extra_info.append(f"max: {field_def['maxLength']}")
                    elif field_type == 'currency':
                        extra_info.append("€")
                    
                    extra_str = f" ({', '.join(extra_info)})" if extra_info else ""
                    print(f"   • {field_name}: {field_type}{extra_str}{required}{disabled}{isCustom}")
            
            # Beziehungen (Links)
            if 'links' in entity_def and entity_def['links']:
                print(f"\n🔗 Beziehungen ({len(entity_def['links'])}):")
                for link_name, link_def in sorted(entity_def['links'].items()):
                    link_type = link_def.get('type', 'unknown')
                    foreign_entity = link_def.get('entity', 'unknown')
                    foreign_link = link_def.get('foreign', 'N/A')
                    relation_name = link_def.get('relationName', '')
                    disabled = " [DISABLED]" if link_def.get('disabled') else ""
                    
                    relation_info = f" (relationName: {relation_name})" if relation_name else ""
                    print(f"   • {link_name} [{link_type}] → {foreign_entity}.{foreign_link}{relation_info}{disabled}")
            
            # Formula Scripts
            formula_file = CUSTOM_PATH / f"Resources/metadata/formula/{entity_name}.json"
            if formula_file.exists():
                with open(formula_file, 'r', encoding='utf-8') as f:
                    formula_def = json.load(f)
                print(f"\n⚡ Formula Scripts:")
                for script_type in ['beforeSaveScript', 'beforeSaveApiScript', 'afterSaveScript']:
                    if script_type in formula_def:
                        script = formula_def[script_type]
                        lines = script.count('\n') + 1
                        print(f"   • {script_type}: {lines} Zeilen")
            
            print()
            
        except json.JSONDecodeError as e:
            print(f"❌ Fehler beim Parsen von {entity_file.name}: {e}")
        except Exception as e:
            print(f"❌ Fehler bei {entity_file.name}: {e}")
    
    return entities


def analyze_relationships(entities: Dict):
    """Analysiert Beziehungen zwischen Entitäten."""
    print_section("BEZIEHUNGSGRAPH", "=")
    
    # Sammle alle Beziehungen
    relationships = defaultdict(list)
    
    for entity_name, entity_data in entities.items():
        entity_def = entity_data['def']
        if 'links' not in entity_def:
            continue
        
        for link_name, link_def in entity_def['links'].items():
            if link_def.get('disabled'):
                continue
            
            target_entity = link_def.get('entity')
            link_type = link_def.get('type', 'unknown')
            
            if target_entity:
                relationships[entity_name].append({
                    'link_name': link_name,
                    'type': link_type,
                    'target': target_entity,
                    'foreign': link_def.get('foreign', 'N/A')
                })
    
    # Gib Beziehungsgraph aus
    for entity_name in sorted(relationships.keys()):
        links = relationships[entity_name]
        if links:
            print(f"\n{entity_name}:")
            for link in links:
                arrow = "→" if link['type'] in ['belongsTo', 'hasOne'] else "⇄"
                print(f"   {arrow} {link['link_name']} [{link['type']}] → {link['target']}")


def analyze_custom_classes():
    """Analysiert Custom PHP Klassen."""
    print_section("CUSTOM PHP KLASSEN", "=")
    
    classes_path = CUSTOM_PATH / "Classes"
    
    if not classes_path.exists():
        print("ℹ️  Keine Custom PHP Klassen gefunden.")
        return
    
    php_files = list(classes_path.rglob("*.php"))
    
    if not php_files:
        print("ℹ️  Keine Custom PHP Klassen gefunden.")
        return
    
    # Gruppiere nach Typ
    by_type = defaultdict(list)
    
    for php_file in php_files:
        relative_path = php_file.relative_to(classes_path)
        parts = relative_path.parts
        
        if len(parts) > 0:
            class_type = parts[0]
            by_type[class_type].append(relative_path)
    
    for class_type in sorted(by_type.keys()):
        print(f"\n📦 {class_type}:")
        for file_path in sorted(by_type[class_type]):
            print(f"   • {file_path}")


def analyze_workflows():
    """Analysiert Workflows."""
    print_section("WORKFLOWS", "=")
    
    workflows_path = BASE_PATH / "custom/workflows"
    
    if not workflows_path.exists():
        print("ℹ️  Keine Workflows gefunden.")
        return
    
    workflow_files = list(workflows_path.glob("*.json"))
    
    if not workflow_files:
        print("ℹ️  Keine Workflows gefunden.")
        return
    
    for workflow_file in sorted(workflow_files):
        try:
            with open(workflow_file, 'r', encoding='utf-8') as f:
                workflow = json.load(f)
            
            name = workflow.get('name', workflow_file.stem)
            entity = workflow.get('entityType', 'N/A')
            is_active = workflow.get('isActive', False)
            status = "✓ AKTIV" if is_active else "✗ INAKTIV"
            
            print(f"\n📋 {name} ({workflow_file.name})")
            print(f"   Entität: {entity}")
            print(f"   Status: {status}")
            
            # Trigger-Typ
            if 'type' in workflow:
                print(f"   Trigger: {workflow['type']}")
            
            # Aktionen
            if 'actions' in workflow:
                actions = workflow['actions']
                print(f"   Aktionen ({len(actions)}):")
                for action in actions[:5]:  # Erste 5 Aktionen
                    action_type = action.get('type', 'unknown')
                    print(f"      • {action_type}")
                if len(actions) > 5:
                    print(f"      ... und {len(actions) - 5} weitere")
        
        except Exception as e:
            print(f"❌ Fehler beim Lesen von {workflow_file.name}: {e}")


def analyze_frontend():
    """Analysiert Frontend Anpassungen."""
    print_section("FRONTEND ANPASSUNGEN", "=")
    
    # JavaScript
    js_path = BASE_PATH / "client/custom/src"
    if js_path.exists():
        js_files = list(js_path.rglob("*.js"))
        if js_files:
            print_subsection("JavaScript Files")
            for js_file in sorted(js_files):
                relative = js_file.relative_to(js_path)
                print(f"   • {relative}")
    
    # CSS
    css_path = BASE_PATH / "client/custom/css"
    if css_path.exists():
        css_files = list(css_path.glob("*.css"))
        if css_files:
            print_subsection("CSS Files")
            for css_file in sorted(css_files):
                print(f"   • {css_file.name}")
    
    # App Client Config
    client_config = CUSTOM_PATH / "Resources/metadata/app/client.json"
    if client_config.exists():
        print_subsection("App Client Config")
        try:
            with open(client_config, 'r', encoding='utf-8') as f:
                config = json.load(f)
            
            if 'cssList' in config:
                print("   CSS List:")
                for css in config['cssList']:
                    if css != "__APPEND__":
                        print(f"      • {css}")
            
            if 'scriptList' in config:
                print("   Script List:")
                for script in config['scriptList']:
                    if script != "__APPEND__":
                        print(f"      • {script}")
        
        except Exception as e:
            print(f"   ❌ Fehler: {e}")


def analyze_layouts():
    """Analysiert Custom Layouts."""
    print_section("CUSTOM LAYOUTS", "=")
    
    layouts_path = CUSTOM_PATH / "Resources/metadata/layouts"
    
    if not layouts_path.exists():
        print("ℹ️  Keine Custom Layouts gefunden.")
        return
    
    # Gruppiere nach Entität
    entities = defaultdict(list)
    
    for layout_file in layouts_path.rglob("*.json"):
        relative = layout_file.relative_to(layouts_path)
        entity = relative.parts[0] if len(relative.parts) > 1 else "unknown"
        layout_type = relative.stem
        entities[entity].append(layout_type)
    
    for entity in sorted(entities.keys()):
        layouts = sorted(entities[entity])
        print(f"\n{entity}:")
        print(f"   Layouts: {', '.join(layouts)}")


def analyze_i18n():
    """Analysiert Internationalisierung."""
    print_section("INTERNATIONALISIERUNG (i18n)", "=")
    
    i18n_path = CUSTOM_PATH / "Resources/i18n"
    
    if not i18n_path.exists():
        print("ℹ️  Keine i18n Dateien gefunden.")
        return
    
    languages = [d.name for d in i18n_path.iterdir() if d.is_dir()]
    
    print(f"Unterstützte Sprachen: {', '.join(sorted(languages))}")
    
    for lang in sorted(languages):
        lang_path = i18n_path / lang
        json_files = list(lang_path.glob("*.json"))
        
        if json_files:
            print(f"\n{lang}:")
            print(f"   Übersetzungsdateien: {len(json_files)}")
            
            # Zähle Labels
            total_labels = 0
            for json_file in json_files:
                try:
                    with open(json_file, 'r', encoding='utf-8') as f:
                        data = json.load(f)
                        # Rekursiv Labels zählen
                        def count_labels(obj):
                            if isinstance(obj, dict):
                                return sum(count_labels(v) for v in obj.values())
                            elif isinstance(obj, str):
                                return 1
                            return 0
                        total_labels += count_labels(data)
                except:
                    pass
            
            print(f"   Geschätzte Labels: ~{total_labels}")


def print_quick_stats():
    """Gibt eine Schnellübersicht aus."""
    print_section("SCHNELLÜBERSICHT", "=")
    
    stats = {}
    
    # Entitäten
    entity_defs_path = CUSTOM_PATH / "Resources/metadata/entityDefs"
    if entity_defs_path.exists():
        stats['Entities'] = len(list(entity_defs_path.glob("*.json")))
    
    # PHP Klassen
    classes_path = CUSTOM_PATH / "Classes"
    if classes_path.exists():
        stats['PHP Classes'] = len(list(classes_path.rglob("*.php")))
    
    # Workflows
    workflows_path = BASE_PATH / "custom/workflows"
    if workflows_path.exists():
        stats['Workflows'] = len(list(workflows_path.glob("*.json")))
    
    # JS Files
    js_path = BASE_PATH / "client/custom/src"
    if js_path.exists():
        stats['JavaScript Files'] = len(list(js_path.rglob("*.js")))
    
    # CSS Files
    css_path = BASE_PATH / "client/custom/css"
    if css_path.exists():
        stats['CSS Files'] = len(list(css_path.glob("*.css")))
    
    # Layouts
    layouts_path = CUSTOM_PATH / "Resources/metadata/layouts"
    if layouts_path.exists():
        stats['Custom Layouts'] = len(list(layouts_path.rglob("*.json")))
    
    # i18n
    i18n_path = CUSTOM_PATH / "Resources/i18n"
    if i18n_path.exists():
        languages = [d.name for d in i18n_path.iterdir() if d.is_dir()]
        stats['Languages'] = len(languages)
    
    print("📊 Projekt-Statistiken:\n")
    for key, value in stats.items():
        print(f"   • {key:<20} {value:>5}")


def main():
    """Hauptfunktion - führt alle Analysen aus."""
    print("\n" + "=" * 80)
    print("KI-EINSTIEGSSCRIPT FÜR ESPOCRM PROJEKT".center(80))
    print("Automatische Projekt-Analyse für KI-basierte Programmierung".center(80))
    print("=" * 80)
    
    # 1. Schnellübersicht
    print_quick_stats()
    
    # 2. README.md
    read_readme()
    
    # 3. Entitäten analysieren
    entities = analyze_entities()
    
    # 4. Beziehungsgraph
    if entities:
        analyze_relationships(entities)
    
    # 5. Custom Layouts
    analyze_layouts()
    
    # 6. Custom PHP Klassen
    analyze_custom_classes()
    
    # 7. Workflows
    analyze_workflows()
    
    # 8. Frontend
    analyze_frontend()
    
    # 9. i18n
    analyze_i18n()
    
    # Abschluss
    print_section("ANALYSE ABGESCHLOSSEN", "=")
    print("\n✅ Die KI hat jetzt einen vollständigen Überblick über das Projekt!")
    print("   Alle Entitäten, Beziehungen, Custom Klassen und Frontend-Anpassungen wurden erfasst.\n")
    
    # Hinweis auf README.md
    print("=" * 80)
    print("📖 WICHTIG: Bitte jetzt die README.md lesen!")
    print("=" * 80)
    print(f"\n   Pfad: {README_PATH}")
    print(f"\n   Die README.md enthält {README_PATH.stat().st_size // 1024}KB detaillierte Projektdokumentation:")
    print("   • Struktur und Funktionsweise")
    print("   • Rebuild-Prozess")
    print("   • Workflow-Verwaltung")
    print("   • Formula-Scripts und Custom PHP")
    print("   • Internationalisierung")
    print("   • Troubleshooting")
    print("\n   📌 UNBEDINGT LESEN für vollständiges Projektverständnis!\n")


if __name__ == "__main__":
    main()
