# [DEF:backend.src.api.routes.profile:Module]
#
# @TIER:      CRITICAL
# @SEMANTICS: api, profile, preferences, self-service, account-lookup
# @PURPOSE:   Exposes self-scoped profile preference endpoints and environment-based Superset account lookup.
# @LAYER:     API
# @RELATION:  DEPENDS_ON -> backend.src.services.profile_service
# @RELATION:  DEPENDS_ON -> backend.src.dependencies.get_current_user
# @RELATION:  DEPENDS_ON -> backend.src.core.database.get_db
#
# @INVARIANT: Endpoints are self-scoped and never mutate another user preference.
# @UX_STATE: ProfileLoad -> Returns stable ProfilePreferenceResponse for authenticated user.
# @UX_STATE: Saving -> Validation errors map to actionable 422 details.
# @UX_STATE: LookupLoading -> Returns success/degraded Superset lookup payload.
# @UX_FEEDBACK: Stable status/message/warning payloads support profile page feedback.
# @UX_RECOVERY: Lookup degradation keeps manual username save path available.

# [SECTION: IMPORTS]
from typing import Optional

from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session

from ...core.database import get_db
from ...core.logger import logger, belief_scope
from ...dependencies import (
    get_config_manager,
    get_current_user,
    get_plugin_loader,
)
from ...models.auth import User
from ...schemas.profile import (
    ProfilePreferenceResponse,
    ProfilePreferenceUpdateRequest,
    SupersetAccountLookupRequest,
    SupersetAccountLookupResponse,
)
from ...services.profile_service import (
    EnvironmentNotFoundError,
    ProfileAuthorizationError,
    ProfileService,
    ProfileValidationError,
)
# [/SECTION]

router = APIRouter(prefix="/api/profile", tags=["profile"])


# [DEF:_get_profile_service:Function]
# @PURPOSE: Build profile service for current request scope.
# @PRE: db session and config manager are available.
# @POST: Returns a ready ProfileService instance.
def _get_profile_service(db: Session, config_manager, plugin_loader=None) -> ProfileService:
    return ProfileService(
        db=db,
        config_manager=config_manager,
        plugin_loader=plugin_loader,
    )
# [/DEF:_get_profile_service:Function]


# [DEF:get_preferences:Function]
# @PURPOSE: Get authenticated user's dashboard filter preference.
# @PRE: Valid JWT and authenticated user context.
# @POST: Returns preference payload for current user only.
@router.get("/preferences", response_model=ProfilePreferenceResponse)
async def get_preferences(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    config_manager=Depends(get_config_manager),
    plugin_loader=Depends(get_plugin_loader),
):
    with belief_scope("profile.get_preferences", f"user_id={current_user.id}"):
        logger.reason("[REASON] Resolving current user preference")
        service = _get_profile_service(db, config_manager, plugin_loader)
        return service.get_my_preference(current_user)
# [/DEF:get_preferences:Function]


# [DEF:update_preferences:Function]
# @PURPOSE: Update authenticated user's dashboard filter preference.
# @PRE: Valid JWT and valid request payload.
# @POST: Persists normalized preference for current user or raises validation/authorization errors.
@router.patch("/preferences", response_model=ProfilePreferenceResponse)
async def update_preferences(
    payload: ProfilePreferenceUpdateRequest,
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    config_manager=Depends(get_config_manager),
    plugin_loader=Depends(get_plugin_loader),
):
    with belief_scope("profile.update_preferences", f"user_id={current_user.id}"):
        service = _get_profile_service(db, config_manager, plugin_loader)
        try:
            logger.reason("[REASON] Attempting preference save")
            return service.update_my_preference(current_user=current_user, payload=payload)
        except ProfileValidationError as exc:
            logger.reflect("[REFLECT] Preference validation failed")
            raise HTTPException(status_code=422, detail=exc.errors) from exc
        except ProfileAuthorizationError as exc:
            logger.explore("[EXPLORE] Cross-user mutation guard blocked request")
            raise HTTPException(status_code=403, detail=str(exc)) from exc
# [/DEF:update_preferences:Function]


# [DEF:lookup_superset_accounts:Function]
# @PURPOSE: Lookup Superset account candidates in selected environment.
# @PRE: Valid JWT, authenticated context, and environment_id query parameter.
# @POST: Returns success or degraded lookup payload with stable shape.
@router.get("/superset-accounts", response_model=SupersetAccountLookupResponse)
async def lookup_superset_accounts(
    environment_id: str = Query(...),
    search: Optional[str] = Query(default=None),
    page_index: int = Query(default=0, ge=0),
    page_size: int = Query(default=20, ge=1, le=100),
    sort_column: str = Query(default="username"),
    sort_order: str = Query(default="desc"),
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db),
    config_manager=Depends(get_config_manager),
    plugin_loader=Depends(get_plugin_loader),
):
    with belief_scope(
        "profile.lookup_superset_accounts",
        f"user_id={current_user.id}, environment_id={environment_id}",
    ):
        service = _get_profile_service(db, config_manager, plugin_loader)
        lookup_request = SupersetAccountLookupRequest(
            environment_id=environment_id,
            search=search,
            page_index=page_index,
            page_size=page_size,
            sort_column=sort_column,
            sort_order=sort_order,
        )
        try:
            logger.reason("[REASON] Executing Superset account lookup")
            return service.lookup_superset_accounts(
                current_user=current_user,
                request=lookup_request,
            )
        except EnvironmentNotFoundError as exc:
            logger.explore("[EXPLORE] Lookup request references unknown environment")
            raise HTTPException(status_code=404, detail=str(exc)) from exc
# [/DEF:lookup_superset_accounts:Function]

# [/DEF:backend.src.api.routes.profile:Module]