from datetime import datetime, timedelta
from types import SimpleNamespace

from app.bot.ui.panel import (
    PANEL_SECTION_ADMIN,
    PANEL_SECTION_HOME,
    PANEL_SECTION_REFERRAL,
    PANEL_SECTION_SUBSCRIPTION,
    PANEL_SECTION_SUPPORT,
    PANEL_SECTION_TERMS,
    PanelContext,
    build_panel_keyboard,
    render_panel_caption,
)
from app.services.sync_service import CachedUserView


def _button_texts(markup) -> list[str]:
    return [button.text for row in markup.inline_keyboard for button in row]


def _cached_user_view(*, telegram_id: int = 123456789) -> CachedUserView:
    return CachedUserView(
        record=SimpleNamespace(
            username="oreol-renew",
            status="ACTIVE",
            expire_at=datetime.now() + timedelta(days=10),
            used_traffic_bytes=0,
            traffic_limit_bytes=0,
            short_uuid="renew999",
            subscription_url="https://example.com/sub/renew999",
            telegram_id=telegram_id,
        ),
        internal_squads=["VPN"],
    )


def test_home_panel_caption_without_subscription() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_HOME,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "Добро пожаловать в <b>OREOL VPN</b>" in caption
    assert "<b>Профиль</b>" not in caption
    assert "<b>Подписка</b>" in caption
    assert "Статус: <b>Не активна</b>" in caption
    assert "Срок: <b>—</b>" in caption
    assert "Трафик: <b>—</b>" in caption


def test_home_panel_keyboard_has_expected_buttons() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
    button_texts = _button_texts(markup)

    assert "Профиль" not in button_texts
    assert "💳 Подписка" in button_texts
    assert "🆘 Поддержка" in button_texts
    assert "👥 Реферальная система" in button_texts
    assert "📜 Условия использования" in button_texts
    assert len(markup.inline_keyboard[0]) == 1
    assert markup.inline_keyboard[0][0].text == "💳 Подписка"
    assert markup.inline_keyboard[0][0].callback_data == "payment:menu"


def test_admin_home_panel_keyboard_has_admin_button() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=True,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
    button_texts = _button_texts(markup)

    assert "🛠 Админ-панель" in button_texts
    assert len(markup.inline_keyboard[1]) == 1
    assert markup.inline_keyboard[1][0].text == "🛠 Админ-панель"
    assert markup.inline_keyboard[1][0].callback_data == "panel:admin"


def test_admin_panel_caption_contains_dashboard_stats() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=True,
        users=[],
        admin_total_telegram_users=120,
        admin_total_cached_users=80,
        admin_active_cached_users=67,
        admin_pending_orders=9,
        admin_review_orders=4,
        admin_open_tickets=3,
        admin_pending_referral_bonuses=2,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_ADMIN,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "<b>🛠 Админ-панель OREOL VPN</b>" in caption
    assert "Пользователей в боте: <b>120</b>" in caption
    assert "Чеков на проверке: <b>4</b>" in caption
    assert "Открытых тикетов: <b>3</b>" in caption
    assert "Бонусов в ожидании: <b>2</b>" in caption


def test_admin_panel_keyboard_has_expected_buttons() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=True,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(
        section=PANEL_SECTION_ADMIN,
        context=context,
        payment_review_url="https://t.me/c/123/56/57",
        support_ticket_url="https://t.me/c/123/2/3",
    )
    button_texts = _button_texts(markup)

    assert "🔍 Найти пользователя" in button_texts
    assert "👤 Пользователи" in button_texts
    assert "🔄 Полная синхронизация" in button_texts
    assert "💸 Очередь оплат" in button_texts
    assert "🗂 История тикетов" in button_texts
    assert "🎫 Чат тикетов" in button_texts
    assert "↻ Обновить" in button_texts
    assert "🏠 Главное меню" in button_texts


def test_subscription_caption_without_subscription_but_with_payment() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        payment_enabled=True,
        payment_plan_title="OREOL VPN на 30 дней",
        payment_plan_description="Доступ к VPN на 30 дней",
        payment_plan_price_stars=250,
        payment_plan_duration_days=30,
        payment_plan_traffic_limit_bytes=0,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_SUBSCRIPTION,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "У вас пока нет активного доступа." in caption
    assert "OREOL VPN на 30 дней" in caption
    assert "Цена: <b>250 ₽</b>" in caption
    assert "После выбора тарифа бот покажет реквизиты" in caption


