"""Tests for PowerPath client-side validation.

Validates that resources reject invalid input before making network requests.
"""

import pytest

from timeback_common import InputValidationError
from timeback_powerpath.resources.assessment import AssessmentResource
from timeback_powerpath.resources.lesson_plans import LessonPlansResource
from timeback_powerpath.resources.placement import PlacementResource
from timeback_powerpath.resources.syllabus import SyllabusResource
from timeback_powerpath.resources.test_assignments import TestAssignmentsResource


class MockPaths:
    base = "/powerpath"


class MockTransport:
    """Stub transport that tracks whether any request was made."""

    def __init__(self):
        self.request_count = 0
        self.paths = MockPaths()
        self.base_url = "https://example.test"

    async def get(self, _path, *, params=None):  # noqa: ARG002
        self.request_count += 1
        raise RuntimeError("request should not be called")

    async def post(self, _path, _data=None, *, headers=None):  # noqa: ARG002
        self.request_count += 1
        raise RuntimeError("request should not be called")

    async def put(self, _path, _data=None, *, headers=None):  # noqa: ARG002
        self.request_count += 1
        raise RuntimeError("request should not be called")

    async def delete(self, _path, *, headers=None):  # noqa: ARG002
        self.request_count += 1
        raise RuntimeError("request should not be called")

    async def close(self):
        pass


class TestLessonPlansValidation:
    """Tests for lesson plans validation."""

    @pytest.mark.asyncio
    async def test_create_validates_input(self):
        """create() should validate input before request."""
        transport = MockTransport()
        resource = LessonPlansResource(transport)

        with pytest.raises(InputValidationError):
            await resource.create({"courseId": "", "userId": "user-1"})

        assert transport.request_count == 0


class TestAssessmentValidation:
    """Tests for assessment validation."""

    @pytest.mark.asyncio
    async def test_update_student_question_response_validates(self):
        """updateStudentQuestionResponse should validate input before request."""
        transport = MockTransport()
        resource = AssessmentResource(transport)

        with pytest.raises(InputValidationError):
            await resource.update_student_question_response(
                {
                    "student": "",
                    "question": "question-1",
                    "lesson": "lesson-1",
                }
            )

        assert transport.request_count == 0

    @pytest.mark.asyncio
    async def test_get_assessment_progress_validates(self):
        """getAssessmentProgress should validate params before request."""
        transport = MockTransport()
        resource = AssessmentResource(transport)

        with pytest.raises(InputValidationError):
            await resource.get_assessment_progress({"student": "", "lesson": "lesson-1"})

        assert transport.request_count == 0


class TestPlacementValidation:
    """Tests for placement validation."""

    @pytest.mark.asyncio
    async def test_get_next_placement_test_validates(self):
        """getNextPlacementTest should validate params before request."""
        transport = MockTransport()
        resource = PlacementResource(transport)

        with pytest.raises(InputValidationError):
            await resource.get_next_placement_test({"student": "", "subject": "Math"})

        assert transport.request_count == 0

    @pytest.mark.asyncio
    async def test_reset_user_placement_validates(self):
        """resetUserPlacement should validate input before request."""
        transport = MockTransport()
        resource = PlacementResource(transport)

        with pytest.raises(InputValidationError):
            await resource.reset_user_placement({"student": "student-1", "subject": "Unknown"})

        assert transport.request_count == 0


class TestTestAssignmentsValidation:
    """Tests for test assignments validation."""

    @pytest.mark.asyncio
    async def test_create_validates_input(self):
        """create() should validate input before request."""
        transport = MockTransport()
        resource = TestAssignmentsResource(transport)

        with pytest.raises(InputValidationError):
            await resource.create({"student": "", "subject": "Math", "grade": 4})

        assert transport.request_count == 0


class TestSyllabusValidation:
    """Tests for syllabus validation."""

    @pytest.mark.asyncio
    async def test_get_validates_query_params(self):
        """get() should validate query params before request."""
        transport = MockTransport()
        resource = SyllabusResource(transport)

        with pytest.raises(InputValidationError):
            await resource.get("course-1", {"status": "bad"})

        assert transport.request_count == 0
