# /opt/docker/dev/service_finder/backend/app/services/system_service.py
"""
Hierarchikus System Parameters szolgáltatás.
A rendszerparaméterek prioritásos felülbírálást támogatnak: User > Region > Country > Global.
"""

import logging
from typing import Optional, Any, Dict
from sqlalchemy import select, func  # HOZZÁADVA: func a NOW() híváshoz
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload

from app.models.system import SystemParameter, ParameterScope

logger = logging.getLogger(__name__)


class SystemService:
    """
    Rendszerparaméterek kezelése hierarchikus scope-okkal.
    """

    async def get_scoped_parameter(
        self,
        db: AsyncSession,
        key: str,
        user_id: Optional[str] = None,
        region_id: Optional[str] = None,
        country_code: Optional[str] = None,
        default: Any = None,
    ) -> Any:
        """
        Lekéri a paraméter értékét a következő prioritási sorrendben:
        1. USER scope (ha user_id megadva)
        2. REGION scope (ha region_id megadva)
        3. COUNTRY scope (ha country_code megadva)
        4. GLOBAL scope

        Ha egy scope-ban nem található a paraméter, a következő scope-ot próbálja.
        Visszaadja a paraméter JSON értékét (általában dict), vagy a default értéket.

        :param db: Adatbázis munkamenet
        :param key: A paraméter kulcsa
        :param user_id: Felhasználó azonosítója (opcionális)
        :param region_id: Régió azonosítója (opcionális)
        :param country_code: Országkód (pl. 'HU', 'GB') (opcionális)
        :param default: Alapértelmezett érték, ha a paraméter nem található
        :return: A paraméter értéke (általában dict) vagy default
        """
        # Prioritási sorrend: USER -> REGION -> COUNTRY -> GLOBAL
        scopes = []
        if user_id:
            scopes.append((ParameterScope.USER, str(user_id)))
        if region_id:
            scopes.append((ParameterScope.REGION, str(region_id)))
        if country_code:
            scopes.append((ParameterScope.COUNTRY, str(country_code)))
        scopes.append((ParameterScope.GLOBAL, None))

        for scope_level, scope_id in scopes:
            stmt = select(SystemParameter).where(
                SystemParameter.key == key,
                SystemParameter.scope_level == scope_level,
                SystemParameter.is_active == True,
            )
            if scope_id is not None:
                stmt = stmt.where(SystemParameter.scope_id == scope_id)
            else:
                stmt = stmt.where(SystemParameter.scope_id.is_(None))

            result = await db.execute(stmt)
            param = result.scalar_one_or_none()
            if param is not None:
                logger.debug(
                    f"Paraméter '{key}' található {scope_level.value} scope-ban (scope_id={scope_id})"
                )
                return param.value
            else:
                logger.debug(
                    f"Paraméter '{key}' nem található {scope_level.value} scope-ban (scope_id={scope_id})"
                )

        logger.info(f"Paraméter '{key}' nem található egyetlen scope-ban sem, default értéket használunk")
        return default

    async def set_scoped_parameter(
        self,
        db: AsyncSession,
        key: str,
        value: Dict,
        scope_level: ParameterScope,
        scope_id: Optional[str] = None,
        category: str = "general",
        description: Optional[str] = None,
        last_modified_by: Optional[int] = None,
    ) -> SystemParameter:
        """
        Létrehoz vagy frissít egy rendszerparamétert a megadott scope-ban.
        Ha már létezik ugyanazzal a kulccsal, scope_level-lel és scope_id-vel, felülírja.
        """
        from sqlalchemy.dialects.postgresql import insert

        # UPSERT logika: ON CONFLICT DO UPDATE
        insert_stmt = insert(SystemParameter).values(
            key=key,
            value=value,
            scope_level=scope_level,
            scope_id=scope_id,
            category=category,
            description=description,
            last_modified_by=last_modified_by,
            is_active=True,
        )
        upsert_stmt = insert_stmt.on_conflict_do_update(
            constraint="uix_param_scope",
            set_=dict(
                value=value,
                category=category,
                description=description,
                last_modified_by=last_modified_by,
                updated_at=func.now(),
            ),
        )
        await db.execute(upsert_stmt)
        await db.commit()

        # Visszaolvassuk a létrehozott/frissített rekordot
        stmt = select(SystemParameter).where(
            SystemParameter.key == key,
            SystemParameter.scope_level == scope_level,
            SystemParameter.scope_id == scope_id,
        )
        result = await db.execute(stmt)
        param = result.scalar_one()
        return param

# --- GLOBÁLIS PÉLDÁNY ÉS SEGÉDFÜGGVÉNYEK ---
# Ezek a fájl legszélén vannak (0-s behúzás), így kívülről importálhatóak!

system_service = SystemService()

async def get_system_parameter(db: AsyncSession, key: str, default: Any = None) -> Any:
    """ 
    Proxy függvény, amit a marketplace_service és más modulok közvetlenül importálnak.
    A globális system_service példányt használja.
    """
    return await system_service.get_scoped_parameter(db, key, default=default)