import copy

from ...fake_data import create_student, create_students, create_year_group
from ...utils import (
    _test_case_client,
    _test_case_client_without_response,
    assert_model_changes,
)

valid_data = {
    "first_name": "Albert",
    "last_name": "Rose",
    "index": 234_343,
    "email": "albert@gmail.com",
}

new_data = {"first_name": "Martin", "last_name": "Green", "pesel": "93030312894"}

data_to_create_student = {
    "first_name": "Albert",
    "last_name": "Marcus",
    "pesel": "93030312896",
    "index": 123_456,
}


def test_list_students(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        create_students(yg, 45)
        data = _test_case_client_without_response(
            client,
            f"/api/coordinator/students/{yg.id}/?per_page=10",
            None,
            200,
            method="get",
        )
        assert data.get("max_pages") == 5
        assert len(data.get("students")) == 10


def test_detail_student(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        st = create_student(valid_data, yg.id)
        data = _test_case_client_without_response(
            client,
            f"/api/coordinator/students/{st.index}/detail/",
            None,
            200,
            method="get",
        )
        assert_model_changes(st, data)


def test_detail_student_if_student_doesnt_exist(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        _test_case_client(
            client,
            "/api/coordinator/students/43/detail/",
            None,
            "Not found student!",
            404,
            method="get",
            key="error",
        )


def test_delete_student(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        st = create_student(valid_data, yg.id)
        _test_case_client(
            client,
            f"/api/coordinator/students/{st.index}/",
            None,
            "Student was deleted!",
            202,
            method="delete",
        )


def test_delete_student_if_student_doesnt_exist(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        _test_case_client(
            client,
            "/api/coordinator/students/43/",
            None,
            "Not found student!",
            404,
            method="delete",
            key="error",
        )


def test_edit_student(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        st = create_student(valid_data, yg.id)
        _test_case_client(
            client,
            f"/api/coordinator/students/{st.index}/",
            new_data,
            "Student was updated!",
            200,
            method="put",
        )


def test_edit_student_with_invalid_data(test_app_with_context) -> None:
    data = copy.copy(new_data)
    data["pesel"] = "43333333333433443"
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        st = create_student(valid_data, yg.id)
        _test_case_client(
            client,
            f"/api/coordinator/students/{st.index}/",
            data,
            "Validation error",
            400,
            method="put",
        )


def test_edit_student_if_student_doesnt_exist(test_app_with_context) -> None:
    with test_app_with_context.test_client() as client:
        _test_case_client(
            client,
            "/api/coordinator/students/54/",
            new_data,
            "Not found student!",
            404,
            method="put",
            key="error",
        )


def test_create_student(test_app_with_context) -> None:
    data = copy.copy(data_to_create_student)
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        data["year_group_id"] = yg.id
        _test_case_client(
            client,
            "/api/coordinator/students/",
            data,
            "Student was created!",
            200,
            method="post",
        )


def test_create_student_with_invalid_data(test_app_with_context) -> None:
    data = copy.copy(data_to_create_student)
    data["pesel"] = "434343434343344"
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        data["year_group_id"] = yg.id
        _test_case_client(
            client,
            "/api/coordinator/students/",
            data,
            "Validation error",
            400,
            method="post",
        )


def test_create_student_if_year_group_doesnt_exist(test_app_with_context) -> None:
    data = copy.copy(data_to_create_student)
    with test_app_with_context.test_client() as client:
        data["year_group_id"] = 34
        _test_case_client(
            client,
            "/api/coordinator/students/",
            data,
            "Not found year group!",
            404,
            method="post",
            key="error",
        )


def test_create_student_if_student_has_already_assigned_to_this_group(
    test_app_with_context,
) -> None:
    data = copy.copy(data_to_create_student)
    with test_app_with_context.test_client() as client:
        yg = create_year_group()
        create_student(data, yg.id)
        data["year_group_id"] = yg.id
        _test_case_client(
            client,
            "/api/coordinator/students/",
            data,
            "You are assigned to this year group!",
            400,
            method="post",
            key="error",
        )