from http import HTTPStatus
from typing import TYPE_CHECKING
from unittest.mock import ANY
from uuid import uuid4

from starlette.testclient import TestClient

from testing.util import get_random_string, get_resources_path
from yak_server.cli.database import initialize_database

if TYPE_CHECKING:
    from fastapi import FastAPI
    from sqlalchemy import Engine


def test_bets_by_groups(app_with_valid_jwt_config: "FastAPI", engine_for_test: "Engine") -> None:
    client = TestClient(app_with_valid_jwt_config)

    initialize_database(engine_for_test, get_resources_path("test_compute_points_v1"))

    response_signup = client.post(
        "/api/v1/users/signup",
        json={
            "name": get_random_string(6),
            "first_name": get_random_string(6),
            "last_name": get_random_string(6),
            "password": get_random_string(9),
        },
    )

    assert response_signup.status_code == HTTPStatus.CREATED

    access_token = response_signup.json()["result"]["access_token"]

    # Retrieve all groups
    groups_response = client.get(
        "/api/v1/groups",
        headers={"Authorization": f"Bearer {access_token}"},
    )

    assert groups_response.status_code == HTTPStatus.OK
    group_id = groups_response.json()["result"]["groups"][0]["id"]

    # Success case
    bets_by_valid_group = client.get(
        f"/api/v1/bets/groups/{group_id}",
        headers={"Authorization": f"Bearer {access_token}"},
    )

    assert bets_by_valid_group.json()["result"] == {
        "binary_bets": [
            {
                "id": ANY,
                "locked": False,
                "team1": None,
                "team2": None,
            },
        ],
        "group": {
            "code": "A",
            "description": "Groupe A",
            "id": ANY,
        },
        "phase": {
            "code": "GROUP",
            "description": "Phase de groupes",
            "id": ANY,
        },
        "score_bets": [
            {
                "id": ANY,
                "locked": False,
                "team1": {
                    "code": "FR",
                    "description": "France",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
                "team2": {
                    "code": "IE",
                    "description": "Irlande",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
            },
            {
                "id": ANY,
                "locked": False,
                "team1": {
                    "code": "FR",
                    "description": "France",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
                "team2": {
                    "code": "IM",
                    "description": "Île de Man",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
            },
            {
                "id": ANY,
                "locked": False,
                "team1": {
                    "code": "IE",
                    "description": "Irlande",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
                "team2": {
                    "code": "IM",
                    "description": "Île de Man",
                    "flag": {"url": ANY},
                    "id": ANY,
                    "score": None,
                },
            },
        ],
    }

    assert len(bets_by_valid_group.json()["result"]["score_bets"]) == 3
    assert [
        (score_bet["team1"]["flag"]["url"], score_bet["team2"]["flag"]["url"])
        for score_bet in bets_by_valid_group.json()["result"]["score_bets"]
    ] == [
        ("https://fake-team-flag_france.com", "https://fake-team-flag_ireland.com"),
        ("https://fake-team-flag_france.com", "https://fake-team-flag_isle_of_man.com"),
        ("https://fake-team-flag_ireland.com", "https://fake-team-flag_isle_of_man.com"),
    ]

    # Error case : invalid group code
    invalid_group_code = uuid4()

    bets_by_invalid_group_code = client.get(
        f"/api/v1/bets/groups/{invalid_group_code}",
        headers={"Authorization": f"Bearer {access_token}"},
    )

    assert bets_by_invalid_group_code.json() == {
        "ok": False,
        "error_code": HTTPStatus.NOT_FOUND,
        "description": f"Group not found: {invalid_group_code}",
    }
