"""Weather — real weather data from OpenWeatherMap API."""
from __future__ import annotations

import logging
from datetime import datetime

import aiohttp

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import ContextTypes

from bot import db
from bot.config import OPENWEATHER_API_KEY
from bot.persian_router import register_mixed

logger = logging.getLogger(__name__)

# Persian weather descriptions
WEATHER_FA = {
    "clear sky": "آسمان صاف",
    "few clouds": "کمی ابری",
    "scattered clouds": "ابرهای پراکنده",
    "broken clouds": "ابرهای شکسته",
    "overcast clouds": "ابری",
    "light rain": "باران سبک",
    "moderate rain": "باران متوسط",
    "heavy rain": "باران شدید",
    "thunderstorm": "طوفان",
    "snow": "برف",
    "light snow": "برف سبک",
    "mist": "مه",
    "fog": "مه غلیظ",
    "haze": "مه رقیق",
    "drizzle": "نم‌نم باران",
}

# Weather emojis
WEATHER_EMOJI = {
    "clear": "☀️",
    "clouds": "☁️",
    "rain": "🌧️",
    "drizzle": "🌦️",
    "thunderstorm": "⛈️",
    "snow": "❄️",
    "mist": "🌫️",
    "fog": "🌫️",
    "haze": "🌫️",
}


def _get_weather_emoji(description: str) -> str:
    for key, emoji in WEATHER_EMOJI.items():
        if key in description.lower():
            return emoji
    return "🌤️"


def _translate_weather(description: str) -> str:
    return WEATHER_FA.get(description.lower(), description)


async def weather_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Get weather: /weather [city]"""
    if not OPENWEATHER_API_KEY:
        await update.message.reply_text(
            "⚠️ کلید API آب و هوا تنظیم نشده.\n"
            "در فایل .env اضافه کنید:\n"
            "<code>OPENWEATHER_API_KEY=your_key</code>",
            parse_mode=ParseMode.HTML,
        )
        return

    args = (update.message.text or "").split(maxsplit=1)
    city = args[1] if len(args) > 1 else "Tehran"

    try:
        async with aiohttp.ClientSession() as session:
            url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={OPENWEATHER_API_KEY}&units=metric&lang=fa"
            async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
                if resp.status != 200:
                    await update.message.reply_text(f"❌ شهر «{city}» پیدا نشد.")
                    return
                data = await resp.json()

        temp = data["main"]["temp"]
        feels_like = data["main"]["feels_like"]
        humidity = data["main"]["humidity"]
        wind = data["wind"]["speed"]
        description = data["weather"][0]["description"]
        city_name = data["name"]
        country = data["sys"]["country"]

        emoji = _get_weather_emoji(description)
        desc_fa = _translate_weather(description)

        text = (
            f"{emoji} <b>آب و هوای {city_name}, {country}</b>\n\n"
            f"🌡 دما: <b>{temp}°C</b>\n"
            f"🤗 حس واقعی: {feels_like}°C\n"
            f"💧 رطوبت: {humidity}%\n"
            f"💨 باد: {wind} m/s\n"
            f"☁️ وضعیت: {desc_fa}"
        )
        await update.message.reply_text(text, parse_mode=ParseMode.HTML)

    except aiohttp.ClientError:
        await update.message.reply_text("❌ خطا در اتصال به سرور آب و هوا.")
    except Exception as e:
        logger.warning(f"Weather error: {e}")
        await update.message.reply_text("❌ خطای غیرمنتظره.")


async def weather_forecast_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """5-day weather forecast: /forecast [city]"""
    if not OPENWEATHER_API_KEY:
        await update.message.reply_text("⚠️ کلید API آب و هوا تنظیم نشده.")
        return

    args = (update.message.text or "").split(maxsplit=1)
    city = args[1] if len(args) > 1 else "Tehran"

    try:
        async with aiohttp.ClientSession() as session:
            url = f"https://api.openweathermap.org/data/2.5/forecast?q={city}&appid={OPENWEATHER_API_KEY}&units=metric&lang=fa&cnt=10"
            async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
                if resp.status != 200:
                    await update.message.reply_text(f"❌ شهر «{city}» پیدا نشد.")
                    return
                data = await resp.json()

        city_name = data["city"]["name"]
        text = f"📅 <b>پیش‌بینی {city_name}:</b>\n\n"

        for item in data["list"][:5]:
            dt = datetime.fromtimestamp(item["dt"])
            temp = item["main"]["temp"]
            desc = item["weather"][0]["description"]
            emoji = _get_weather_emoji(desc)
            desc_fa = _translate_weather(desc)
            text += f"🕐 {dt.strftime('%H:%M')} │ {emoji} {desc_fa} │ 🌡 {temp}°C\n"

        await update.message.reply_text(text, parse_mode=ParseMode.HTML)

    except Exception as e:
        logger.warning(f"Forecast error: {e}")
        await update.message.reply_text("❌ خطای غیرمنتظره.")


def register(app) -> None:
    register_mixed(
        app,
        {
            "weather": weather_cmd,
            "forecast": weather_forecast_cmd,
        },
        {
            "آب و هوا": weather_cmd,
            "هوای": weather_cmd,
            "هوا": weather_cmd,
            "پیش‌بینی هوا": weather_forecast_cmd,
            "آینده آب و هوا": weather_forecast_cmd,
        },
    )
