# /opt/docker/dev/service_finder/backend/app/workers/technical_enricher.py
import asyncio
import logging
import os
import datetime
import random
import sys
# JAVÍTVA: case hozzáadva az importhoz
from sqlalchemy import select, and_, update, text, func, case 
from app.db.session import AsyncSessionLocal
from app.models.vehicle_definitions import VehicleModelDefinition
from app.models.asset import AssetCatalog
from app.services.ai_service import AIService
from duckduckgo_search import DDGS

# --- SZIGORÚ NAPLÓZÁS ---
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(levelname)s] Alchemist-v1.3: %(message)s',
    stream=sys.stdout
)
logger = logging.getLogger("Robot-Enricher")

class TechEnricher:
    """
    Industrial TechEnricher (Alchemist Bot).
    Felelős az MDM (Master Data Management) 'Arany' rekordjainak előállításáért.
    """

    def __init__(self):
        self.max_attempts = 5
        self.batch_size = 10
        self.daily_ai_limit = 500
        self.ai_calls_today = 0
        self.last_reset_date = datetime.date.today()

    def check_budget(self) -> bool:
        """ Ellenőrzi, hogy beleférünk-e még a napi AI keretbe. """
        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 is_data_sane(self, data: dict) -> bool:
        """ Technikai józansági vizsgálat (Hallucináció elleni védelem). """
        try:
            if not data: return False
            ccm = int(data.get("ccm", 0) or 0)
            kw = int(data.get("kw", 0) or 0)
            # Extrém értékek szűrése (pl. nem létezik 20 literes személyautó motor)
            if ccm > 16000 or (kw > 1500 and data.get("vehicle_type") != "truck"):
                return False
            return True
        except: return False

    async def get_web_wisdom(self, make: str, model: str) -> str:
        """ Ha az AI bizonytalan, ez a funkció gyűjt kontextust a netről. """
        query = f"{make} {model} technical specifications oil capacity engine code"
        try:
            def sync_search():
                with DDGS() as ddgs:
                    # Az első 3 találat body részét gyűjtjük össze
                    results = ddgs.text(query, max_results=3)
                    return "\n".join([r['body'] for r in results]) if results else ""
            
            return await asyncio.to_thread(sync_search)
        except Exception as e:
            logger.warning(f"🌐 Web Search Error ({make}): {e}")
            return ""

    async def process_single_record(self, record_id: int):
        """ 
        Egyetlen rekord dúsítása izolált folyamatban. 
        Logika: Read -> AI Process -> Write Merge.
        """
        # 1. ADAT LEKÉRÉSE
        async with AsyncSessionLocal() as db:
            res = await db.execute(select(VehicleModelDefinition).where(VehicleModelDefinition.id == record_id))
            rec = res.scalar_one_or_none()
            if not rec: return
            make, m_name, v_type = rec.make, rec.marketing_name, (rec.vehicle_type or "car")

        # 2. AI FELDOLGOZÁS (DB kapcsolat nélkül!)
        try:
            # Elsődleges kísérlet a belső tudásbázis alapján
            ai_data = await AIService.get_clean_vehicle_data(make, m_name, v_type, {})
            
            # Ha az AI bizonytalan, indítunk egy webes mélyfúrást
            if not ai_data or not ai_data.get("kw"):
                logger.info(f"🔍 AI bizonytalan, Web-Context hívása: {make} {m_name}")
                web_info = await self.get_web_wisdom(make, m_name)
                ai_data = await AIService.get_clean_vehicle_data(make, m_name, v_type, {"web_context": web_info})

            if not ai_data or not self.is_data_sane(ai_data):
                raise ValueError("Hibás vagy hiányos AI válasz.")

            # 3. MENTÉS ÉS MERGE (Új session)
            async with AsyncSessionLocal() as db:
                # MDM Összefésülés: létezik-e már ez a variáns a katalógusban?
                clean_model = str(ai_data.get("marketing_name", m_name))[:50].upper()
                cat_stmt = select(AssetCatalog).where(and_(
                    AssetCatalog.make == make.upper(),
                    AssetCatalog.model == clean_model,
                    AssetCatalog.power_kw == ai_data.get("kw")
                )).limit(1)
                
                existing_cat = (await db.execute(cat_stmt)).scalar_one_or_none()
                
                if not existing_cat:
                    db.add(AssetCatalog(
                        make=make.upper(),
                        model=clean_model,
                        power_kw=ai_data.get("kw"),
                        engine_capacity=ai_data.get("ccm"),
                        fuel_type=ai_data.get("fuel_type", "petrol"),
                        factory_data=ai_data # Teljes technikai JSONB (olaj, gumi, stb.)
                    ))
                    logger.info(f"✨ ÚJ KATALÓGUS ELEM (Gold Data): {make} {clean_model}")

                # Staging (Discovery) állapot frissítése
                await db.execute(
                    update(VehicleModelDefinition)
                    .where(VehicleModelDefinition.id == record_id)
                    .values(
                        status="ai_enriched",
                        technical_code=ai_data.get("technical_code") or f"REF-{record_id}",
                        engine_capacity=ai_data.get("ccm"),
                        power_kw=ai_data.get("kw"),
                        updated_at=func.now()
                    )
                )
                await db.commit()
                self.ai_calls_today += 1

        except Exception as e:
            logger.error(f"🚨 Hiba a(z) {record_id} rekordnál: {e}")
            async with AsyncSessionLocal() as db:
                # Hibakezelés: ha sokszor bukik el, felfüggesztjük a rekordot
                await db.execute(
                    update(VehicleModelDefinition)
                    .where(VehicleModelDefinition.id == record_id)
                    .values(
                        attempts=VehicleModelDefinition.attempts + 1,
                        last_error=str(e)[:200],
                        status=case(
                            (VehicleModelDefinition.attempts >= 4, "suspended"),
                            else_="unverified"
                        ),
                        updated_at=func.now()
                    )
                )
                await db.commit()

    async def run(self):
        logger.info(f"🚀 Alchemist Robot v1.3.0 ONLINE (Napi keret: {self.daily_ai_limit})")
        while True:
            if not self.check_budget():
                logger.warning("💰 AI költségkeret kimerült mára. Alvás 1 órát.")
                await asyncio.sleep(3600); continue

            try:
                async with AsyncSessionLocal() as db:
                    # Olyan rekordokat keresünk, amik még nincsenek dúsítva és nincs túl sok hiba rajtuk
                    stmt = select(VehicleModelDefinition.id).where(and_(
                        VehicleModelDefinition.status == "unverified",
                        VehicleModelDefinition.attempts < self.max_attempts
                    )).limit(self.batch_size)
                    
                    # JAVÍTVA: Fetchall és list comprehension
                    res = await db.execute(stmt)
                    ids = [r[0] for r in res.fetchall()]

                if not ids:
                    await asyncio.sleep(60); continue

                logger.info(f"📦 Batch feldolgozása indul: {len(ids)} tétel.")
                for rid in ids:
                    await self.process_single_record(rid)
                    # VGA kímélése és API rate-limit védelem
                    await asyncio.sleep(random.uniform(5.0, 15.0))

            except Exception as e:
                logger.error(f"🚨 Főciklus hiba: {e}")
                await asyncio.sleep(30)

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