import re
import json
import time
import sys
from pathlib import Path
from datetime import date

SCRIPT_DIR = Path(__file__).resolve().parent
PROJECT_ROOT = SCRIPT_DIR.parent
if str(PROJECT_ROOT) not in sys.path:
    sys.path.insert(0, str(PROJECT_ROOT))
if str(SCRIPT_DIR) not in sys.path:
    sys.path.insert(0, str(SCRIPT_DIR))

try:
    from scripts.reindex import run_indexing, BASE_DIR, GRAPH_FILE
except ImportError:
    from reindex import run_indexing, BASE_DIR, GRAPH_FILE


MAPA_FILE = BASE_DIR / "MAPA_DE_LA_APLICACION.md"

def update_map_document(auto_create_workflows=True):
    print("=" * 70)
    print("🤖 AGENTE ESPECIALIZADO: ACTUALIZACIÓN DEL MAPA DE LA APLICACIÓN")
    print("=" * 70)
    
    # 1. Ejecutar reindexación completa del grafo y workflows
    print("\n[1/3] Reindexando código fuente, grafo de dependencias y workflows...")
    file_data, all_tables, ddl_tables = run_indexing(auto_create_workflows=auto_create_workflows)
    
    graph_data = json.loads(GRAPH_FILE.read_text(encoding='utf-8'))
    stats = graph_data['stats']
    modules = graph_data['modules']
    
    today_str = date.today().strftime("%Y-%m-%d")
    
    print(f" -> Módulos analizados: {stats['total_units']} (UI: {stats['ui_forms_count']}, Logic: {stats['logic_units_count']}, Common: {stats['common_units_count']}, Data: {stats['datamodules_count']})")
    print(f" -> Tablas referenciadas: {len(all_tables)} | Tablas en DDL: {len(ddl_tables)}")
    print(f" -> Cobertura de workflows: {stats['workflows_count']} / {stats['total_units']}")

    if not MAPA_FILE.exists():
        print(f"❌ Error: No se encontró {MAPA_FILE}")
        return
        
    print("\n[2/3] Sincronizando MAPA_DE_LA_APLICACION.md...")
    content = MAPA_FILE.read_text(encoding='utf-8')
    
    # 2. Actualizar metadatos de cabecera en MAPA_DE_LA_APLICACION.md
    content = re.sub(
        r'> \*\*Versión\*\*: ([^\n\|]+) \| \*\*Última Actualización\*\*: [0-9\-]+',
        f'> **Versión**: \\1 | **Última Actualización**: {today_str}',
        content
    )
    
    new_stats_line = (
        f"> **Módulos Totales**: {stats['total_units']} unidades (`src/`) &bull; "
        f"**Formularios UI**: {stats['ui_forms_count']} &bull; "
        f"**Servicios Logic**: {stats['logic_units_count']} &bull; "
        f"**DataModules**: {stats['datamodules_count']} &bull; "
        f"**Common**: {stats['common_units_count']} &bull; "
        f"**Tablas BD**: {len(all_tables)} (en código) / {len(ddl_tables)} (en DDL)"
    )
    
    content = re.sub(
        r'> \*\*Módulos Totales\*\*: [^\n]+ unidades \(`src/`\)[^\n]+',
        new_stats_line,
        content
    )
    
    # 2.1 Sincronizar contadores en la Tabla de Contenidos (TOC)
    content = re.sub(
        r'- 4\.1\. Capa UI \(`src/UI` — \d+ unidades\)',
        f"- 4.1. Capa UI (`src/UI` — {stats['ui_forms_count']} unidades)",
        content
    )
    content = re.sub(
        r'- 4\.2\. Capa Logic \(`src/Logic` — \d+ unidades\)',
        f"- 4.2. Capa Logic (`src/Logic` — {stats['logic_units_count']} unidades)",
        content
    )
    content = re.sub(
        r'- 4\.3\. Capa Common \(`src/Common` — \d+ unidades\)',
        f"- 4.3. Capa Common (`src/Common` — {stats['common_units_count']} unidades)",
        content
    )
    content = re.sub(
        r'- 4\.4\. Capa Data \(`src/Data` — \d+ unidades\)',
        f"- 4.4. Capa Data (`src/Data` — {stats['datamodules_count']} unidades)",
        content
    )
    content = re.sub(
        r'5\. \[Mapa del Modelo de Datos [^\]]+\]\([^\)]+\)',
        f"5. [Mapa del Modelo de Datos ({len(all_tables)} Tablas en MariaDB / {len(ddl_tables)} en DDL)](#5-mapa-del-modelo-de-datos-{len(all_tables)}-tablas-en-mariadb--{len(ddl_tables)}-en-ddl)",
        content
    )
    content = re.sub(
        r'6\. \[Catálogo Maestro de Módulos y Formularios \(\d+ Unidades\)',
        f"6. [Catálogo Maestro de Módulos y Formularios ({stats['total_units']} Unidades)",
        content
    )
    
    # 2.2 Sincronizar contadores en Sección 4 (diagrama de cajas)
    content = re.sub(
        r'src/UI \(\d+ unidades\)',
        f"src/UI ({stats['ui_forms_count']} unidades)",
        content
    )
    content = re.sub(
        r'src/Common \(\d+ unidades\)',
        f"src/Common ({stats['common_units_count']} unidades)",
        content
    )
    
    # 2.3 Sincronizar títulos de Sección 5 y 6
    content = re.sub(
        r'## 5\. Mapa del Modelo de Datos \([^\)]+\)',
        f"## 5. Mapa del Modelo de Datos ({len(all_tables)} Tablas en MariaDB / {len(ddl_tables)} en DDL)",
        content
    )
    content = re.sub(
        r'## 6\. Catálogo Maestro de Módulos y Formularios(?: \(\d+ Unidades\))?',
        f"## 6. Catálogo Maestro de Módulos y Formularios ({stats['total_units']} Unidades)",
        content
    )
    content = re.sub(
        r'Inventario consolidado de los \d+ módulos Pascal',
        f"Inventario consolidado de los {stats['total_units']} módulos Pascal",
        content
    )
    
    # 3. Purgar módulos obsoletos que ya no existen en src/
    existing_modules = set(re.findall(r'\|\s*`([A-Za-z0-9_]+\.pas)`\s*\|', content))
    obsolete_modules = sorted([m for m in existing_modules if m not in modules])
    
    if obsolete_modules:
        print(f" -> Módulos obsoletos a eliminar del mapa: {len(obsolete_modules)}")
        for m in obsolete_modules:
            # Eliminar la fila completa correspondiente
            content = re.sub(r'\|\s*`' + re.escape(m) + r'`\s*\|[^\n]*\n?', '', content)
            print(f"    - Eliminado del catálogo: {m}")
        # Re-evaluar existentes tras purga
        existing_modules = set(re.findall(r'\|\s*`([A-Za-z0-9_]+\.pas)`\s*\|', content))
    
    # 4. Detectar módulos que faltan en la Sección 6 del MAPA
    missing_modules = sorted([m for m in modules.keys() if m not in existing_modules])
    print(f" -> Módulos existentes en catálogo del mapa: {len(existing_modules)}")
    print(f" -> Módulos pendientes de registrar en mapa: {len(missing_modules)}")
    
    if missing_modules:
        rows_to_add = []
        for m in missing_modules:
            mod_info = modules[m]
            layer = mod_info.get('layer', 'UI')
            form_class = mod_info.get('class') or mod_info.get('unit', m.replace('.pas', ''))
            domain_id = mod_info.get('domain', '07_maestros_almacenes')
            dom_num = domain_id[:2] if domain_id else '06'
            
            # Formulario o propósito
            if 'editor' in m.lower():
                purpose = "Editor"
            elif 'list' in m.lower():
                purpose = "Listado Rejilla"
            elif 'service' in m.lower() or 'calc' in m.lower():
                purpose = "Servicio Lógica"
            elif 'client' in m.lower():
                purpose = "Cliente API"
            elif 'types' in m.lower():
                purpose = "Tipos / Enums"
            elif layer == 'Data':
                purpose = "DataModule"
            else:
                purpose = "Gestión / Tab"
                
            tbls = mod_info.get('tables', [])
            tbls_str = ", ".join(f"`{t}`" for t in tbls[:3]) if tbls else "—"
            if len(tbls) > 3:
                tbls_str += f" (+{len(tbls)-3})"
                
            row = f"| `{m}` | **{layer}** | `{form_class}` | {dom_num} | {purpose} | {tbls_str} |"
            rows_to_add.append(row)
            print(f"    + Añadido al catálogo: {m} [{layer}] (Dominio {dom_num})")
            
        # Buscar el final de la tabla de la Sección 6 para insertar las filas
        # La sección 6 termina antes de "## 7. Puntos de Integración Externa"
        sec7_marker = "## 7. Puntos de Integración Externa"
        if sec7_marker in content:
            parts = content.split(sec7_marker)
            # Añadir antes de la línea divisoria o al final de la tabla
            table_part = parts[0].rstrip()
            # Si hay una línea divisoria '---' al final de la tabla, insertamos antes de ella
            if table_part.endswith("---"):
                table_part = table_part[:-3].rstrip()
                insert_content = "\n" + "\n".join(rows_to_add) + "\n\n---\n\n"
            else:
                insert_content = "\n" + "\n".join(rows_to_add) + "\n\n"
            content = table_part + insert_content + sec7_marker + parts[1]
        else:
            content += "\n" + "\n".join(rows_to_add) + "\n"
            
    MAPA_FILE.write_text(content, encoding='utf-8')
    print("\n[3/3] Guardando MAPA_DE_LA_APLICACION.md actualizado...")
    
    print("\n" + "=" * 70)
    print("✅ MAPA DE LA APLICACIÓN ACTUALIZADO CON ÉXITO")
    print("=" * 70)
    print(f"• Fecha de sincronización: {today_str}")
    print(f"• Total unidades registradas: {stats['total_units']}")
    print(f"• Nuevos módulos incorporados en esta ejecución: {len(missing_modules)}")
    if missing_modules:
        for m in missing_modules:
            print(f"   - {m}")
    if obsolete_modules:
        print(f"• Módulos obsoletos purgados: {len(obsolete_modules)}")
        for m in obsolete_modules:
            print(f"   - {m}")
    print("• Artefactos maestros sincronizados:")
    print("   ✓ MAPA_DE_LA_APLICACION.md")
    print("   ✓ .agents/INDEX.md")
    print("   ✓ .agents/codebase_graph.json")
    print("   ✓ .agents/domains/*.md")
    print("   ✓ .agents/workflows/*.md")
    print("=" * 70)

if __name__ == '__main__':
    update_map_document()
