import asyncio
import logging
import datetime
import random
import sys
import json
import os
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 + Kézi Moderáció Patch)
    Tiszta GPU fókusz: Csak az AI elemzésre és adategyesítésre koncentrál.
    Nincs felesleges webkeresés. Szigorú, de intelligens 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

    def validate_merged_data(self, merged_kw: int, merged_ccm: int, v_class: str, fuel: str, current_attempts: int) -> tuple[bool, str]:
        """ Intelligens validáció a MERGE után. Visszaadja a státuszt és a hiba okát. """
        if merged_ccm > 18000:
            return False, f"Irreális CCM érték ({merged_ccm})"
        if merged_kw > 1500 and v_class != "truck":
            return False, f"Irreális KW érték ({merged_kw})"

        # Ha hiányzik a KW
        if merged_kw == 0:
            if current_attempts < 3:
                return False, "Hiányzó KW adat. Újrakutatás javasolt."
            else:
                logger.warning("Sane-check: Többszöri próbálkozás után sincs KW, de átengedjük részlegesként.")

        # Ha hiányzik a CCM (és belsőégésű)
        if merged_ccm == 0 and "electric" not in fuel and "elektric" not in fuel and v_class != "trailer":
             if current_attempts < 3:
                 return False, "Hiányzó CCM (belsőégésű motornál). Újrakutatás javasolt."
             else:
                 logger.warning("Sane-check: Többszöri próbálkozás után sincs CCM, átengedjük részlegesként.")

        return True, "OK"

    async def process_single_record(self, db, record_id: int, base_info: dict, current_attempts: int):
        # Pontos azonosító a logokhoz (Márka, Modell, ID, RDW adatok)
        v_ident = f"{base_info['make'].upper()} {base_info['m_name']} (ID: {record_id}, RDW: {base_info['rdw_ccm']}ccm, KW: {base_info['rdw_kw']})"
        attempt_str = f"[Próba: {current_attempts + 1}/{self.max_attempts}]"
        
        ai_data = {} # Üres dict, ha az AI hívás elszállna
        
        try:
            logger.info(f"🧠 AI dúsítás indul: {v_ident} {attempt_str}")
            
            # 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
            )
            
            if not ai_data:
                raise ValueError("Teljesen üres AI válasz (API hiba vagy extrém hallucináció).")

            # 2. LÉPÉS: HIBRID MERGE (Még a validáció előtt!)
            # 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 int(ai_data.get("kw", 0) or 0)
            final_ccm = base_info['rdw_ccm'] if base_info['rdw_ccm'] > 0 else int(ai_data.get("ccm", 0) 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")

            # 3. LÉPÉS: Intelligens Validáció
            is_valid, error_msg = self.validate_merged_data(final_kw, final_ccm, base_info['v_type'], final_fuel.lower(), current_attempts)
            if not is_valid:
                raise ValueError(f"Validációs hiba: {error_msg}")

            # 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)
                ON CONFLICT ON CONSTRAINT uix_vehicle_catalog_full DO NOTHING
                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: {v_ident}")
            self.ai_calls_today += 1

        except Exception as e:
            await db.rollback()
            logger.warning(f"⚠️ Alkimista hiba - {v_ident}: {e}")
            
            # Ha elértük a limitet, KÉZI MODERÁCIÓRA küldjük, egyébként vissza a Kutatónak
            new_status = 'manual_review_needed' if current_attempts + 1 >= self.max_attempts else 'unverified'
            
            # Elmentjük az AI részleges válaszát (vagy a hibát), hogy az admin lássa, mit rontott el a gép
            review_data = ai_data if ai_data else {"error": "Nincs értékelhető JSON adat az AI-tól", "raw_context": base_info['web_context']}
            
            await db.execute(
                update(VehicleModelDefinition)
                .where(VehicleModelDefinition.id == record_id)
                .values(
                    attempts=current_attempts + 1,
                    last_error=str(e)[:200],
                    status=new_status,
                    specifications=review_data, # Kézi ellenőrzéshez beírjuk a törött adatot!
                    updated_at=func.now()
                )
            )
            await db.commit()
            
            if new_status == 'unverified':
                logger.info(f"♻️ Akta visszaküldve a Robot-2-nek (Kutató). {attempt_str}")
            else:
                logger.error(f"🛑 Max próbálkozás elérve! Kézi moderációra küldve: {v_ident}")

    async def run(self):
        logger.info(f"🚀 Alchemist Pro HIBRID ONLINE (Atomi Zárolás + Moderáció 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)
                    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__":
    asyncio.run(TechEnricher().run())