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

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

class TechEnricher:
    """
    Vehicle Robot 3: Alchemist Pro (Sentinel Gateway Edition)
    Az AIService 2.2-t használja (Ollama -> Groq Fallback).
    Kinyeri a felszereltségi szintet (trim_level) és pótolja a hiányzó adatokat.
    """
    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]:
        if merged_ccm > 18000:
            return False, f"Irreális CCM érték ({merged_ccm})"
        if merged_kw > 1500 and v_class not in ["truck", "other"]:
            return False, f"Irreális KW érték ({merged_kw})"

        if merged_kw == 0 and current_attempts < 3:
            return False, "Hiányzó KW adat. Újrakutatás javasolt."

        if merged_ccm == 0 and "elektr" not in fuel.lower() and v_class != "trailer" and current_attempts < 3:
             return False, "Hiányzó CCM (belsőégésű motornál)."

        return True, "OK"

    async def process_single_record(self, db, record_id: int, base_info: dict, current_attempts: int):
        v_ident = f"{base_info['make'].upper()} {base_info['m_name']} (ID: {record_id})"
        attempt_str = f"[Próba: {current_attempts + 1}/{self.max_attempts}]"
        
        try:
            logger.info(f"🧠 AI dúsítás indul: {v_ident} {attempt_str}")
            
            # Szigorú Prompt a Master AI Service-nek
            prompt = f"""
            Elemezd az alábbi járműadatokat és a webes kutatást! Készíts belőle egy JSON objektumot.
            Jármű: {base_info['make']} {base_info['m_name']}
            Hatósági adatok: {base_info['rdw_ccm']} ccm, {base_info['rdw_kw']} kW, Üzemanyag: {base_info['rdw_fuel']}
            Webes szöveg: {base_info['web_context'][:2000]}

            FELADATOK:
            1. Keresd meg a felszereltségi szintet (trim_level) a modell nevéből vagy a szövegből (pl. AMG, Highline, Titanium, M-Sport, Elegance, ST-Line). Ha nincs, legyen üres string.
            2. Ha az RDW adatokban a kW vagy a ccm 0, pótold a szövegből a helyes értéket!
            
            KIZÁRÓLAG EGY ÉRVÉNYES JSON-T ADJ VISSZA! (A Groq/Gemini miatt kötelező a JSON szó használata).
            Várt kulcsok: "kw" (int), "ccm" (int), "trim_level" (string), "transmission" (string), "drive_type" (string).
            """
            
            # Hívjuk a te profi Gateway-edet! (_execute_ai_call átveszi a db session-t is a beállításokhoz)
            ai_data = await AIService._execute_ai_call(db, prompt, model_key="text")
            
            if not ai_data:
                raise ValueError("Üres AI válasz (Minden fallback elbukott).")

            # HIBRID MERGE
            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)
            trim_level = str(ai_data.get("trim_level", ""))[:100]

            # Sane-Check
            is_valid, error_msg = self.validate_merged_data(final_kw, final_ccm, base_info['v_type'], base_info['rdw_fuel'], current_attempts)
            if not is_valid:
                raise ValueError(f"Validációs hiba: {error_msg}")

            # Staging tábla frissítése (Arany minősítés)
            await db.execute(
                update(VehicleModelDefinition)
                .where(VehicleModelDefinition.id == record_id)
                .values(
                    status="gold_enriched",
                    engine_capacity=final_ccm,
                    power_kw=final_kw,
                    trim_level=trim_level if trim_level.lower() not in ["null", "none"] else "",
                    specifications=ai_data,
                    updated_at=func.now()
                )
            )
            await db.commit()
            logger.info(f"✨ ARANY REKORD KÉSZ: {v_ident} | Trim: {trim_level}")
            self.ai_calls_today += 1

        except Exception as e:
            await db.rollback()
            logger.warning(f"⚠️ Alkimista hiba - {v_ident}: {e}")
            
            new_status = 'manual_review_needed' 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(f"♻️ Akta visszaküldve a Kutatónak (R2). {attempt_str}")

    async def run(self):
        logger.info(f"🚀 R3 Alchemist Pro ONLINE (Sentinel Gateway Integráció)")
        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:
                    query = text("""
                        UPDATE vehicle.vehicle_model_definitions
                        SET status = 'ai_synthesis_in_progress'
                        WHERE id = (
                            SELECT id FROM vehicle.vehicle_model_definitions
                            WHERE status = 'awaiting_ai_synthesis'
                              AND attempts < :max_attempts
                              AND is_manual = FALSE
                            ORDER BY priority_score DESC
                            FOR UPDATE SKIP LOCKED LIMIT 1
                        )
                        RETURNING id, make, marketing_name, vehicle_class, power_kw, engine_capacity, fuel_type, raw_search_context, attempts;
                    """)
                    
                    result = await db.execute(query, {"max_attempts": self.max_attempts})
                    task = result.fetchone()
                    await db.commit()

                if task:
                    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", "web_context": task[7] or ""
                    }
                    async with AsyncSessionLocal() as process_db:
                        await self.process_single_record(process_db, task[0], base_info, task[8])
                    
                else:
                    await asyncio.sleep(10)

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

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