"""Tests for route search and search tools."""

from __future__ import annotations

import pytest
import respx
from httpx import Response

from korea_transit_mcp_server.tools.route import (
    _format_duration,
    _format_fare,
    format_route_result,
    search_transit_route,
)
from korea_transit_mcp_server.tools.search import find_nearby_stations, search_station


# ---- Unit tests for formatters ----

def test_format_duration_minutes():
    assert _format_duration(45) == "45분"


def test_format_duration_hours():
    assert _format_duration(90) == "1시간 30분"


def test_format_duration_exact_hours():
    assert _format_duration(120) == "2시간"


def test_format_fare():
    assert _format_fare(1250) == "1,250원"


def test_format_route_result_empty():
    assert "찾을 수 없습니다" in format_route_result({})
    assert "찾을 수 없습니다" in format_route_result({"result": {}})
    assert "찾을 수 없습니다" in format_route_result({"result": {"path": []}})


def test_format_route_result_with_paths():
    data = {
        "result": {
            "path": [
                {
                    "info": {
                        "totalTime": 55,
                        "totalWalk": 400,
                        "payment": 1350,
                        "busTransitCount": 0,
                        "subwayTransitCount": 1,
                    },
                    "subPath": [
                        {"trafficType": 3, "distance": 200, "sectionTime": 3},
                        {
                            "trafficType": 1,
                            "lane": [{"name": "2호선"}],
                            "startName": "강남",
                            "endName": "교대",
                            "stationCount": 1,
                            "sectionTime": 2,
                        },
                        {"trafficType": 3, "distance": 150, "sectionTime": 2},
                    ],
                }
            ]
        }
    }
    result = format_route_result(data)
    assert "1개 경로" in result
    assert "55분" in result
    assert "1,350원" in result
    assert "2호선" in result
    assert "강남" in result
    assert "교대" in result
    assert "도보" in result


# ---- Integration tests with mocked HTTP ----

ODSAY_BASE = "https://api.odsay.com/v1/api"


@respx.mock
@pytest.mark.asyncio
async def test_search_transit_route():
    """Test full route search with station resolution + route search."""
    # Mock station search for "강남역"
    respx.get(f"{ODSAY_BASE}/searchStation").mock(
        side_effect=[
            Response(200, json={
                "result": {
                    "station": [
                        {"stationName": "강남역", "stationID": "100", "x": "127.028", "y": "37.498"}
                    ]
                }
            }),
            Response(200, json={
                "result": {
                    "station": [
                        {"stationName": "판교역", "stationID": "200", "x": "127.111", "y": "37.394"}
                    ]
                }
            }),
        ]
    )

    # Mock route search
    respx.get(f"{ODSAY_BASE}/searchPubTransPathT").mock(
        return_value=Response(200, json={
            "result": {
                "path": [
                    {
                        "info": {
                            "totalTime": 40,
                            "totalWalk": 300,
                            "payment": 2050,
                            "busTransitCount": 0,
                            "subwayTransitCount": 1,
                        },
                        "subPath": [
                            {"trafficType": 3, "distance": 150, "sectionTime": 2},
                            {
                                "trafficType": 1,
                                "lane": [{"name": "신분당선"}],
                                "startName": "강남",
                                "endName": "판교",
                                "stationCount": 3,
                                "sectionTime": 15,
                            },
                        ],
                    }
                ]
            }
        })
    )

    result = await search_transit_route("강남역", "판교역")
    assert "1개 경로" in result
    assert "40분" in result
    assert "신분당선" in result


@respx.mock
@pytest.mark.asyncio
async def test_search_station():
    respx.get(f"{ODSAY_BASE}/searchStation").mock(
        return_value=Response(200, json={
            "result": {
                "station": [
                    {
                        "stationName": "강남역",
                        "stationID": "100",
                        "stationClass": "2",
                        "x": "127.028",
                        "y": "37.498",
                        "laneName": "2호선, 신분당선",
                    }
                ]
            }
        })
    )

    result = await search_station("강남역")
    assert "강남역" in result
    assert "지하철역" in result


@respx.mock
@pytest.mark.asyncio
async def test_find_nearby_stations():
    respx.get(f"{ODSAY_BASE}/pointSearch").mock(
        return_value=Response(200, json={
            "result": {
                "station": [
                    {
                        "stationName": "강남역",
                        "stationID": "100",
                        "stationClass": "2",
                        "x": "127.028",
                        "y": "37.498",
                        "distance": "120",
                    }
                ]
            }
        })
    )

    result = await find_nearby_stations(127.027, 37.498, 500)
    assert "강남역" in result
    assert "120m" in result
