"""
Placement Resource

PowerPath placement testing operations.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any
from urllib.parse import quote

from timeback_common import serialize_input, validate_non_empty_string, validate_with_schema

from ..types.inputs import PlacementQueryParams, PlacementResetUserPlacementInput
from ..types.responses import (
    GetAllPlacementTestsResponse,
    GetCurrentLevelResponse,
    GetNextPlacementTestResponse,
    GetSubjectProgressResponse,
    ResetPlacementResponse,
)

if TYPE_CHECKING:
    from ..lib.transport import Transport


class PlacementResource:
    """Placement resource for PowerPath placement APIs."""

    def __init__(self, transport: Transport) -> None:
        self._transport = transport

    @property
    def _base_path(self) -> str:
        return self._transport.paths.base

    async def get_placement(self, student_id: str) -> dict[str, Any]:
        """Get placement data for a student."""
        validate_non_empty_string(student_id, "student_id")
        return await self._transport.get(
            f"{self._base_path}/placement/{quote(student_id, safe='')}"
        )

    async def get_all_placement_tests(
        self, params: PlacementQueryParams | dict[str, Any]
    ) -> GetAllPlacementTestsResponse:
        """Get all placement tests for a student."""
        validate_with_schema(PlacementQueryParams, params, "get all placement tests")
        body = await self._transport.get(
            f"{self._base_path}/placement/getAllPlacementTests",
            params=serialize_input(params, PlacementQueryParams),
        )
        return GetAllPlacementTestsResponse.model_validate(body)

    async def get_current_level(
        self, params: PlacementQueryParams | dict[str, Any]
    ) -> GetCurrentLevelResponse:
        """Get current placement level for a student."""
        validate_with_schema(PlacementQueryParams, params, "get current level")
        body = await self._transport.get(
            f"{self._base_path}/placement/getCurrentLevel",
            params=serialize_input(params, PlacementQueryParams),
        )
        return GetCurrentLevelResponse.model_validate(body)

    async def get_next_placement_test(
        self, params: PlacementQueryParams | dict[str, Any]
    ) -> GetNextPlacementTestResponse:
        """Get the next placement test for a student."""
        validate_with_schema(PlacementQueryParams, params, "get next placement test")
        body = await self._transport.get(
            f"{self._base_path}/placement/getNextPlacementTest",
            params=serialize_input(params, PlacementQueryParams),
        )
        return GetNextPlacementTestResponse.model_validate(body)

    async def get_subject_progress(
        self, params: PlacementQueryParams | dict[str, Any]
    ) -> GetSubjectProgressResponse:
        """Get subject progress for a student."""
        validate_with_schema(PlacementQueryParams, params, "get subject progress")
        body = await self._transport.get(
            f"{self._base_path}/placement/getSubjectProgress",
            params=serialize_input(params, PlacementQueryParams),
        )
        return GetSubjectProgressResponse.model_validate(body)

    async def reset_user_placement(
        self, input: PlacementResetUserPlacementInput | dict[str, Any]
    ) -> ResetPlacementResponse:
        """Reset user placement."""
        validate_with_schema(
            PlacementResetUserPlacementInput, input, "placement reset user placement"
        )
        body = await self._transport.post(
            f"{self._base_path}/placement/resetUserPlacement",
            serialize_input(input, PlacementResetUserPlacementInput),
        )
        return ResetPlacementResponse.model_validate(body)
