# /opt/docker/dev/service_finder/backend/app/scripts/sync_engine.py
#!/usr/bin/env python3
# docker exec -it sf_api python -m app.scripts.sync_engine
import asyncio
import importlib
import sys
from pathlib import Path
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy import inspect, text
from sqlalchemy.schema import CreateTable

# Path beállítása
sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from app.database import Base
from app.core.config import settings

def dynamic_import_models():
    """Modellek betöltése a Metadata feltöltéséhez."""
    models_dir = Path(__file__).parent.parent / "models"
    # Rekurzív bejárás az alkönyvtárakkal együtt
    for py_file in models_dir.rglob("*.py"):
        if py_file.name == "__init__.py": continue
        # Számítsuk ki a modulnevet a models könyvtárhoz képest
        relative_path = py_file.relative_to(models_dir)
        # Konvertáljuk path-t modulná: pl. identity/identity.py -> identity.identity
        module_stem = str(relative_path).replace('/', '.').replace('\\', '.')[:-3]  # eltávolítjuk a .py-t
        module_name = f"app.models.{module_stem}"
        try:
            importlib.import_module(module_name)
        except Exception as e:
            # Csak debug célra
            print(f"Failed to import {module_name}: {e}")
            pass

async def perform_detailed_audit():
    engine = create_async_engine(str(settings.SQLALCHEMY_DATABASE_URI))
    
    # Audit számlálók
    stats = {"ok": 0, "fixed": 0, "extra": 0, "missing": 0}

    def audit_logic(connection):
        inspector = inspect(connection)
        metadata = Base.metadata
        db_schemas = inspector.get_schema_names()
        model_schemas = sorted({t.schema for t in metadata.sorted_tables if t.schema})

        print("\n" + "="*80)
        print(f"{'🔍 RÉSZLETES SCHEMA AUDIT JELENTÉS':^80}")
        print("="*80)

        # --- A IRÁNY: KÓD -> ADATBÁZIS (Minden ellenőrzése) ---
        print(f"\n[A IRÁNY: Kód (SQLAlchemy) -> Adatbázis (PostgreSQL)]")
        print("-" * 50)
        
        for schema in model_schemas:
            # 1. Séma ellenőrzése
            if schema not in db_schemas:
                print(f"❌ HIÁNYZIK: Séma [{schema}] -> Létrehozás...")
                connection.execute(text(f'CREATE SCHEMA IF NOT EXISTS "{schema}"'))
                stats["fixed"] += 1
            else:
                print(f"✅ RENDBEN: Séma [{schema}] létezik.")
                stats["ok"] += 1

            db_tables = inspector.get_table_names(schema=schema)
            model_tables = [t for t in metadata.sorted_tables if t.schema == schema]

            for table in model_tables:
                full_name = f"{schema}.{table.name}"
                
                # 2. Tábla ellenőrzése
                if table.name not in db_tables:
                    print(f"   ❌ HIÁNYZIK: Tábla [{full_name}] -> Létrehozás...")
                    connection.execute(CreateTable(table))
                    stats["fixed"] += 1
                    continue
                else:
                    print(f"   ✅ RENDBEN: Tábla [{full_name}] létezik.")
                    stats["ok"] += 1

                # 3. Oszlopok ellenőrzése
                db_cols = {c['name']: c for c in inspector.get_columns(table.name, schema=schema)}
                for col in table.columns:
                    col_path = f"{full_name}.{col.name}"
                    if col.name not in db_cols:
                        print(f"      ❌ HIÁNYZIK: Oszlop [{col_path}] -> Hozzáadás...")
                        col_type = col.type.compile(dialect=connection.dialect)
                        default_sql = ""
                        if col.server_default is not None:
                            arg = col.server_default.arg
                            val = arg.text if hasattr(arg, 'text') else str(arg)
                            default_sql = f" DEFAULT {val}"
                        null_sql = " NOT NULL" if not col.nullable else ""
                        connection.execute(text(f'ALTER TABLE "{schema}"."{table.name}" ADD COLUMN "{col.name}" {col_type}{default_sql}{null_sql}'))
                        stats["fixed"] += 1
                    else:
                        print(f"      ✅ RENDBEN: Oszlop [{col_path}]")
                        stats["ok"] += 1

        # --- B IRÁNY: ADATBÁZIS -> KÓD (Árnyék adatok keresése) ---
        print(f"\n[B IRÁNY: Adatbázis -> Kód (Extra elemek keresése)]")
        print("-" * 50)
        
        for schema in model_schemas:
            if schema not in db_schemas: continue
            
            db_tables = inspector.get_table_names(schema=schema)
            model_table_names = {t.name for t in metadata.sorted_tables if t.schema == schema}

            for db_table in db_tables:
                # Ignore deprecated tables (ending with _deprecated)
                if db_table.endswith("_deprecated"):
                    continue
                full_db_name = f"{schema}.{db_table}"
                if db_table not in model_table_names:
                    print(f"   ⚠️  EXTRA TÁBLA: [{full_db_name}] (Nincs a kódban!)")
                    stats["extra"] += 1
                else:
                    # Extra oszlopok a táblán belül
                    db_cols = inspector.get_columns(db_table, schema=schema)
                    model_col_names = {c.name for c in metadata.tables[full_db_name].columns}
                    
                    for db_col in db_cols:
                        col_name = db_col['name']
                        if col_name not in model_col_names:
                            print(f"      ⚠️  EXTRA OSZLOP: [{full_db_name}.{col_name}]")
                            stats["extra"] += 1

        # --- ÖSSZESÍTŐ ---
        print("\n" + "="*80)
        print(f"{'📊 AUDIT ÖSSZESÍTŐ':^80}")
        print("="*80)
        print(f" ✅ Megfelelt (OK):          {stats['ok']:>4} elem")
        print(f" ❌ Javítva/Pótolva (Fixed):  {stats['fixed']:>4} elem")
        print(f" ⚠️  Extra (Shadow Data):     {stats['extra']:>4} elem")
        print("-" * 80)
        if stats["fixed"] == 0 and stats["extra"] == 0:
            print(f"{'✨ A RENDSZER TÖKÉLETESEN SZINKRONBAN VAN!':^80}")
        else:
            print(f"{'ℹ️  A rendszer üzemkész, de nézd át az extra (Shadow) elemeket!':^80}")
        print("="*80 + "\n")

    async with engine.begin() as conn:
        await conn.run_sync(audit_logic)
    await engine.dispose()

async def main():
    dynamic_import_models()
    await perform_detailed_audit()

if __name__ == "__main__":
    asyncio.run(main())