# /opt/docker/dev/service_finder/backend/app/workers/vehicle/bike/bike_R3_engine_scout.py
import asyncio
import logging
import random
import json
import re
from bs4 import BeautifulSoup
from playwright.async_api import async_playwright
from sqlalchemy import text
from app.database import AsyncSessionLocal

logging.basicConfig(level=logging.INFO, format='%(asctime)s [R3-EXTRACTOR] %(message)s')
logger = logging.getLogger("R3")

class R3DataMiner:
    def clean_key(self, key):
        if "," in key: key = key.split(",")[-1]
        key = key.replace("What is the ", "").replace("How much ", "").replace("How many ", "")
        return key.split("?")[0].strip().capitalize()

    async def scrape_specs(self, context, url):
        page = await context.new_page()
        try:
            await asyncio.sleep(random.uniform(4, 8))
            await page.goto(url, wait_until="domcontentloaded", timeout=60000)
            content = await page.content()
            soup = BeautifulSoup(content, 'html.parser')

            data = {"make": "", "model": "", "generation": "", "modification": "",
                    "year_from": None, "power_kw": 0, "engine_cc": 0,
                    "specifications": {}, "source_url": url}

            for row in soup.find_all('tr'):
                th, td = row.find('th'), row.find('td')
                if not th or not td: continue
                k_raw, v = th.get_text(strip=True), td.get_text(strip=True)
                k_low = k_raw.lower()

                if "brand" == k_low: data["make"] = v
                elif "model" == k_low: data["model"] = v
                elif "generation" == k_low: data["generation"] = v
                elif "modification" == k_low: data["modification"] = v
                elif "start of production" in k_low:
                    m = re.search(r'(\d{4})', v)
                    data["year_from"] = int(m.group(1)) if m else None
                elif "power" == k_low:
                    hp = re.search(r'(\d+)\s*Hp', v, re.I)
                    if hp: data["power_kw"] = int(int(hp.group(1)) / 1.36)
                elif "displacement" in k_low:
                    cc = re.search(r'(\d+)\s*cm3', v)
                    if cc: data["engine_cc"] = int(cc.group(1))
                
                data["specifications"][self.clean_key(k_raw)] = v
            return data
        except Exception as e:
            logger.error(f"Hiba az adatlapon: {e}"); return None
        finally: await page.close()

    async def run(self):
        async with async_playwright() as p:
            browser = await p.chromium.launch(headless=True)
            context = await browser.new_context(user_agent="Mozilla/5.0...")
            while True:
                async with AsyncSessionLocal() as db:
                    res = await db.execute(text("""
                        UPDATE vehicle.auto_data_crawler_queue SET status = 'processing'
                        WHERE id = (SELECT id FROM vehicle.auto_data_crawler_queue 
                                    WHERE level = 'engine' AND status = 'pending' 
                                    ORDER BY id ASC LIMIT 1 FOR UPDATE SKIP LOCKED)
                        RETURNING id, url, name
                    """))
                    target = res.fetchone()
                    await db.commit()
                if not target: break
                
                data = await self.scrape_specs(context, target[1])
                if data and data["make"]:
                    async with AsyncSessionLocal() as db:
                        await db.execute(text("""
                            INSERT INTO vehicle.external_reference_library 
                            (source_name, make, model, generation, modification, year_from, power_kw, engine_cc, specifications, source_url)
                            VALUES ('auto-data.net', :make, :model, :gen, :mod, :y, :p, :e, :s, :u)
                            ON CONFLICT (source_url) DO UPDATE SET specifications = EXCLUDED.specifications, last_scraped_at = NOW();
                        """), {"make": data["make"], "model": data["model"], "gen": data["generation"], "mod": data["modification"],
                               "y": data["year_from"], "p": data["power_kw"], "e": data["engine_cc"], "s": json.dumps(data["specifications"]), "u": data["source_url"]})
                        await db.execute(text("UPDATE vehicle.auto_data_crawler_queue SET status = 'completed' WHERE id = :id"), {"id": target[0]})
                        await db.commit()
                        logger.info(f"✅ ARANYMENTÉS: {data['make']} {data['model']} {data['modification']}")
                else:
                    async with AsyncSessionLocal() as db:
                        await db.execute(text("UPDATE vehicle.auto_data_crawler_queue SET status = 'error' WHERE id = :id"), {"id": target[0]})
                        await db.commit()
            await browser.close()

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