import datetime
from pathlib import Path

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

from gallery.easel.core import AppRequest
from gallery.easel.depends.api import api_resolver
from gallery.easel.depends.weather import WeatherApiDepends
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, weather_icon_svg, wind_direction_icon


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


templates = build_templates(
    Path(__file__).parent / "templates",
    {
        "wind_direction_icon": wind_direction_icon,
        "cloudness_icon": cloudness_icon,
        "weather_icon_svg": weather_icon_svg,
    },
    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=HTMLResponse)
async def get_weather_index(request: AppRequest, provider: str | None = None, query: str | None = None):
    if query and provider:
        weather_api = api_resolver(WeatherApi)(request, provider)
        locations = await weather_api.find_locations(query)
    else:
        locations = []
    return templates.TemplateResponse(
        request=request,
        name="index.html",
        context={
            "locations": locations,
        },
    )


@router.get("/{provider}/{location}", response_class=RedirectResponse)
async def get_weather(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)


@router.get("/zmiyevka-184640/tag/{tag}", response_class=RedirectResponse)
async def get_zmiyevka_weather_compat(request: AppRequest):
    path_parts = request.url.path.split("/")
    path_parts.insert(2, "gismeteo")
    return RedirectResponse("/".join(path_parts))
