# /opt/docker/dev/service_finder/backend/discovery_bot.py
import asyncio
import json
import httpx
import os
import hashlib
import logging
from urllib.parse import quote
from sqlalchemy import select
from app.database import AsyncSessionLocal
from app.models.staged_data import ServiceStaging

# Logolás beállítása
logging.basicConfig(level=logging.INFO, format='%(asctime)s [%(levelname)s]: %(message)s')
logger = logging.getLogger("OSM-Discovery")

# Konfiguráció
HUNGARY_BBOX = "45.7,16.1,48.6,22.9"
OVERPASS_URL = "http://overpass-api.de/api/interpreter?data="

class OSMDiscoveryBot:
    @staticmethod
    def generate_fingerprint(name: str, city: str) -> str:
        """ 
        Ujjlenyomat generálása a deduplikációhoz. 
        Kicsit lazább, mint a Hunter-nél, mert az OSM címadatok néha hiányosak.
        """
        raw = f"{str(name).lower()}|{str(city).lower()}"
        return hashlib.md5(raw.encode()).hexdigest()

    @staticmethod
    def get_service_type(tags: dict, name: str) -> str:
        """ OSM tagek leképezése belső kategóriákra. """
        name = name.lower()
        shop = tags.get('shop', '')
        amenity = tags.get('amenity', '')
        
        if shop == 'tyres' or 'gumi' in name: return 'tire_shop'
        if amenity == 'car_wash' or 'mosó' in name: return 'car_wash'
        if any(x in name for x in ['villamos', 'autóvill', 'elektro']): return 'electrician'
        if any(x in name for x in ['fényez', 'lakatos', 'karosszéria']): return 'body_shop'
        return 'mechanic'

    async def fetch_osm_data(self, query_part: str):
        """ Aszinkron adatgyűjtés az Overpass API-tól. """
        query = f'[out:json][timeout:120];(node{query_part}({HUNGARY_BBOX});way{query_part}({HUNGARY_BBOX}););out center;'
        async with httpx.AsyncClient(timeout=150) as client:
            try:
                resp = await client.get(OVERPASS_URL + quote(query))
                if resp.status_code == 200:
                    return resp.json().get('elements', [])
                return []
            except Exception as e:
                logger.error(f"❌ Overpass hiba: {e}")
                return []

    async def sync(self):
        logger.info("🛰️ OSM Országos szinkronizáció indítása...")
        
        # 1. Lekérdezések összeállítása
        queries = [
            '["shop"~"car_repair|tyres"]',
            '["amenity"="car_wash"]'
        ]
        
        all_elements = []
        for q in queries:
            elements = await self.fetch_osm_data(q)
            all_elements.extend(elements)
        
        logger.info(f"📊 {len(all_elements)} potenciális szervizpont érkezett.")

        async with AsyncSessionLocal() as db:
            added_count = 0
            for node in all_elements:
                tags = node.get('tags', {})
                if not tags.get('name'): continue

                lat = node.get('lat', node.get('center', {}).get('lat'))
                lon = node.get('lon', node.get('center', {}).get('lon'))
                
                name = tags.get('name', tags.get('operator', 'Ismeretlen szerviz'))
                city = tags.get('addr:city', 'Ismeretlen')
                street = tags.get('addr:street', '')
                housenumber = tags.get('addr:housenumber', '')
                
                f_print = self.generate_fingerprint(name, city)

                # Deduplikáció ellenőrzése
                stmt = select(ServiceStaging).where(ServiceStaging.fingerprint == f_print)
                existing = (await db.execute(stmt)).scalar_one_or_none()

                if not existing:
                    db.add(ServiceStaging(
                        name=name,
                        source="osm_discovery_v2",
                        fingerprint=f_print,
                        city=city,
                        full_address=f"{city}, {street} {housenumber}".strip(", "),
                        status="pending",
                        trust_score=20, # Az OSM adatokat alacsonyabb bizalommal kezeljük, mint a Google-t
                        raw_data=tags
                    ))
                    added_count += 1
            
            await db.commit()
            logger.info(f"✅ Szinkron kész. {added_count} új elem került a Staging táblába.")

if __name__ == "__main__":
    bot = OSMDiscoveryBot()
    asyncio.run(bot.sync())