# /opt/docker/dev/service_finder/backend/app/workers/vehicle/vehicle_robot_1_gb_hunter.py
import asyncio
import httpx
import logging
import os
import sys
import json
from datetime import datetime
from sqlalchemy import text, func
from app.database import AsyncSessionLocal
from app.models import VehicleModelDefinition

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

class QuotaManager:
    """ Szigorú napi limit figyelő a DVLA API-hoz """
    def __init__(self, service_name: str, daily_limit: int):
        self.service_name = service_name
        self.daily_limit = daily_limit
        self.state_file = f"/app/temp/.quota_{service_name}.json"
        self._ensure_file()

    def _ensure_file(self):
        os.makedirs(os.path.dirname(self.state_file), exist_ok=True)
        if not os.path.exists(self.state_file):
            with open(self.state_file, 'w') as f:
                json.dump({"date": datetime.now().strftime("%Y-%m-%d"), "count": 0}, f)

    def can_make_request(self) -> bool:
        with open(self.state_file, 'r') as f:
            data = json.load(f)
        
        today = datetime.now().strftime("%Y-%m-%d")
        if data["date"] != today:
            data = {"date": today, "count": 0} 
            
        if data["count"] >= self.daily_limit:
            return False
            
        data["count"] += 1
        with open(self.state_file, 'w') as f:
            json.dump(data, f)
        return True

class GBHunter:
    """
    Vehicle Robot 1-GB: The DVLA Sniper
    Kizárólag brit rendszámok (VRM) alapján kérdez le hiteles adatokat.
    """
    DVLA_URL = "https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles"
    
    def __init__(self):
        self.api_key = os.getenv("DVLA_API_KEY")
        self.daily_limit = int(os.getenv("DVLA_DAILY_LIMIT", "1000"))
        self.quota = QuotaManager("dvla", self.daily_limit)
        self.headers = {
            "x-api-key": self.api_key,
            "Content-Type": "application/json"
        }

    async def fetch_dvla_data(self, client: httpx.AsyncClient, vrm: str):
        """ API hívás hibatűréssel (Max 3 próba) """
        if not self.api_key:
            logger.error("❌ HIÁNYZIK A DVLA_API_KEY a .env fájlból!")
            return None

        payload = {"registrationNumber": vrm}
        for attempt in range(3):
            try:
                resp = await client.post(self.DVLA_URL, json=payload, headers=self.headers)
                
                if resp.status_code == 200:
                    return resp.json()
                elif resp.status_code == 404:
                    logger.warning(f"⚠️ DVLA nem találta ezt a rendszámot: {vrm}")
                    return "NOT_FOUND"
                elif resp.status_code == 429: # Rate limit / Túl gyors hívás
                    await asyncio.sleep(2 ** attempt)
                elif resp.status_code == 403:
                    logger.error("❌ DVLA API hiba: 403 Forbidden (Hibás API kulcs!)")
                    return None
                else:
                    logger.error(f"❌ DVLA API hiba: {resp.status_code}")
                    return None
            except httpx.RequestError as e:
                if attempt == 2:
                    logger.error(f"Kritikus hálózati hiba: {e}")
                    return None
                await asyncio.sleep(2 ** attempt)
        return None

    async def process_record(self, db, record_id: int, vrm: str, make_csv: str, model_csv: str):
        logger.info(f"🇬🇧 GB Vadászat indul: {vrm} ({make_csv} {model_csv})")
        
        if not self.quota.can_make_request():
            logger.warning("🛑 NAPI DVLA KVÓTA ELÉRVE! A robot holnapig alvó módba lép.")
            return "QUOTA_EXCEEDED"

        async with httpx.AsyncClient(timeout=15.0) as client:
            data = await self.fetch_dvla_data(client, vrm)
            
        if data == "NOT_FOUND":
            # Hibás volt a CSV rendszám, lezárjuk a feladatot
            await db.execute(text("UPDATE vehicle.gb_catalog_discovery SET status = 'invalid_vrm' WHERE id = :id"), {"id": record_id})
            await db.commit()
            return "DONE"
            
        if not data:
            # Hálózati hiba, visszateszük a sorba
            await db.execute(text("UPDATE vehicle.gb_catalog_discovery SET status = 'pending' WHERE id = :id"), {"id": record_id})
            await db.commit()
            return "ERROR"

        # SIKERES LEKÉRDEZÉS - Adatok kinyerése
        ccm = data.get("engineCapacity", 0)
        fuel = data.get("fuelType", "Unknown")
        year = data.get("yearOfManufacture", 0)
        co2 = data.get("co2Emissions", 0)
        approval = data.get("typeApproval", "")
        dvla_make = data.get("make", make_csv)

        # Beszúrás a Mestertáblába (A hiányzó lóerőt majd az Alkimista megszerzi!)
        query_vmd = text("""
            INSERT INTO vehicle.vehicle_model_definitions
            (make, marketing_name, vehicle_class, fuel_type, engine_capacity, co2_emissions_combined, year_from, type_approval_number, status, source)
            VALUES (:make, :model, 'car', :fuel, :ccm, :co2, :year, :approval, 'ACTIVE', 'GB-DVLA-API')
            ON CONFLICT (make, normalized_name, variant_code, version_code, fuel_type) DO NOTHING;
        """)
        
        try:
            await db.execute(query_vmd, {
                "make": dvla_make.upper(),
                "model": model_csv.upper(),
                "fuel": fuel,
                "ccm": ccm,
                "co2": co2,
                "year": year if year else None,
                "approval": approval
            })
            
            # Pipáljuk a feladatot
            await db.execute(text("UPDATE vehicle.gb_catalog_discovery SET status = 'processed' WHERE id = :id"), {"id": record_id})
            await db.commit()
            logger.info(f"✅ GB Rekord mentve a VMD táblába: {dvla_make} {model_csv} ({ccm}cc {fuel})")
            return "DONE"
        except Exception as e:
            await db.rollback()
            logger.error(f"🚨 Adatbázis hiba mentéskor: {e}")
            await db.execute(text("UPDATE vehicle.gb_catalog_discovery SET status = 'pending' WHERE id = :id"), {"id": record_id})
            await db.commit()
            return "ERROR"

    @classmethod
    async def run(cls):
        self_instance = cls()
        logger.info("🤖 Robot-1-GB (DVLA Sniper) ONLINE (Atomi Zárolás & Kvótamenedzser)")
        
        while True:
            try:
                async with AsyncSessionLocal() as db:
                    # ATOMI ZÁROLÁS
                    query = text("""
                        UPDATE vehicle.gb_catalog_discovery
                        SET status = 'processing'
                        WHERE id = (
                            SELECT id FROM vehicle.gb_catalog_discovery
                            WHERE status = 'pending'
                            FOR UPDATE SKIP LOCKED
                            LIMIT 1
                        )
                        RETURNING id, vrm, make, model;
                    """)
                    
                    result = await db.execute(query)
                    task = result.fetchone()
                    await db.commit()

                if task:
                    status = await self_instance.process_record(db, task[0], task[1], task[2], task[3])
                    if status == "QUOTA_EXCEEDED":
                        await asyncio.sleep(3600) # Alsó mód, ha elfogyott a limit
                    else:
                        await asyncio.sleep(1.5) # Lassítás, hogy kíméljük az API-t
                else:
                    await asyncio.sleep(60) # Nincs új brit rendszám
                    
            except Exception as e:
                logger.error(f"💀 Kritikus hiba a főciklusban: {e}")
                await asyncio.sleep(10)

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