from fastapi.testclient import TestClient
from sqlmodel import Session, select

from app.db.session import engine, init_db
from app.main import app
from app.models import Child, ScheduleBlock
from tests.conftest import admin_headers


def first_child_id() -> int:
    with Session(engine) as session:
        return session.exec(select(Child).order_by(Child.sort_order)).first().id


def test_schedule_summary_uses_school_blocks_and_external_activities():
    init_db()
    with TestClient(app) as client:
        child_id = first_child_id()
        summary = client.get("/api/schedule/summary", params={"date": "2026-06-16"})

    assert summary.status_code == 200
    child = next(item for item in summary.json()["children"] if item["child_id"] == child_id)
    assert child["school_start"] == "08:20"
    assert child["leave_home_time"] == "08:05"
    assert child["school_end"] == "11:50"
    assert child["has_afternoon_school"] is False
    assert child["afternoon_free_from"] == "11:50"
    assert any(block["title"] == "Gitarre ZI 205" for block in child["external_activities"])


def test_schedule_summary_turnen_requires_sports_gear():
    init_db()
    with TestClient(app) as client:
        child_id = first_child_id()
        summary = client.get("/api/schedule/summary", params={"date": "2026-06-16"})

    child = next(item for item in summary.json()["children"] if item["child_id"] == child_id)
    assert child["requires_sports_gear_today"] is True
    assert any(block["title"] == "Turnen" for block in child["todays_blocks"])


def test_schedule_current_returns_week_grid():
    init_db()
    with TestClient(app) as client:
        response = client.get("/api/schedule/current")

    assert response.status_code == 200
    data = response.json()
    assert [day["label"] for day in data["weekdays"]][:5] == ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag"]
    assert len(data["children"]) == 2
    assert any(slot["is_lunch_break"] for slot in data["time_slots"])
    assert any(block["title"] == "Mädchenriege" and block["counts_as_school"] is False for block in data["blocks"])


def test_admin_schedule_crud_and_delete_removes_from_public_view():
    init_db()
    with TestClient(app) as client:
        headers = admin_headers(client)
        child_id = first_child_id()
        create = client.post(
            "/api/admin/schedule/blocks",
            headers=headers,
            json={
                "child_id": child_id,
                "weekday": 3,
                "title": "Testfach",
                "start_time": "15:20",
                "end_time": "16:05",
                "block_type": "school_subject",
                "counts_as_school": True,
            },
        )
        block_id = create.json()["schedule_block"]["id"]
        patch = client.patch(f"/api/admin/schedule/blocks/{block_id}", headers=headers, json={"title": "Testfach geändert"})
        current = client.get("/api/schedule/current").json()
        delete = client.delete(f"/api/admin/schedule/blocks/{block_id}", headers=headers)
        after_delete = client.get("/api/schedule/current").json()

    assert create.status_code == 201
    assert patch.json()["schedule_block"]["title"] == "Testfach geändert"
    assert any(block["id"] == block_id and block["title"] == "Testfach geändert" for block in current["blocks"])
    assert delete.status_code == 200
    assert all(block["id"] != block_id for block in after_delete["blocks"])


def test_admin_schedule_overlap_warning():
    init_db()
    with TestClient(app) as client:
        headers = admin_headers(client)
        child_id = first_child_id()
        response = client.post(
            "/api/admin/schedule/blocks",
            headers=headers,
            json={
                "child_id": child_id,
                "weekday": 1,
                "title": "Überlappung",
                "start_time": "08:30",
                "end_time": "08:50",
                "block_type": "school_subject",
                "counts_as_school": True,
            },
        )

    assert response.status_code == 201
    assert response.json()["warning"] == "overlap"


def test_seed_from_reference_requires_explicit_confirmation():
    init_db()
    with TestClient(app) as client:
        headers = admin_headers(client)
        missing = client.post("/api/admin/schedule/seed-from-reference", headers=headers, json={"confirm": "NOPE"})
        confirmed = client.post("/api/admin/schedule/seed-from-reference", headers=headers, json={"confirm": "RESET_STUNDENPLAN"})

    assert missing.status_code == 400
    assert missing.json()["detail"]["code"] == "confirmation_required"
    assert confirmed.status_code == 200
    assert confirmed.json()["blocks"]
