from typing import Any

from aiogram import F, Router
from aiogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.utils.keyboard import InlineKeyboardBuilder
from sqlalchemy.ext.asyncio import AsyncSession
from handlers.buttons import BACK

from core.settings.tariffs_config import TARIFFS_CONFIG, update_tariffs_config
from filters.admin import IsAdminFilter

from ..panel.keyboard import AdminPanelCallback


router = Router()
router.callback_query.filter(IsAdminFilter())

PACK_MODES = ["", "traffic", "devices", "all"]


def format_pack_mode_label(mode: str | None) -> str:
    """Возвращает человекочитаемое название режима пакетов."""
    if not mode:
        return "выкл"
    if mode == "traffic":
        return "только трафик"
    if mode == "devices":
        return "только устройства"
    if mode == "all":
        return "трафик и устройства"
    return f"неизвестно ({mode})"


def build_tariffs_settings_kb() -> InlineKeyboardMarkup:
    """Клавиатура основного экрана настроек тарификации."""
    allow_downgrade = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True))
    pack_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or ""
    recalc_enabled = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False))

    builder = InlineKeyboardBuilder()

    builder.row(
        InlineKeyboardButton(
            text=f"Понижение: {'вкл' if allow_downgrade else 'выкл'}",
            callback_data=AdminPanelCallback(action="settings_tariffs_toggle_downgrade").pack(),
        )
    )

    builder.row(
        InlineKeyboardButton(
            text=f"Режим пакетов: {format_pack_mode_label(pack_mode)}",
            callback_data=AdminPanelCallback(action="settings_tariffs_packs").pack(),
        )
    )

    builder.row(
        InlineKeyboardButton(
            text=f"Перерасчёт при докупке: {'да' if recalc_enabled else 'нет'}",
            callback_data=AdminPanelCallback(action="settings_tariffs_toggle_addons_recalc").pack(),
        )
    )

    builder.row(
        InlineKeyboardButton(
            text=BACK,
            callback_data=AdminPanelCallback(action="settings").pack(),
        )
    )

    return builder.as_markup()


def build_tariffs_settings_text() -> str:
    """Текст основного экрана настроек тарификации."""
    allow_downgrade = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True))
    pack_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or ""
    recalc_enabled = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False))

    lines: list[str] = [
        "⚙️ Настройки тарификации",
        "",
        f"• Понижение условий при изменении: {'включено' if allow_downgrade else 'выключено'}",
        f"• Режим доплат: {format_pack_mode_label(pack_mode)}",
        f"• Перерасчёт при докупке: {'да' if recalc_enabled else 'нет'}",
        "",
        "ℹ️ Как работают режимы доплат:",
        "",
        "🔹 <b>Пакеты</b>",
        "<blockquote>Позволяет докупать трафик и устройства к активной подписке неограниченное количество раз.",
        "При продлении подписки все параметры возвращаются к исходно сконфигурированному тарифу.",
        "</blockquote>\n\n🔹 <b>Базовый конфигуратор (выкл. режим пакетов)</b>",
        "<blockquote>Позволяет выбрать параметры тарифа из доступных опций.",
        "Выбранные условия сохраняются и будут использоваться при последующих продлениях.",
        "При включённом понижении клиент сможет понижать условия тарифа.</blockquote>",
    ]
    return "\n".join(lines)


async def refresh_tariffs_settings_screen(callback: CallbackQuery) -> None:
    """Обновляет основной экран настроек тарификации."""
    await callback.message.edit_text(
        build_tariffs_settings_text(),
        reply_markup=build_tariffs_settings_kb(),
    )
    await callback.answer()


def build_tariffs_packs_kb() -> InlineKeyboardMarkup:
    """Клавиатура экрана выбора режима пакетов."""
    current = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or ""

    builder = InlineKeyboardBuilder()

    builder.row(
        InlineKeyboardButton(
            text=f"{'✅ ' if current == '' else ''}Выкл",
            callback_data=AdminPanelCallback(action="settings_tariffs_mode_off").pack(),
        )
    )
    builder.row(
        InlineKeyboardButton(
            text=f"{'✅ ' if current == 'traffic' else ''}Только трафик",
            callback_data=AdminPanelCallback(action="settings_tariffs_mode_traffic").pack(),
        )
    )
    builder.row(
        InlineKeyboardButton(
            text=f"{'✅ ' if current == 'devices' else ''}Только устройства",
            callback_data=AdminPanelCallback(action="settings_tariffs_mode_devices").pack(),
        )
    )
    builder.row(
        InlineKeyboardButton(
            text=f"{'✅ ' if current == 'all' else ''}Трафик и устройства",
            callback_data=AdminPanelCallback(action="settings_tariffs_mode_all").pack(),
        )
    )

    builder.row(
        InlineKeyboardButton(
            text=BACK,
            callback_data=AdminPanelCallback(action="settings_tariffs").pack(),
        )
    )

    return builder.as_markup()


