from __future__ import annotations

from datetime import datetime, timezone
from types import SimpleNamespace
from uuid import uuid4

import pytest

from backend.app.repositories import StationRepository, TrackRepository, TrainRepository
from backend.app.services.network import get_network_snapshot


@pytest.fixture
def sample_entities() -> dict[str, SimpleNamespace]:
    timestamp = datetime.now(timezone.utc)
    station = SimpleNamespace(
        id=uuid4(),
        name="Test Station",
        location=None,
        created_at=timestamp,
        updated_at=timestamp,
    )
    track = SimpleNamespace(
        id=uuid4(),
        start_station_id=station.id,
        end_station_id=station.id,
        length_meters=1234.5,
        max_speed_kph=160,
        status="operational",
        is_bidirectional=True,
        track_geometry=None,
        created_at=timestamp,
        updated_at=timestamp,
    )
    train = SimpleNamespace(
        id=uuid4(),
        designation="Test Express",
        capacity=200,
        max_speed_kph=220,
        created_at=timestamp,
        updated_at=timestamp,
    )
    return {"station": station, "track": track, "train": train}


def test_network_snapshot_prefers_repository_data(
    monkeypatch: pytest.MonkeyPatch, sample_entities: dict[str, SimpleNamespace]
) -> None:
    station = sample_entities["station"]
    track = sample_entities["track"]
    train = sample_entities["train"]

    monkeypatch.setattr(StationRepository, "list_active",
                        lambda self: [station])
    monkeypatch.setattr(TrackRepository, "list_all", lambda self: [track])
    monkeypatch.setattr(TrainRepository, "list_all", lambda self: [train])

    snapshot = get_network_snapshot(session=None)  # type: ignore[arg-type]

    assert snapshot["stations"]
    assert snapshot["stations"][0]["name"] == station.name
    assert snapshot["tracks"][0]["lengthMeters"] == pytest.approx(
        track.length_meters)
    assert snapshot["trains"][0]["designation"] == train.designation
    assert snapshot["trains"][0]["operatingTrackIds"] == []


def test_network_snapshot_falls_back_when_repositories_empty(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    monkeypatch.setattr(StationRepository, "list_active", lambda self: [])
    monkeypatch.setattr(TrackRepository, "list_all", lambda self: [])
    monkeypatch.setattr(TrainRepository, "list_all", lambda self: [])

    snapshot = get_network_snapshot(session=None)  # type: ignore[arg-type]

    assert snapshot["stations"]
    assert snapshot["trains"]
    assert any(station["name"] ==
               "Central" for station in snapshot["stations"])
