"""Weather source routes: CRUD + test endpoint."""

from fastapi import APIRouter, Depends, HTTPException

from wled_controller.api.auth import AuthRequired
from wled_controller.api.dependencies import (
    fire_entity_event,
    get_weather_manager,
    get_weather_source_store,
)
from wled_controller.api.schemas.weather_sources import (
    WeatherSourceCreate,
    WeatherSourceListResponse,
    WeatherSourceResponse,
    WeatherSourceUpdate,
    WeatherTestResponse,
)
from wled_controller.core.weather.weather_manager import WeatherManager
from wled_controller.core.weather.weather_provider import WMO_CONDITION_NAMES
from wled_controller.storage.base_store import EntityNotFoundError
from wled_controller.storage.weather_source import WeatherSource
from wled_controller.storage.weather_source_store import WeatherSourceStore
from wled_controller.utils import get_logger

logger = get_logger(__name__)

router = APIRouter()


def _to_response(source: WeatherSource) -> WeatherSourceResponse:
    d = source.to_dict()
    return WeatherSourceResponse(
        id=d["id"],
        name=d["name"],
        provider=d["provider"],
        provider_config=d.get("provider_config", {}),
        latitude=d["latitude"],
        longitude=d["longitude"],
        update_interval=d["update_interval"],
        description=d.get("description"),
        tags=d.get("tags", []),
        created_at=source.created_at,
        updated_at=source.updated_at,
    )


@router.get("/api/v1/weather-sources", response_model=WeatherSourceListResponse, tags=["Weather Sources"])
async def list_weather_sources(
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
):
    sources = store.get_all_sources()
    return WeatherSourceListResponse(
        sources=[_to_response(s) for s in sources],
        count=len(sources),
    )


@router.post("/api/v1/weather-sources", response_model=WeatherSourceResponse, status_code=201, tags=["Weather Sources"])
async def create_weather_source(
    data: WeatherSourceCreate,
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
):
    try:
        source = store.create_source(
            name=data.name,
            provider=data.provider,
            provider_config=data.provider_config,
            latitude=data.latitude,
            longitude=data.longitude,
            update_interval=data.update_interval,
            description=data.description,
            tags=data.tags,
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    fire_entity_event("weather_source", "created", source.id)
    return _to_response(source)


@router.get("/api/v1/weather-sources/{source_id}", response_model=WeatherSourceResponse, tags=["Weather Sources"])
async def get_weather_source(
    source_id: str,
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
):
    try:
        return _to_response(store.get_source(source_id))
    except EntityNotFoundError:
        raise HTTPException(status_code=404, detail=f"Weather source {source_id} not found")


@router.put("/api/v1/weather-sources/{source_id}", response_model=WeatherSourceResponse, tags=["Weather Sources"])
async def update_weather_source(
    source_id: str,
    data: WeatherSourceUpdate,
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
    manager: WeatherManager = Depends(get_weather_manager),
):
    try:
        source = store.update_source(
            source_id,
            name=data.name,
            provider=data.provider,
            provider_config=data.provider_config,
            latitude=data.latitude,
            longitude=data.longitude,
            update_interval=data.update_interval,
            description=data.description,
            tags=data.tags,
        )
    except EntityNotFoundError:
        raise HTTPException(status_code=404, detail=f"Weather source {source_id} not found")
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    manager.update_source(source_id)
    fire_entity_event("weather_source", "updated", source.id)
    return _to_response(source)


@router.delete("/api/v1/weather-sources/{source_id}", status_code=204, tags=["Weather Sources"])
async def delete_weather_source(
    source_id: str,
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
):
    try:
        store.delete_source(source_id)
    except EntityNotFoundError:
        raise HTTPException(status_code=404, detail=f"Weather source {source_id} not found")
    fire_entity_event("weather_source", "deleted", source_id)


@router.post("/api/v1/weather-sources/{source_id}/test", response_model=WeatherTestResponse, tags=["Weather Sources"])
async def test_weather_source(
    source_id: str,
    _auth: AuthRequired,
    store: WeatherSourceStore = Depends(get_weather_source_store),
    manager: WeatherManager = Depends(get_weather_manager),
):
    """Force-fetch current weather and return the result."""
    try:
        store.get_source(source_id)  # validate exists
    except EntityNotFoundError:
        raise HTTPException(status_code=404, detail=f"Weather source {source_id} not found")

    data = manager.fetch_now(source_id)
    condition = WMO_CONDITION_NAMES.get(data.code, f"Unknown ({data.code})")
    return WeatherTestResponse(
        code=data.code,
        condition=condition,
        temperature=data.temperature,
        wind_speed=data.wind_speed,
        cloud_cover=data.cloud_cover,
    )
