"""Competition & Event Management tests — Phase 9.7."""
from __future__ import annotations

from datetime import datetime, timezone

import pytest

from app.events.publisher import get_event_publisher
from app.events.types import SportsCenterEventType
from app.tests.conftest import TENANT_A, TENANT_B, tenant_headers


async def _seed(client, headers):
    center = await client.post(
        "/api/v1/sports-centers",
        json={"code": "cp97", "name": "Competition Center", "status": "active"},
        headers=headers,
    )
    assert center.status_code == 201
    center_id = center.json()["id"]
    member = await client.post(
        "/api/v1/members",
        json={"sports_center_id": center_id, "display_name": "Competitor", "status": "active"},
        headers=headers,
    )
    assert member.status_code == 201
    coach = await client.post(
        "/api/v1/coaches",
        json={"sports_center_id": center_id, "code": "j1", "display_name": "Judge One"},
        headers=headers,
    )
    assert coach.status_code == 201
    return center_id, member.json()["id"], coach.json()["id"]


@pytest.mark.asyncio
async def test_competition_happy_path(client):
    headers = tenant_headers(TENANT_A)
    center_id, member_id, coach_id = await _seed(client, headers)

    competition = await client.post(
        "/api/v1/competitions",
        json={
            "sports_center_id": center_id,
            "code": "cup1",
            "name": "Summer Cup",
            "max_teams": 8,
        },
        headers=headers,
    )
    assert competition.status_code == 201, competition.text
    competition_id = competition.json()["id"]

    team_a = await client.post(
        "/api/v1/competition-teams",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "code": "ta",
            "name": "Team Alpha",
        },
        headers=headers,
    )
    team_b = await client.post(
        "/api/v1/competition-teams",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "code": "tb",
            "name": "Team Beta",
        },
        headers=headers,
    )
    assert team_a.status_code == 201 and team_b.status_code == 201

    registration = await client.post(
        "/api/v1/competition-registrations",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "member_id": member_id,
            "team_id": team_a.json()["id"],
        },
        headers=headers,
    )
    assert registration.status_code == 201, registration.text
    reg_id = registration.json()["id"]
    confirm = await client.post(f"/api/v1/competition-registrations/{reg_id}/confirm", headers=headers)
    assert confirm.status_code == 200

    match = await client.post(
        "/api/v1/competition-matches",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "code": "m1",
            "home_team_id": team_a.json()["id"],
            "away_team_id": team_b.json()["id"],
            "scheduled_at": datetime.now(timezone.utc).isoformat(),
        },
        headers=headers,
    )
    assert match.status_code == 201, match.text

    result = await client.post(
        "/api/v1/competition-results",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "match_id": match.json()["id"],
            "home_score": 2,
            "away_score": 1,
            "winner_team_id": team_a.json()["id"],
            "outcome": "win",
        },
        headers=headers,
    )
    assert result.status_code == 201, result.text

    rankings = await client.get(
        f"/api/v1/competition-rankings?competition_id={competition_id}",
        headers=headers,
    )
    assert rankings.status_code == 200
    assert len(rankings.json()) >= 1

    medal = await client.post(
        "/api/v1/competition-medals",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "member_id": member_id,
            "medal_kind": "gold",
        },
        headers=headers,
    )
    assert medal.status_code == 201, medal.text

    judge = await client.post(
        "/api/v1/competition-judges",
        json={
            "sports_center_id": center_id,
            "competition_id": competition_id,
            "coach_id": coach_id,
            "role": "head_judge",
        },
        headers=headers,
    )
    assert judge.status_code == 201, judge.text

    events = get_event_publisher().published
    assert any(e.event_type == SportsCenterEventType.COMPETITION_CREATED for e in events)
    assert any(e.event_type == SportsCenterEventType.COMPETITION_RESULT_RECORDED for e in events)


@pytest.mark.asyncio
async def test_competition_tenant_isolation(client):
    headers_a = tenant_headers(TENANT_A)
    headers_b = tenant_headers(TENANT_B)
    center_id, _, _ = await _seed(client, headers_a)
    competition = await client.post(
        "/api/v1/competitions",
        json={"sports_center_id": center_id, "code": "iso", "name": "Iso Cup"},
        headers=headers_a,
    )
    competition_id = competition.json()["id"]
    other = await client.patch(
        f"/api/v1/competitions/{competition_id}",
        json={"name": "Hacked"},
        headers=headers_b,
    )
    assert other.status_code in (404, 403)


@pytest.mark.asyncio
async def test_capabilities_phase_97(client):
    resp = await client.get("/capabilities")
    data = resp.json()
    assert data["phase"] == "9.7"
    assert data["version"] == "0.9.7.0"
    assert data["features"]["competition_management"] is True
