from __future__ import annotations

import html
import math
from datetime import datetime
from typing import Any


def format_bytes(value: int | float | None) -> str:
    if value is None or value <= 0:
        return "0 B"

    units = ["B", "KB", "MB", "GB", "TB", "PB"]
    size = float(value)
    unit_index = 0

    while size >= 1024 and unit_index < len(units) - 1:
        size /= 1024
        unit_index += 1

    if unit_index == 0:
        return f"{int(size)} {units[unit_index]}"
    return f"{size:.2f} {units[unit_index]}"


def format_datetime(value: datetime | None) -> str:
    if value is None:
        return "не указано"
    return value.strftime("%d.%m.%Y %H:%M")


def format_traffic_limit(limit_bytes: int | None) -> str:
    if limit_bytes is None or limit_bytes <= 0:
        return "без лимита"
    return format_bytes(limit_bytes)


def _format_days_word(value: int) -> str:
    remainder_100 = value % 100
    remainder_10 = value % 10
    if 11 <= remainder_100 <= 14:
        return "дней"
    if remainder_10 == 1:
        return "день"
    if 2 <= remainder_10 <= 4:
        return "дня"
    return "дней"


def format_datetime_with_days_left(value: datetime | None) -> str:
    if value is None:
        return "не указано"

    now = datetime.now(value.tzinfo) if value.tzinfo is not None else datetime.now()
    seconds_left = (value - now).total_seconds()
    if seconds_left <= 0:
        return f"{format_datetime(value)} (истёк)"

    days_left = max(1, math.ceil(seconds_left / 86400))
    return f"{format_datetime(value)} ({days_left} {_format_days_word(days_left)})"


def build_help_text(*, is_admin: bool) -> str:
    lines = [
        "<b>Команды</b>",
        "/start - открыть главное меню",
        "",
        "Дальше используйте кнопки внутри интерфейса бота.",
    ]
    return "\n".join(lines)


def format_payment_plan(
    *,
    title: str,
    description: str,
    price_stars: int,
    duration_days: int,
    traffic_limit_bytes: int,
) -> str:
    lines = [
        "<b>Тариф</b>",
        "",
        f"<b>{html.escape(title)}</b>",
        html.escape(description),
        "",
        f"Срок: <b>{duration_days} дн.</b>",
        f"Трафик: <b>{format_traffic_limit(traffic_limit_bytes)}</b>",
        f"Цена: <b>{price_stars} ₽</b>",
    ]
    return "\n".join(lines)


def format_issued_access(
    *,
    subscription_url: str,
    expire_at: datetime,
    traffic_limit_bytes: int,
    brand_name: str = "",
    success_text: str = "",
    is_renewal: bool = False,
) -> str:
    normalized_brand_name = html.escape(brand_name.strip()) if brand_name.strip() else "VPN"
    title = (
        f"<b>🔥 {normalized_brand_name} — подписка продлена</b>"
        if is_renewal
        else f"<b>🔥 {normalized_brand_name} — доступ готов</b>"
    )
    status_text = (
        "Подписка продлена. Откройте её кнопкой ниже "
        "или импортируйте ссылку вручную в ваш VPN-клиент."
        if is_renewal
        else "Подписка активирована. Откройте её кнопкой ниже "
        "или импортируйте ссылку вручную в ваш VPN-клиент."
    )
    lines = [
        title,
        "",
        f"<blockquote>{status_text}</blockquote>",
        "",
        "<b>🔗 Ключ / подписка</b>",
        html.escape(subscription_url),
        "",
        (
            "<blockquote>"
            f"⏳ Действует до: <b>{format_datetime_with_days_left(expire_at)}</b>\n"
            f"📶 Трафик: <b>{format_traffic_limit(traffic_limit_bytes)}</b>"
            "</blockquote>"
        ),
        "",
        "<b>📲 Что делать дальше</b>",
        "1. Нажмите кнопку «Открыть подписку» ниже или откройте ссылку выше.",
        "2. Импортируйте подписку или ключ в приложение VPN-клиента.",
        "3. Управлять доступом и продлевать его можно в панели бота.",
        "",
        (
            "<blockquote>"
            "💡 <b>О белых списках:</b> подписки с белыми списками предназначены "
            "для использования в условиях полной блокировки. Если полной блокировки нет — "
            "рекомендуем пользоваться VPN"
            "</blockquote>"
        ),
        "",
        "<i>Если ссылка не открывается автоматически, скопируйте её в клиент вручную.</i>",
    ]
    normalized_success_text = success_text.strip()
    if normalized_success_text:
        lines[7:7] = [
            "<b>Информация</b>",
            f"<blockquote>{html.escape(normalized_success_text)}</blockquote>",
            "",
        ]
    return "\n".join(lines)


def format_user_card(
    *,
    user: Any,
    squad_names: list[str],
    recent_requests: list[Any] | None = None,
) -> str:
    lines = [
        f"<b>{html.escape(user.username)}</b> <code>{html.escape(user.status)}</code>",
        f"UUID: <code>{html.escape(user.rw_uuid)}</code>",
        f"Short UUID: <code>{html.escape(user.short_uuid)}</code>",
        f"Telegram ID: <code>{user.telegram_id if user.telegram_id is not None else '-'}</code>",
        f"Истекает: <b>{format_datetime(user.expire_at)}</b>",
        (
            "Трафик: "
            f"<b>{format_bytes(user.used_traffic_bytes)}</b> / "
            f"<b>{format_traffic_limit(user.traffic_limit_bytes)}</b>"
        ),
        f"За все время: <b>{format_bytes(user.lifetime_used_traffic_bytes)}</b>",
        f"Последний UA: {html.escape(user.sub_last_user_agent or 'неизвестно')}",
        f"Последнее открытие подписки: {format_datetime(user.sub_last_opened_at)}",
        f"Подписка: {html.escape(user.subscription_url)}",
    ]

    if user.email:
        lines.append(f"Email: {html.escape(user.email)}")
    if user.tag:
        lines.append(f"Tag: <code>{html.escape(user.tag)}</code>")
    if user.description:
        lines.append(f"Описание: {html.escape(user.description)}")
    if squad_names:
        lines.append(f"Squads: {html.escape(', '.join(sorted(squad_names)))}")

    if recent_requests:
        lines.append("")
        lines.append("<b>Последние запросы подписки</b>")
        for request in recent_requests:
            lines.append(
                f"- {format_datetime(request.request_at)} | "
                f"IP: {html.escape(request.request_ip or '-')} | "
                f"UA: {html.escape((request.user_agent or '-')[:80])}"
            )

    return "\n".join(lines)
