import asyncio
import logging
import sys
from sqlalchemy import select, and_, text, update
from sqlalchemy.orm import joinedload
from app.database import AsyncSessionLocal 
from app.models import Asset, AssetCatalog
from app.services.ai_service import AIService

logging.basicConfig(
    level=logging.INFO, 
    format='%(asctime)s [%(levelname)s] Vehicle-VIN-Auditor: %(message)s', 
    stream=sys.stdout
)
logger = logging.getLogger("Vehicle-Robot-4-VINAuditor")

class VINAuditor:
    """
    Vehicle Robot 4: VIN Auditor (Atomi Zárolás Patch)
    Egyedi járművek (Assets) alvázszám alapú hitelesítése.
    """
    
    @classmethod
    async def audit_asset(cls, db, asset_id: int):
        """ Egy konkrét eszköz hitelesítése alvázszám alapján. """
        # 1. Adatok begyűjtése
        stmt = select(Asset).options(joinedload(Asset.catalog)).where(Asset.id == asset_id)
        asset = (await db.execute(stmt)).scalar_one_or_none()
        
        if not asset or not asset.vin or not asset.catalog:
            return
            
        make = asset.catalog.make
        vin = asset.vin
        current_kw = asset.catalog.power_kw

        # 2. AI FÁZIS
        try:
            logger.info(f"🛡️ VIN Ellenőrzés indítása: {vin}")
            truth = await AIService.get_clean_vehicle_data(make, vin, {"source": "vin_audit", "vin": vin})
            
            if truth and truth.get("kw"):
                real_kw = int(truth["kw"])
                
                # Ha jelentős (>=5 kW) eltérés van
                if abs(real_kw - (current_kw or 0)) >= 5:
                    logger.warning(f"⚠️ Eltérés észlelve! VIN: {vin} | Valóság: {real_kw}kW != Katalógus: {current_kw}kW")
                    
                    new_v = AssetCatalog(
                        make=make.upper(), 
                        model=truth.get("marketing_name", asset.catalog.model), 
                        power_kw=real_kw,
                        source=f"VIN-AUDIT-{vin}"
                    )
                    db.add(new_v)
                    await db.flush() 
                    
                    await db.execute(
                        update(Asset)
                        .where(Asset.id == asset_id)
                        .values(catalog_id=new_v.id, is_verified=True, status="active")
                    )
                else:
                    await db.execute(
                        update(Asset)
                        .where(Asset.id == asset_id)
                        .values(is_verified=True, status="active")
                    )
                
                await db.commit()
                logger.info(f"✅ VIN Audit sikeresen lezárva: {vin}")
            else:
                logger.warning(f"⚠️ AI nem tudta azonosítani a VIN-t: {vin}")
                # Visszaállítjuk, de megjelöljük, hogy már próbáltuk
                await db.execute(update(Asset).where(Asset.id == asset_id).values(status="audit_failed"))
                await db.commit()

        except Exception as e:
            await db.rollback()
            logger.error(f"🚨 Kritikus hiba az audit során: {e}")

    async def run(self):
        logger.info("🛡️ Vehicle VIN Auditor ONLINE (Atomi Zárolás)")
        while True:
            try:
                async with AsyncSessionLocal() as db:
                    # ATOMI ZÁROLÁS (Asset táblán)
                    query = text("""
                        UPDATE vehicle.assets
                        SET status = 'audit_in_progress'
                        WHERE id = (
                            SELECT id FROM vehicle.assets
                            WHERE is_verified = false 
                              AND vin IS NOT NULL
                              AND status NOT IN ('audit_in_progress', 'audit_failed')
                            FOR UPDATE SKIP LOCKED
                            LIMIT 1
                        )
                        RETURNING id;
                    """)
                    
                    result = await db.execute(query)
                    task = result.fetchone()
                    await db.commit()
                
                if task:
                    async with AsyncSessionLocal() as process_db:
                        await self.audit_asset(process_db, task[0])
                    await asyncio.sleep(2)
                else:
                    await asyncio.sleep(60)
            except Exception as e:
                logger.error(f"🚨 Hiba a főciklusban: {e}")
                await asyncio.sleep(30)

if __name__ == "__main__":
    auditor = VINAuditor()
    asyncio.run(auditor.run())