from datetime import datetime, timedelta, timezone
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import ContextTypes
from asgiref.sync import sync_to_async
from hotels.models import Reservation, Hotel
from users.models import User

from bot.utils.pdf_report import generate_pdf_report
from bot.utils.database import get_hotels_for_user, get_hotel_by_name
from django.utils.timezone import make_aware

async def statistics(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Вывод списка отелей для статистики."""
    query = update.callback_query
    user_id = query.from_user.id
    await query.answer()

    # Получаем пользователя
    user = await sync_to_async(User.objects.filter(chat_id=user_id).first)()
    if not user:
        await query.edit_message_text("Вы не зарегистрированы в системе.")
        return

    # Получаем отели, связанные с пользователем
    user_hotels = await get_hotels_for_user(user)
    if not user_hotels:
        await query.edit_message_text("У вас нет доступных отелей для статистики.")
        return

    # Формируем кнопки для выбора отеля
    keyboard = [
        [InlineKeyboardButton(hotel.hotel.name, callback_data=f"stats_hotel_{hotel.hotel.id}")]
        for hotel in user_hotels
    ]
    keyboard.append([InlineKeyboardButton("🏠 Главная", callback_data="main_menu")])
    reply_markup = InlineKeyboardMarkup(keyboard)
    await query.edit_message_text("Выберите отель:", reply_markup=reply_markup)

async def stats_select_period(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Выбор периода времени для статистики."""
    query = update.callback_query
    await query.answer()

    hotel_id = int(query.data.split("_")[2])
    context.user_data["selected_hotel"] = hotel_id

    keyboard = [
        [InlineKeyboardButton("День", callback_data="stats_period_day")],
        [InlineKeyboardButton("Неделя", callback_data="stats_period_week")],
        [InlineKeyboardButton("Месяц", callback_data="stats_period_month")],
        [InlineKeyboardButton("Все время", callback_data="stats_period_all")],
        [InlineKeyboardButton("🏠 Главная", callback_data="main_menu")],
        [InlineKeyboardButton("🔙 Назад", callback_data="statistics")],
    ]
    reply_markup = InlineKeyboardMarkup(keyboard)
    await query.edit_message_text("Выберите период времени:", reply_markup=reply_markup)


async def generate_statistics(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """Генерация и отправка статистики."""
    query = update.callback_query
    await query.answer()

    hotel_id = context.user_data.get("selected_hotel")
    if not hotel_id:
        await query.edit_message_text("Ошибка: ID отеля не найден.")
        return

    period = query.data.split("_")[2]
    print(f'Period raw: {query.data}')
    print(f'Selected period: {period}')

    now = datetime.utcnow().replace(tzinfo=timezone.utc)  # Используем timezone.utc

    if period == "day":
        start_date = (now - timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = now.replace(hour=23, minute=59, second=59, microsecond=999999)
    elif period == "week":
        start_date = (now - timedelta(days=7)).replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = now.replace(hour=23, minute=59, second=59, microsecond=999999)
    elif period == "month":
        start_date = (now - timedelta(days=30)).replace(hour=0, minute=0, second=0, microsecond=0)
        end_date = now.replace(hour=23, minute=59, second=59, microsecond=999999)
    else:  # "all"
        start_date = None
        end_date = None

    print(f'Raw start_date: {start_date}, Raw end_date: {end_date}')

    # Убедитесь, что даты имеют временную зону UTC
    if start_date:
        start_date = make_aware(start_date) if start_date.tzinfo is None else start_date
    if end_date:
        end_date = make_aware(end_date) if end_date.tzinfo is None else end_date

    print(f'Filtered start_date: {start_date}, Filtered end_date: {end_date}')

    # Фильтрация по "дата заезда"
    if start_date and end_date:
        reservations = await sync_to_async(list)(
            Reservation.objects.filter(
                hotel_id=hotel_id,
                check_in__gte=start_date,
                check_in__lte=end_date
            ).select_related('hotel')
        )
    else:  # Без фильтра по дате
        reservations = await sync_to_async(list)(
            Reservation.objects.filter(
                hotel_id=hotel_id
            ).select_related('hotel')
        )

    print(f'Filtered reservations count: {len(reservations)}')

    if not reservations:
        await query.edit_message_text("Нет данных для статистики за выбранный период.")
        return

    hotel = await sync_to_async(Hotel.objects.get)(id=hotel_id)
    print(f'Hotel: {hotel.name}')

    for reservation in reservations:
        print(f"Reservation ID: {reservation.reservation_id}, Hotel: {reservation.hotel.name}, "
              f"Room number: {reservation.room_number}, Check-in: {reservation.check_in}, Check-out: {reservation.check_out}")

    # Генерация PDF отчета (пример)
    file_path = generate_pdf_report(hotel.name, reservations, start_date, end_date)
    print(f'Generated file path: {file_path}')

    with open(file_path, "rb") as file:
        await query.message.reply_document(document=file, filename=f"{hotel.name}_report.pdf")

async def stats_back(update: Update, context):
    """Возврат к выбору отеля."""
    query = update.callback_query
    await query.answer()

    # Получаем отели, связанные с пользователем
    user_id = query.from_user.id
    user = await sync_to_async(User.objects.filter(chat_id=user_id).first)()
    if not user:
        await query.edit_message_text("Ошибка: Пользователь не найден.")
        return

    hotels = await get_hotels_for_user(user)
    if not hotels:
        await query.edit_message_text("У вас нет доступных отелей.")
        return

    # Формируем кнопки для выбора отеля
    keyboard = [
        [InlineKeyboardButton(hotel.name, callback_data=f"stats_hotel_{hotel.id}")]
        for hotel in hotels
    ]
    keyboard.append([InlineKeyboardButton("🏠 Главная", callback_data="main_menu")])
    reply_markup = InlineKeyboardMarkup(keyboard)
    await query.edit_message_text("Выберите отель:", reply_markup=reply_markup)
