
import asyncio
import logging
import datetime
import random
import sys
import json
from sqlalchemy import text, func, update, case
from app.database import AsyncSessionLocal
from app.models.vehicle_definitions import VehicleModelDefinition
from app.models.asset import AssetCatalog
from app.services.ai_service import AIService

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

class TechEnricher:
    """
    Vehicle Robot 3: Alchemist Pro (Atomi Zárolás Patch)
    Tiszta GPU fókusz: Csak az AI elemzésre és adategyesítésre koncentrál.
    Nincs felesleges webkeresés. Szigorú Sane-Check.
    """
    def __init__(self):
        self.max_attempts = 5
        self.daily_ai_limit = int(os.getenv("AI_DAILY_LIMIT", "10000"))
        self.ai_calls_today = 0
        self.last_reset_date = datetime.date.today()

    def check_budget(self) -> bool:
        if datetime.date.today() > self.last_reset_date:
            self.ai_calls_today = 0
            self.last_reset_date = datetime.date.today()
        return self.ai_calls_today < self.daily_ai_limit

    ddef is_data_sane(self, data: dict, base_info: dict) -> bool:
        """ Szigorított, de intelligens AI Hallucináció szűrő """
        if not data: 
            logger.warning("Sane-check: Teljesen üres AI válasz.")
            return False
        
        try:
            # 1. Alapvető fizikai korlátok vizsgálata (csak az AI adatokon)
            ai_ccm = int(data.get("ccm", 0) or 0)
            ai_kw = int(data.get("kw", 0) or 0)
            v_class = base_info.get("v_type", "car")
            
            if ai_ccm > 18000:
                logger.warning(f"Sane-check bukás: Irreális CCM érték ({ai_ccm})")
                return False
            if ai_kw > 1500 and v_class != "truck":
                logger.warning(f"Sane-check bukás: Irreális KW érték ({ai_kw})")
                return False
                
            # 2. KOMBINÁLT Adat teljesség vizsgálata (RDW + AI)
            # Ha az RDW tudja, akkor nem baj, ha az AI nem találta meg!
            merged_kw = base_info.get('rdw_kw') or ai_kw
            merged_ccm = base_info.get('rdw_ccm') or ai_ccm
            fuel = data.get("fuel_type", base_info.get("rdw_fuel", "")).lower()

            # Ha még kombinálva sincs meg a KW
            if merged_kw == 0:
                logger.warning("Sane-check figyelmeztetés: Hiányzó KW (se RDW, se AI). Engedélyezve részleges adatként.")
                # Nem térünk vissza False-al, inkább mentsük el, amit eddig tudunk!
            
            # Ha még kombinálva sincs meg a CCM (és nem elektromos)
            if merged_ccm == 0 and "electric" not in fuel and "elektric" not in fuel and v_class != "trailer":
                logger.warning("Sane-check figyelmeztetés: Hiányzó CCM egy belsőégésű motornál. Engedélyezve részleges adatként.")
                # Ezt is átengedjük, hogy kitörjünk a végtelen hurokból.

            return True
            
        except Exception as e:
            logger.error(f"Sane check hiba: {e}")
            return False

    async def process_single_record(self, db, record_id: int, base_info: dict, current_attempts: int):
        try:
            logger.info(f"🧠 AI dúsítás indul: {base_info['make']} {base_info['m_name']}")
            
            # 1. LÉPÉS: AI Hívás (Rábízzuk az adatokat a modellre)
            ai_data = await AIService.get_clean_vehicle_data(
                base_info['make'], 
                base_info['m_name'], 
                base_info
            )

            # 2. LÉPÉS: Validáció (Ha az AI rossz adatot ad, NEM megyünk ki a webre, hanem dobjuk az aktát!)
            if not ai_data or not self.is_data_sane(ai_data, base_info):
                raise ValueError("Az AI hiányos adatot adott vissza vagy hallucinált.")

            # 3. LÉPÉS: HIBRID MERGE (Az RDW adatok felülbírálják az AI-t a hatósági paramétereknél)
            final_kw = base_info['rdw_kw'] if base_info['rdw_kw'] > 0 else (ai_data.get("kw") or 0)
            final_ccm = base_info['rdw_ccm'] if base_info['rdw_ccm'] > 0 else (ai_data.get("ccm") or 0)
            
            # Üzemanyag tisztítása
            fuel_rdw = base_info.get('rdw_fuel', '')
            final_fuel = fuel_rdw if fuel_rdw and fuel_rdw != "Unknown" else ai_data.get("fuel_type", "petrol")
            
            final_engine = base_info['rdw_engine'] if base_info['rdw_engine'] else ai_data.get("engine_code", "Unknown")
            final_euro = base_info['rdw_euro'] or ai_data.get("euro_classification")
            final_cylinders = base_info['rdw_cylinders'] or ai_data.get("cylinders")

            # 4. LÉPÉS: Mentés az Arany Katalógusba
            clean_model = str(ai_data.get("marketing_name", base_info['m_name']))[:50].upper()
            
            cat_stmt = text("""
                INSERT INTO data.vehicle_catalog 
                (master_definition_id, make, model, power_kw, engine_capacity, fuel_type, factory_data)
                VALUES (:m_id, :make, :model, :kw, :ccm, :fuel, :factory)
                RETURNING id;
            """)
            
            await db.execute(cat_stmt, {
                "m_id": record_id,
                "make": base_info['make'].upper(),
                "model": clean_model,
                "kw": final_kw,
                "ccm": final_ccm,
                "fuel": final_fuel,
                "factory": json.dumps(ai_data)
            })

            # 5. LÉPÉS: Staging tábla (VMD) lezárása
            await db.execute(
                update(VehicleModelDefinition)
                .where(VehicleModelDefinition.id == record_id)
                .values(
                    status="gold_enriched",
                    engine_capacity=final_ccm,
                    power_kw=final_kw,
                    fuel_type=final_fuel,
                    engine_code=final_engine,
                    euro_classification=final_euro,
                    cylinders=final_cylinders,
                    specifications=ai_data, # Elmentjük az AI teljes outputját a mestertáblába is
                    updated_at=func.now()
                )
            )
            await db.commit()
            logger.info(f"✨ ARANY REKORD KÉSZ: {base_info['make'].upper()} {clean_model}")
            self.ai_calls_today += 1

        except Exception as e:
            await db.rollback()
            logger.warning(f"⚠️ Alkimista hiba ({base_info['make']} {base_info['m_name']}): {e}")
            
            # Visszaküldés a sorba vagy felfüggesztés
            new_status = 'suspended' if current_attempts + 1 >= self.max_attempts else 'unverified'
            
            await db.execute(
                update(VehicleModelDefinition)
                .where(VehicleModelDefinition.id == record_id)
                .values(
                    attempts=current_attempts + 1,
                    last_error=str(e)[:200],
                    status=new_status,
                    updated_at=func.now()
                )
            )
            await db.commit()
            if new_status == 'unverified':
                logger.info("♻️ Akta visszaküldve a Robot-2-nek (Kutató).")

    async def run(self):
        logger.info(f"🚀 Alchemist Pro HIBRID ONLINE (Atomi Zárolás Patch)")
        while True:
            if not self.check_budget():
                logger.warning("💸 Napi AI limit kimerítve! Pihenés...")
                await asyncio.sleep(3600); continue

            try:
                async with AsyncSessionLocal() as db:
                    # ATOMI ZÁROLÁS (A "Szent Grál" a race condition ellen)
                    # A Robot-1 (ACTIVE) és a Robot-2 (awaiting_ai_synthesis) aktáit is felveszi!
                    query = text("""
                        UPDATE data.vehicle_model_definitions
                        SET status = 'ai_synthesis_in_progress'
                        WHERE id = (
                            SELECT id FROM data.vehicle_model_definitions
                            WHERE status IN ('awaiting_ai_synthesis', 'ACTIVE')
                              AND attempts < :max_attempts
                            ORDER BY 
                                CASE WHEN status = 'awaiting_ai_synthesis' THEN 1 ELSE 2 END,
                                priority_score DESC
                            FOR UPDATE SKIP LOCKED
                            LIMIT 1
                        )
                        RETURNING id, make, marketing_name, vehicle_class, power_kw, engine_capacity, 
                                  fuel_type, engine_code, euro_classification, cylinders, raw_search_context, attempts;
                    """)
                    
                    result = await db.execute(query, {"max_attempts": self.max_attempts})
                    task = result.fetchone()
                    await db.commit()

                if task:
                    # Szétbontjuk a lekérdezett rekordot a base_info dict-be
                    r_id = task[0]
                    base_info = {
                        "make": task[1], "m_name": task[2], "v_type": task[3] or "car",
                        "rdw_kw": task[4] or 0, "rdw_ccm": task[5] or 0,
                        "rdw_fuel": task[6] or "petrol", "rdw_engine": task[7] or "",
                        "rdw_euro": task[8], "rdw_cylinders": task[9],
                        "web_context": task[10] or ""
                    }
                    attempts = task[11]

                    # Külön adatbázis kapcsolat a feldolgozáshoz (hosszú AI hívás miatt)
                    async with AsyncSessionLocal() as process_db:
                        await self.process_single_record(process_db, r_id, base_info, attempts)
                    
                    # GPU hűtés / Ollama rate limit
                    await asyncio.sleep(random.uniform(1.5, 3.5)) 
                else:
                    logger.info("😴 Nincs feldolgozandó akta, az Alkimista pihen...")
                    await asyncio.sleep(15)

            except Exception as e:
                logger.error(f"💀 Kritikus hiba a főciklusban: {e}")
                await asyncio.sleep(10)

if __name__ == "__main__":
    import os # Import az AI limit környezeti változóhoz
    asyncio.run(TechEnricher().run())