"""Recording transport for fixture-driven EduBridge tests."""

from __future__ import annotations

from typing import Any

from test_support.transport_base import BaseRecordingTransport
from test_support.transport_helpers import dump_model
from timeback_common import EdubridgePaths

from ..types import (
    Application,
    ApplicationMetrics,
    DefaultClass,
    Enrollment,
    HighestGradeMastered,
    MapProfile,
    ResetGoalsResult,
    SubjectTrack,
    SubjectTrackGroup,
    TimeSaved,
    User,
    WeeklyFactRecord,
)


def create_recording_transport(
    fail_request: dict[str, Any] | None = None,
    transport_config: dict[str, Any] | None = None,
) -> BaseRecordingTransport:
    """Create a transport-like object that records calls and returns stub responses."""
    return _EdubridgeRecordingTransport(
        fail_request=fail_request, transport_config=transport_config
    )


class _EdubridgeRecordingTransport(BaseRecordingTransport):
    """EduBridge-specific recording transport with path-aware stubs."""

    def __init__(self, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self.paths = EdubridgePaths()
        self._apply_exclude_paths()

    def _default_get_stub(self, path: str) -> dict[str, Any]:
        if "/analytics/activity" in path or "/analytics/enrollment/" in path:
            return {"facts": _stub_daily_facts()}
        if "/analytics/facts/weekly" in path:
            return {"facts": [dump_model(_stub_weekly_fact())]}
        if "/analytics/highestGradeMastered/" in path:
            return dump_model(_stub_highest_grade_mastered())
        if "/applications/" in path:
            return {"applications": [dump_model(_stub_application())]}
        if "/applicationMetrics/" in path:
            return {"data": dump_model(_stub_application_metrics())}
        if "/enrollments/user/" in path:
            return {"data": [dump_model(_stub_enrollment())]}
        if "/enrollments/defaultClass/" in path:
            return {"data": dump_model(_stub_default_class())}
        if "/learning-reports/map-profile/" in path:
            return {"data": dump_model(_stub_map_profile())}
        if "/time-saved/user/" in path:
            return {"data": dump_model(_stub_time_saved())}
        if "/subject-track/groups" in path:
            return {"groups": [dump_model(_stub_subject_track_group())]}
        if "/subject-track/" in path:
            return {"subjectTrack": [dump_model(_stub_subject_track())]}
        if "/users/" in path:
            return {"users": [dump_model(_stub_user())]}
        return {}

    def _default_post_stub(self, path: str) -> dict[str, Any]:
        if "/enrollments/enroll/" in path:
            return {"data": dump_model(_stub_enrollment())}
        if "/enrollments/resetGoals/" in path:
            return {"data": dump_model(_stub_reset_goals_result())}
        return {}

    def _default_put_stub(self, path: str) -> dict[str, Any]:
        if "/subject-track/" in path:
            return {"subjectTrack": dump_model(_stub_subject_track())}
        return {}


def _stub_daily_facts() -> dict[str, Any]:
    return {
        "2025-01-01": {
            "Math": {
                "activityMetrics": {
                    "xpEarned": 10,
                    "totalQuestions": 8,
                    "correctQuestions": 7,
                    "masteredUnits": 1,
                },
                "timeSpentMetrics": {
                    "activeSeconds": 300,
                    "inactiveSeconds": 30,
                    "wasteSeconds": 5,
                },
                "apps": ["Stub App"],
            }
        }
    }


def _stub_weekly_fact() -> WeeklyFactRecord:
    return WeeklyFactRecord.model_validate(
        {
            "id": 1,
            "email": "student@example.com",
            "date": "2025-01-01",
            "datetime": "2025-01-01T12:00:00Z",
            "source": "activity",
            "year": 2025,
            "month": 1,
            "day": 1,
            "dayOfWeek": 3,
        }
    )


def _stub_highest_grade_mastered() -> HighestGradeMastered:
    return HighestGradeMastered.model_validate(
        {
            "studentId": "student-001",
            "subject": "Math",
            "grades": {"ritGrade": 220, "highestGradeOverall": "8"},
        }
    )


def _stub_application() -> Application:
    return Application.model_validate(
        {"sourcedId": "app-001", "name": "Stub App", "domain": ["stub.example.com"]}
    )


def _stub_application_metrics() -> ApplicationMetrics:
    return ApplicationMetrics.model_validate({"applicationSourcedId": "app-001", "totalUsers": 1})


def _stub_enrollment() -> Enrollment:
    return Enrollment.model_validate(
        {
            "id": "enroll-001",
            "role": "student",
            "course": {"id": "course-001", "title": "Stub Course", "metadata": {}},
            "school": {"id": "school-001", "name": "Stub School"},
            "testOutSupported": True,
            "testOutEligible": False,
        }
    )


def _stub_default_class() -> DefaultClass:
    return DefaultClass.model_validate(
        {
            "id": "class-001",
            "title": "Stub Class",
            "subjectCodes": ["MATH"],
            "subjects": ["Math"],
            "periods": ["term-001"],
            "course": {"id": "course-001", "title": "Stub Course", "metadata": {}},
        }
    )


def _stub_map_profile() -> MapProfile:
    return MapProfile.model_validate({"userId": "user-001", "ritScore": 210, "subject": "Math"})


def _stub_time_saved() -> TimeSaved:
    return TimeSaved.model_validate({"totalHoursSaved": 1.5, "totalDaysSaved": 0.2})


def _stub_subject_track() -> SubjectTrack:
    return SubjectTrack.model_validate(
        {
            "id": "track-001",
            "subject": "Math",
            "grade": "9",
            "course": {"sourcedId": "course-001", "title": "Stub Course"},
            "org": {"sourcedId": "school-001", "name": "Stub School"},
        }
    )


def _stub_subject_track_group() -> SubjectTrackGroup:
    return SubjectTrackGroup.model_validate(
        {
            "id": "group-001",
            "name": "Stub Group",
            "tracks": [dump_model(_stub_subject_track())],
        }
    )


def _stub_user() -> User:
    return User.model_validate(
        {
            "sourcedId": "user-001",
            "status": "active",
            "dateLastModified": "2025-01-01T00:00:00Z",
            "userIds": [{"type": "email", "identifier": "student@example.com"}],
            "enabledUser": "true",
            "givenName": "Stub",
            "familyName": "Student",
            "roles": [],
            "agents": [],
            "userProfiles": [],
        }
    )


def _stub_reset_goals_result() -> ResetGoalsResult:
    return ResetGoalsResult(updated=1, errors=[])
