from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from app.models.service import ServiceProfile, ExpertiseTag, ServiceExpertise
from app.models.organization import Organization
from geoalchemy2.functions import ST_Distance, ST_MakePoint

class SearchService:
    @staticmethod
    async def find_nearby_services(
        db: AsyncSession, 
        lat: float, 
        lon: float, 
        expertise_key: str = None, 
        radius_km: int = 50,
        is_premium: bool = False
    ):
        """
        Keresés távolság és szakértelem alapján.
        Premium: Trust Score + Valós távolság.
        Free: Trust Score + Légvonal.
        """
        user_point = ST_MakePoint(lon, lat) # PostGIS pont létrehozása
        
        # Alap lekérdezés: ServiceProfile + Organization adatok
        stmt = select(ServiceProfile, Organization).join(
            Organization, ServiceProfile.organization_id == Organization.id
        )

        # 1. Sugár alapú szűrés (radius_km * 1000 méter)
        stmt = stmt.where(
            func.ST_DWithin(ServiceProfile.location, user_point, radius_km * 1000)
        )

        # 2. Szakterület szűrése
        if expertise_key:
            stmt = stmt.join(ServiceProfile.expertises).join(ExpertiseTag).where(
                ExpertiseTag.key == expertise_key
            )

        # 3. Távolság és Trust Score alapú sorrend
        # A ST_Distance méterben adja vissza az eredményt
        stmt = stmt.order_by(ST_Distance(ServiceProfile.location, user_point))

        result = await db.execute(stmt.limit(50))
        rows = result.all()

        # Rangsorolási logika alkalmazása
        results = []
        for s_prof, org in rows:
            results.append({
                "id": org.id,
                "name": org.full_name,
                "trust_score": s_prof.trust_score,
                "is_verified": s_prof.is_verified,
                "phone": s_prof.contact_phone,
                "website": s_prof.website,
                "is_premium_partner": s_prof.trust_score >= 90
            })

        # Súlyozott rendezés: Prémium partnerek és Trust Score előre
        return sorted(results, key=lambda x: (not is_premium, -x['trust_score']))