"""Scheduling & Booking tests — Phase 9.4."""
from __future__ import annotations

from datetime import datetime, timedelta, timezone

import pytest

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": "bk94", "name": "Booking 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": "Book Member", "status": "active"},
        headers=headers,
    )
    assert member.status_code == 201
    return center_id, member.json()["id"]


@pytest.mark.asyncio
async def test_booking_happy_path(client):
    headers = tenant_headers(TENANT_A)
    center_id, member_id = await _seed(client, headers)
    now = datetime.now(timezone.utc)
    session = await client.post(
        "/api/v1/sessions",
        json={
            "sports_center_id": center_id,
            "code": "sess1",
            "title": "Morning Class",
            "starts_at": (now + timedelta(hours=1)).isoformat(),
            "ends_at": (now + timedelta(hours=2)).isoformat(),
            "capacity": 10,
        },
        headers=headers,
    )
    assert session.status_code == 201, session.text
    session_id = session.json()["id"]

    booking = await client.post(
        "/api/v1/bookings",
        json={
            "sports_center_id": center_id,
            "session_id": session_id,
            "member_id": member_id,
        },
        headers=headers,
    )
    assert booking.status_code == 201, booking.text
    booking_id = booking.json()["id"]

    confirm = await client.post(f"/api/v1/bookings/{booking_id}/confirm", headers=headers)
    assert confirm.status_code == 200
    assert confirm.json()["status"] == "confirmed"


@pytest.mark.asyncio
async def test_session_conflict(client):
    headers = tenant_headers(TENANT_A)
    center_id, _ = await _seed(client, headers)
    now = datetime.now(timezone.utc)
    payload = {
        "sports_center_id": center_id,
        "code": "conf1",
        "title": "Conflict A",
        "starts_at": (now + timedelta(hours=1)).isoformat(),
        "ends_at": (now + timedelta(hours=2)).isoformat(),
        "capacity": 5,
    }
    first = await client.post("/api/v1/sessions", json=payload, headers=headers)
    assert first.status_code == 201
    payload["code"] = "conf2"
    second = await client.post("/api/v1/sessions", json=payload, headers=headers)
    assert second.status_code == 409 or second.status_code == 400


@pytest.mark.asyncio
async def test_booking_tenant_isolation(client):
    headers_a = tenant_headers(TENANT_A)
    headers_b = tenant_headers(TENANT_B)
    center_id, member_id = await _seed(client, headers_a)
    now = datetime.now(timezone.utc)
    session = await client.post(
        "/api/v1/sessions",
        json={
            "sports_center_id": center_id,
            "code": "iso1",
            "title": "Iso",
            "starts_at": (now + timedelta(hours=1)).isoformat(),
            "ends_at": (now + timedelta(hours=2)).isoformat(),
            "capacity": 1,
        },
        headers=headers_a,
    )
    session_id = session.json()["id"]
    booking = await client.post(
        "/api/v1/bookings",
        json={"sports_center_id": center_id, "session_id": session_id, "member_id": member_id},
        headers=headers_a,
    )
    booking_id = booking.json()["id"]
    other = await client.post(f"/api/v1/bookings/{booking_id}/confirm", headers=headers_b)
    assert other.status_code in (404, 403)
