# /opt/docker/dev/service_finder/backend/app/workers/system/system_robot_2_service_auditor.py
import asyncio
import logging
from datetime import datetime, timezone
from sqlalchemy import select, and_, update, func
from sqlalchemy.dialects.postgresql import insert
from app.database import AsyncSessionLocal
from app.models.marketplace.organization import Organization, OrgType
from app.models.marketplace.service import ServiceProfile
from app.models.marketplace.staged_data import ServiceStaging

# MB 2.0 Naplózás
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s]: %(message)s')
logger = logging.getLogger("System-Robot-2-ServiceAuditor")

class ServiceAuditor:
    """
    System Robot 2: Service Auditor & Judge (Gamification 2.0)
    Feladata: 
    1. Staging adatok auditálása dinamikus trust_score küszöb alapján.
    2. Sikeres audit esetén Organization és ServiceProfile létrehozás.
    3. Bukott audit esetén needs_moderation státusz.
    """
    
    @classmethod
    async def get_promotion_threshold(cls, db):
        """ Dinamikus küszöbérték kiolvasása a system_parameters táblából (SQL text) """
        from sqlalchemy import text
        try:
            result = await db.execute(
                text("SELECT value FROM system.system_parameters WHERE key = 'service_promotion_threshold' AND scope_level = 'global'")
            )
            row = result.fetchone()
            if row:
                import json
                value = json.loads(row[0]) if isinstance(row[0], str) else row[0]
                threshold = value.get('trust_score', 50) if isinstance(value, dict) else 50
            else:
                threshold = 50
        except Exception as e:
            logger.warning(f"⚠️ Nem sikerült lekérni a küszöbértéket: {e}, alapértelmezett 50")
            threshold = 50
        logger.info(f"📊 Dinamikus trust_score küszöb: {threshold}")
        return threshold

    @classmethod
    async def promote_staging_data(cls):
        """ 
        AZ AUTOMATA BÍRÓ (Gamification 2.0):
        Atomikus tranzakcióban feldolgozza az auditor_ready státuszú rekordokat.
        """
        async with AsyncSessionLocal() as db:
            # Dinamikus küszöb lekérdezése
            threshold = await cls.get_promotion_threshold(db)
            
            # FOR UPDATE SKIP LOCKED használata
            stmt = select(ServiceStaging).where(
                ServiceStaging.status == "auditor_ready"
            ).with_for_update(skip_locked=True).limit(10)
            
            result = await db.execute(stmt)
            to_process = result.scalars().all()
            
            processed = 0
            for stage in to_process:
                try:
                    # Audit logika
                    if stage.trust_score >= threshold:
                        # A) SIKERES AUDIT
                        logger.info(f"✅ Sikeres audit: {stage.name} (trust_score={stage.trust_score})")
                        
                        # Organization létrehozása vagy meglévő keresése név alapján
                        org_stmt = select(Organization).where(
                            and_(
                                Organization.name == stage.name,
                                Organization.org_type == OrgType.service
                            )
                        )
                        org_result = await db.execute(org_stmt)
                        org = org_result.scalar_one_or_none()
                        
                        if not org:
                            org = Organization(
                                name=stage.name,
                                org_type=OrgType.service,
                                is_active=True,
                                created_by=stage.submitted_by if stage.submitted_by else None
                            )
                            db.add(org)
                            await db.flush()  # ID generáláshoz
                        
                        # ServiceProfile létrehozása
                        profile = ServiceProfile(
                            organization_id=org.id,
                            name=stage.name,
                            description=stage.description,
                            latitude=None,  # TODO: később geokódolás
                            longitude=None,
                            address=stage.full_address,
                            contact_phone=stage.contact_phone,
                            website=stage.website,
                            status='pending_validation',  # Következő robot/ember dúsíthatja
                            trust_score=stage.trust_score,
                            raw_data=stage.raw_data
                        )
                        db.add(profile)
                        await db.flush()
                        
                        # Staging rekord frissítése
                        stage.status = 'pending_validation'
                        stage.organization_id = org.id
                        stage.service_profile_id = profile.id
                        stage.updated_at = func.now()  # audited_at helyett updated_at
                        
                        logger.info(f"   ➡️ Organization #{org.id} és ServiceProfile #{profile.id} létrehozva")
                    
                    else:
                        # B) BUKOTT AUDIT
                        logger.warning(f"❌ Bukott audit: {stage.name} (trust_score={stage.trust_score} < {threshold})")
                        stage.status = 'needs_moderation'
                        stage.updated_at = func.now()
                    
                    processed += 1
                    
                except Exception as e:
                    logger.error(f"💥 Hiba a staging feldolgozás közben (ID {stage.id}): {e}")
                    await db.rollback()
                    # Staging rekord hibás státuszba helyezése
                    stage.status = 'error'
                    stage.updated_at = func.now()
                    # További hibakezelés: lehet naplózni audit_trail-be
                    continue
            
            if processed > 0:
                await db.commit()
                logger.info(f"📦 Feldolgozva {processed} staging rekord")
            else:
                logger.debug("ℹ️ Nincs feldolgozható staging rekord")

    @classmethod
    async def audit_existing_services(cls):
        """ Karbantartás: Megszűnt helyek inaktiválása. """
        async with AsyncSessionLocal() as db:
            # Csak az aktív szervizeket nézzük
            stmt = select(Organization).where(
                and_(
                    Organization.org_type == OrgType.service, 
                    Organization.is_active == True
                )
            )
            result = await db.execute(stmt)
            services = result.scalars().all()

            for service in services:
                try:
                    # Itt futhat le egy külső csekk (pl. weboldal él-e még?)
                    is_still_open = True 
                    
                    stmt_profile = select(ServiceProfile).where(ServiceProfile.organization_id == service.id)
                    profile_res = await db.execute(stmt_profile)
                    profile = profile_res.scalar_one_or_none()

                    if not is_still_open:
                        service.is_active = False
                        if profile:
                            profile.status = 'closed'
                        logger.warning(f"⚠️ Szerviz inaktiválva: {service.name}")
                    else:
                        if profile:
                            profile.last_audit_at = datetime.now(timezone.utc)

                    await asyncio.sleep(0.5) # Rate limit védelem
                    
                except Exception as e:
                    logger.error(f"❌ Hiba audit közben ({service.name}): {e}")

            await db.commit()

    @classmethod
    async def run(cls):
        logger.info("⚖️ System Auditor ONLINE - Gamification 2.0 Bírói mód")
        while True:
            # 1. Először élesítjük az új felfedezéseket
            await cls.promote_staging_data()
            
            # 2. Utána karbantartjuk a meglévőket
            await cls.audit_existing_services()
            
            # Rövid várakozás a következő ciklus előtt (teszteléshez 60 másodperc)
            await asyncio.sleep(60)

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