def test_subscription_caption_without_payment_uses_ui_instructions() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        payment_enabled=False,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_SUBSCRIPTION,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "откройте поддержку" in caption
    assert "short UUID" in caption
    assert "/link" not in caption


def test_subscription_keyboard_has_buy_button() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        payment_enabled=True,
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_SUBSCRIPTION, context=context)
    button_texts = _button_texts(markup)

    assert "💳 Купить подписку" in button_texts
    assert "🏠 Главное меню" in button_texts


def test_subscription_keyboard_has_renew_button_when_access_exists() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[_cached_user_view()],
        payment_enabled=True,
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_SUBSCRIPTION, context=context)
    button_texts = _button_texts(markup)

    assert "💳 Продлить подписку" in button_texts
    assert "💳 Купить подписку" not in button_texts


def test_subscription_caption_with_existing_access_mentions_renewal() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[_cached_user_view()],
        payment_enabled=True,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_SUBSCRIPTION,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "Продлить подписку" in caption
    assert "автоматически добавит выбранный срок" in caption


def test_terms_panel_caption() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_TERMS,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "<b>📜 Правила VPN</b>" in caption
    assert "использовать VPN только в законных целях" in caption
    assert "не гарантирует полной анонимности" in caption


def test_support_panel_has_create_ticket_button() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_SUPPORT, context=context)
    button_texts = _button_texts(markup)

    assert "🎫 Создать тикет" in button_texts
    assert "🏠 Главное меню" in button_texts


def test_support_panel_has_support_url_button() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(
        section=PANEL_SECTION_SUPPORT,
        context=context,
        support_url="https://t.me/support_account",
    )
    button_texts = _button_texts(markup)

    assert "Написать в поддержку" in button_texts


def test_support_panel_caption() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_SUPPORT,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "<b>🆘 Помощь и сопровождение</b>" in caption
    assert "откройте тикет через кнопку ниже" in caption


def test_referral_panel_caption_with_link() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        referral_code="ABCD1234",
        referral_count=3,
        referral_link="https://t.me/oreol_vpn_bot?start=ref_ABCD1234",
        referral_share_url="https://t.me/share/url?url=test",
        referral_recent_names=["Alex", "Maria"],
        referral_discount_percent=12,
        referral_bonus_days=7,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_REFERRAL,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "<b>👥 Реферальная система</b>" in caption
    assert "Ваш реферальный код: <code>ABCD1234</code>" in caption
    assert "Приглашено пользователей: <b>3</b>" in caption
    assert "+7 дней" in caption
    assert "Чтобы получить скидку 12%" in caption
    assert "https://t.me/oreol_vpn_bot?start=ref_ABCD1234" in caption
    assert "Alex" in caption
    assert "Maria" in caption


def test_referral_caption_uses_runtime_discount_for_applied_code() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        referral_code="ABCD1234",
        referral_count=1,
        applied_referral_code="PROMO777",
        referral_discount_percent=17,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_REFERRAL,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "Код: <code>PROMO777</code>" in caption
    assert "Скидка перед оплатой: <b>17%</b>" in caption


def test_admin_panel_keyboard_has_settings_button() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=True,
        users=[],
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_ADMIN, context=context)
    button_texts = _button_texts(markup)

    assert any("Настрой" in text for text in button_texts)


def test_home_panel_hides_referral_when_disabled() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        referral_enabled=False,
        api_error=None,
    )

    markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
    button_texts = _button_texts(markup)

    assert all("Реферал" not in text for text in button_texts)


def test_referral_panel_caption_when_disabled() -> None:
    context = PanelContext(
        telegram_id=123456789,
        display_name="Evgeniy Spirin",
        username="evgeniy",
        language_code="ru",
        is_admin=False,
        users=[],
        referral_enabled=False,
        api_error=None,
    )

    caption = render_panel_caption(
        section=PANEL_SECTION_REFERRAL,
        context=context,
        brand_name="OREOL VPN",
    )

    assert "отключена" in caption
