import datetime
from pathlib import Path
from typing import Annotated

from fastapi import APIRouter, Depends
from fastapi.responses import HTMLResponse, RedirectResponse

from gallery.easel.core import AppRequest
from gallery.sketch.weather.api import WeatherApi
from gallery.sketch.weather.model import WeatherResponse

from ..common.utils.tag import TagType, TagUtil
from ..common.utils.template import build_templates
from .filters import cloudness_icon, wind_direction_icon


async def get_weather_api(request: AppRequest, provider: str | None = None) -> WeatherApi:
    return request.app.state.api.get_weather(provider)


WeatherApiDepends = Annotated[WeatherApi, Depends(get_weather_api)]


def context_procesor(request: AppRequest) -> dict:
    return {
        "providers": request.app.state.api.get_api_providers(WeatherApi.TYPE),
    }


templates = build_templates(
    Path(__file__).parent / "templates",
    {
        "wind_direction_icon": wind_direction_icon,
        "cloudness_icon": cloudness_icon,
    },
    context_procesor,
)


def build_weather_response(request: AppRequest, response: WeatherResponse):
    return templates.TemplateResponse(
        request=request,
        name="weather.html",
        context={
            "response": response,
        },
    )


router = APIRouter(prefix="/weather")


@router.get("/", response_class=RedirectResponse)
async def get_weather(request: AppRequest):
    default_provider = request.app.state.api.get_api_providers(WeatherApi.TYPE)[0]
    return RedirectResponse(default_provider)


@router.get("/{provider}", response_class=HTMLResponse)
async def get_weather_index(request: AppRequest, weather_api: WeatherApiDepends, query: str | None = None):
    locations = (await weather_api.find_locations(query)) if query else []
    return templates.TemplateResponse(
        request=request,
        name="index.html",
        context={
            "locations": locations,
        },
    )


@router.get("/{provider}/{location}", response_class=RedirectResponse)
async def get_weather_default(location: str):
    return RedirectResponse(f"{location}/tag/today")


@router.get("/{provider}/{location}/day/{date}", response_class=HTMLResponse)
async def get_weather_day(
    request: AppRequest,
    weather_api: WeatherApiDepends,
    location: str,
    date: datetime.date,
):
    response = await weather_api.get_day(location, date)
    return build_weather_response(request, response)


@router.get("/{provider}/{location}/days/{days}", response_class=HTMLResponse)
async def get_weather_days(request: AppRequest, weather_api: WeatherApiDepends, location: str, days: int):
    response = await weather_api.get_days(location, days)
    return build_weather_response(request, response)


@router.get("/{provider}/{location}/tag/{tag}", response_class=HTMLResponse)
async def get_weather_tag(request: AppRequest, weather_api: WeatherApiDepends, location: str, tag: str):
    tag_value = TagUtil.parse_tag(tag)
    if tag_value.type == TagType.DAY:
        response = await weather_api.get_day(location, tag_value.date)
    elif tag_value.type == TagType.DAYS:
        response = await weather_api.get_days(location, tag_value.days)
    else:
        raise ValueError(tag)
    return build_weather_response(request, response)
