import logging
from logging.handlers import RotatingFileHandler
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.utils.keyboard import ReplyKeyboardBuilder
import requests
import asyncio

# настройка логов
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)  # Включаем детальное логирование

formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# логирование в файл, максимум 5мб по 3 бэкапа
file_handler = RotatingFileHandler(
    'weather_bot.log',
    maxBytes=5*1024*1024,
    backupCount=3,
    encoding='utf-8'
)
file_handler.setFormatter(formatter)

# вывод в консоль
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)

logger.addHandler(file_handler)
logger.addHandler(console_handler)

# конфиг
try:
    from config import BOT_TOKEN, WEATHER_API_KEY
except ImportError:
    logging.critical("Ошибка: Создайте файл config.py с BOT_TOKEN и WEATHER_API_KEY!")
    exit(1)

# инициализация бота
bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()

# клавиатура
builder = ReplyKeyboardBuilder()
builder.button(text="Узнать погоду")
builder.button(text="Помощь")
keyboard = builder.as_markup(resize_keyboard=True)

# обработка команд
@dp.message(Command("start", "help"))
async def cmd_start(message: types.Message):
    logging.info(f"Новый пользователь: {message.from_user.id}")
    await message.answer(
        "Бот Погоды\n\n"
        "Отправьте мне название города, и я пришлю текущую погоду.\n"
        "Или нажмите кнопку ниже:",
        reply_markup=keyboard
    )

@dp.message(lambda message: message.text in ["Узнать погоду", "ℹ️ Помощь"])
async def button_handler(message: types.Message):
    if message.text == "Узнать погоду":
        await message.answer("Введите название города:")
    else:
        await cmd_start(message)

@dp.message()
async def get_weather(message: types.Message):
    city = message.text.strip()
    if not city:
        return
    
    logging.info(f"Запрос погоды для: {city} (от {message.from_user.id})")
    
    try:
        # Запрос к API
        url = f"https://api.openweathermap.org/data/2.5/weather?q={city}&appid={WEATHER_API_KEY}&units=metric&lang=ru"
        response = requests.get(url, timeout=10)
        
        logging.debug(f"API Response: {response.status_code} {response.text[:200]}...")
        
        if response.status_code != 200:
            error_msg = response.json().get('message', 'Unknown error')
            logging.error(f"API Error for {city}: {response.status_code} - {error_msg}")
            await message.answer(f"❌ Ошибка: {error_msg.capitalize()}")
            return
            
        data = response.json()
        
        # Формирование ответа
        weather_report = (
            f"Город: {data['name']}\n"
            f"Температура: {data['main']['temp']:.1f}°C\n"
            f"Ощущается как: {data['main']['feels_like']:.1f}°C\n"
            f"Ветер: {data['wind']['speed']} м/с\n"
            f"Погода: {data['weather'][0]['description'].capitalize()}\n"
            f"Влажность: {data['main']['humidity']}%"
        )
        
        logging.info(f"Успешный ответ для {city}")
        await message.answer(weather_report)
        
    except requests.exceptions.Timeout:
        logging.error(f"Таймаут запроса для {city}")
        await message.answer("Сервер погоды не отвечает. Попробуйте позже.")
    except Exception as e:
        logging.exception(f"Ошибка для {city}:")
        await message.answer("⚠️ Произошла внутренняя ошибка. Попробуйте другой город.")

# запуск бота
async def main():
    logging.info("Starting bot...")
    await dp.start_polling(bot)

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        logging.info("Bot stopped by user")
    except Exception as e:
        logging.critical(f"Fatal error: {e}")