def build_tariffs_packs_text() -> str:
    """Текст экрана выбора режима пакетов."""
    current = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or ""

    lines: list[str] = [
        "📦 Режим доплат пакетами",
        "",
        "При активной подписке можно продавать не новый тариф, а доплаты к текущим лимитам.",
        "",
        "Режимы:",
        "<blockquote>",
        "• Выкл — доплаты пакетами отключены, работает обычный конфигуратор лимитов (клиент меняет конфигурацию тарифа для продления).",
        "• Только трафик — пользователь докупает ГБ до продления, количество устройств не меняется.",
        "• Только устройства — пользователь докупает устройства до продления, лимит трафика не меняется.",
        "• Трафик и устройства — можно одновременно докупать и трафик, и устройства до продления как единый пакет.",
        f"</blockquote>\nТекущий режим: {format_pack_mode_label(current)}",
        "",
        "Выберите режим, который покажет варианты для доплаты.\n ❗Доплаты не переносятся при продлении.",
    ]
    return "\n".join(lines)


async def refresh_tariffs_packs_screen(callback: CallbackQuery) -> None:
    """Обновляет экран выбора режима пакетов."""
    await callback.message.edit_text(
        build_tariffs_packs_text(),
        reply_markup=build_tariffs_packs_kb(),
    )
    await callback.answer()


@router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs"))
async def open_tariffs_settings(callback: CallbackQuery, session: AsyncSession) -> None:
    """Открывает основной экран настроек тарификации."""
    await refresh_tariffs_settings_screen(callback)


@router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_toggle_downgrade"))
async def toggle_tariffs_downgrade(callback: CallbackQuery, session: AsyncSession) -> None:
    """Переключает флаг понижения условий."""
    current = bool(TARIFFS_CONFIG.get("ALLOW_DOWNGRADE", True))

    new_config: dict[str, Any] = dict(TARIFFS_CONFIG)
    new_config["ALLOW_DOWNGRADE"] = not current

    await update_tariffs_config(session, new_config)
    await refresh_tariffs_settings_screen(callback)


@router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_toggle_addons_recalc"))
async def toggle_tariffs_addons_recalc(callback: CallbackQuery, session: AsyncSession) -> None:
    """Переключает перерасчёт при докупке."""
    current = bool(TARIFFS_CONFIG.get("KEY_ADDONS_RECALC_PRICE", False))

    new_config: dict[str, Any] = dict(TARIFFS_CONFIG)
    new_config["KEY_ADDONS_RECALC_PRICE"] = not current

    await update_tariffs_config(session, new_config)
    await refresh_tariffs_settings_screen(callback)


@router.callback_query(AdminPanelCallback.filter(F.action == "settings_tariffs_packs"))
async def open_tariffs_packs(callback: CallbackQuery, session: AsyncSession) -> None:
    """Открывает экран выбора режима пакетов."""
    await refresh_tariffs_packs_screen(callback)


@router.callback_query(
    AdminPanelCallback.filter(
        F.action.in_([
            "settings_tariffs_mode_off",
            "settings_tariffs_mode_traffic",
            "settings_tariffs_mode_devices",
            "settings_tariffs_mode_all",
        ])
    )
)
async def set_tariffs_pack_mode(
    callback: CallbackQuery,
    callback_data: AdminPanelCallback,
    session: AsyncSession,
) -> None:
    """Сохраняет выбранный режим пакетов и обновляет экран."""
    action = callback_data.action

    if action == "settings_tariffs_mode_off":
        new_mode = ""
    elif action == "settings_tariffs_mode_traffic":
        new_mode = "traffic"
    elif action == "settings_tariffs_mode_devices":
        new_mode = "devices"
    elif action == "settings_tariffs_mode_all":
        new_mode = "all"
    else:
        new_mode = TARIFFS_CONFIG.get("KEY_ADDONS_PACK_MODE") or ""

    new_config: dict[str, Any] = dict(TARIFFS_CONFIG)
    new_config["KEY_ADDONS_PACK_MODE"] = new_mode

    await update_tariffs_config(session, new_config)
    await refresh_tariffs_packs_screen(callback)
