from datetime import datetime, timedelta

import pytz
from aiogram import Bot, Router, types
from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy.ext.asyncio import AsyncSession

from config import (
    NOTIFY_EXTRA_DAYS,
    NOTIFY_INACTIVE,
    NOTIFY_INACTIVE_TRAFFIC,
    SUPPORT_CHAT_URL,
    TRIAL_CONFIG,
)
from database import (
    add_notification,
    check_notifications_bulk,
    mark_trial_extended,
    update_key_notified,
)
from handlers.buttons import MAIN_MENU
from handlers.keys.key_utils import get_user_traffic
from handlers.texts import (
    TRIAL_INACTIVE_BONUS_MSG,
    TRIAL_INACTIVE_FIRST_MSG,
    ZERO_TRAFFIC_MSG,
)
from handlers.utils import format_days
from logger import logger

from .notify_utils import send_messages_with_limit

router = Router()
moscow_tz = pytz.timezone("Europe/Moscow")


async def notify_inactive_trial_users(bot: Bot, session: AsyncSession):
    logger.info("Проверка пользователей, не активировавших пробный период...")
    users = await check_notifications_bulk(session, "inactive_trial", NOTIFY_INACTIVE)
    logger.info(f"Найдено {len(users)} неактивных пользователей для уведомления.")
    messages = []

    trial_days = TRIAL_CONFIG["duration_days"]

    for user in users:
        tg_id = user["tg_id"]
        username = user["username"]
        first_name = user["first_name"]
        last_name = user["last_name"]
        display_name = username or first_name or last_name or "Пользователь"

        builder = InlineKeyboardBuilder()
        builder.row(
            types.InlineKeyboardButton(
                text="🚀 Активировать пробный период", callback_data="create_key"
            )
        )
        builder.row(types.InlineKeyboardButton(text=MAIN_MENU, callback_data="profile"))
        keyboard = builder.as_markup()

        trial_extended = user["last_notification_time"] is not None

        if trial_extended:
            total_days = NOTIFY_EXTRA_DAYS + trial_days
            message = TRIAL_INACTIVE_BONUS_MSG.format(
                display_name=display_name,
                extra_days_formatted=format_days(NOTIFY_EXTRA_DAYS),
                total_days_formatted=format_days(total_days),
            )
            await mark_trial_extended(tg_id, session)
        else:
            message = TRIAL_INACTIVE_FIRST_MSG.format(
                display_name=display_name,
                trial_time_formatted=format_days(trial_days),
            )

        messages.append(
            {
                "tg_id": tg_id,
                "text": message,
                "keyboard": keyboard,
                "notification_id": "inactive_trial",
            }
        )

    if messages:
        results = await send_messages_with_limit(
            bot,
            messages,
            session=session,
            source_file="special_notifications",
            messages_per_second=25,
        )
        sent_count = 0
        for msg, result in zip(messages, results, strict=False):
            if result:
                await add_notification(session, msg["tg_id"], msg["notification_id"])
                sent_count += 1
        logger.info(f"Отправлено {sent_count} уведомлений неактивным пользователям.")
    logger.info("✅ Проверка пользователей с неактивным пробным периодом завершена.")


async def notify_users_no_traffic(
    bot: Bot, session: AsyncSession, current_time: int, keys: list
):
    logger.info("Проверка пользователей с нулевым трафиком...")
    current_dt = datetime.fromtimestamp(current_time / 1000, tz=moscow_tz)
    messages = []

    for key in keys:
        tg_id = key.tg_id
        email = key.email
        created_at = key.created_at
        client_id = key.client_id
        expiry_time = key.expiry_time
        notified = key.notified

        if created_at is None or notified:
            continue

        created_at_dt = pytz.utc.localize(
            datetime.fromtimestamp(created_at / 1000)
        ).astimezone(moscow_tz)
        if current_dt < created_at_dt + timedelta(hours=NOTIFY_INACTIVE_TRAFFIC):
            continue

        if expiry_time:
            expiry_dt = pytz.utc.localize(
                datetime.fromtimestamp(expiry_time / 1000)
            ).astimezone(moscow_tz)
            if (current_dt - (expiry_dt - timedelta(days=30))) < timedelta(
                hours=NOTIFY_INACTIVE_TRAFFIC
            ):
                continue

        try:
            traffic_data = await get_user_traffic(session, tg_id, email)
        except Exception as e:
            logger.error(f"Ошибка получения трафика для {email}: {e}")
            continue

        if traffic_data.get("status") != "success":
            logger.warning(
                f"⚠ Ошибка при получении трафика для {email}: {traffic_data.get('message')}"
            )
            continue

        total_traffic = sum(
            value if isinstance(value, int | float) else 0
            for value in traffic_data.get("traffic", {}).values()
        )

        try:
            await update_key_notified(session, tg_id, client_id)
        except Exception as e:
            logger.error(f"Ошибка обновления notified для {tg_id} ({client_id}): {e}")
            continue

        if total_traffic == 0:
            logger.info(
                f"⚠ У пользователя {tg_id} ({email}) 0 ГБ трафика. Отправляем уведомление."
            )
            builder = InlineKeyboardBuilder()
            builder.row(
                types.InlineKeyboardButton(
                    text="🔧 Написать в поддержку", url=SUPPORT_CHAT_URL
                )
            )
            builder.row(
                types.InlineKeyboardButton(text=MAIN_MENU, callback_data="profile")
            )
            keyboard = builder.as_markup()
            message = ZERO_TRAFFIC_MSG.format(email=email)
            messages.append(
                {
                    "tg_id": tg_id,
                    "text": message,
                    "keyboard": keyboard,
                    "client_id": client_id,
                }
            )

    if messages:
        results = await send_messages_with_limit(
            bot,
            messages,
            session=session,
            source_file="special_notifications",
            messages_per_second=25,
        )
        sent_count = sum(result for result in results if result)
        logger.info(f"Отправлено {sent_count} уведомлений о нулевом трафике.")

    logger.info("✅ Обработка пользователей с нулевым трафиком завершена.")
