"""Пример: Telegram бот для управления подписками через Amnezio SDK.

Этот пример показывает, как интегрировать SDK в Telegram бота.
Используйте aiogram 3.x или python-telegram-bot.
"""

import asyncio
from datetime import date, timedelta
from amnezio import AmnezioClient
from amnezio.exceptions import NotFoundError, APIError

# Настройки
PANEL_URL = "https://panel.example.com"
PANEL_USERNAME = "admin"
PANEL_PASSWORD = "secret"
DEFAULT_PROFILE_ID = 1
SUBSCRIPTION_DAYS = 30


class VPNManager:
    """Менеджер VPN подписок."""
    
    def __init__(self, panel_url: str, username: str, password: str):
        self.panel_url = panel_url
        self.username = username
        self.password = password
    
    async def create_subscription(
        self,
        telegram_id: int,
        telegram_username: str = None,
        days: int = SUBSCRIPTION_DAYS
    ) -> dict:
        """
        Создать подписку для пользователя Telegram.
        
        Returns:
            dict: Данные подписки с конфигом
        """
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            # Генерация ключей
            keypair = await client.users.generate_keypair()
            
            # Создание пользователя
            sub_id = f"tg_{telegram_id}"
            description = f"Telegram: @{telegram_username}" if telegram_username else f"TG ID: {telegram_id}"
            
            user = await client.users.create(
                sub_id=sub_id,
                private_key=keypair.private_key,
                preshared_key=keypair.preshared_key,
                telegram_id=telegram_id,
                profile_id=DEFAULT_PROFILE_ID,
                paid_for=date.today() + timedelta(days=days),
                tag="telegram",
                description=description
            )
            
            # Получение конфига
            config = await client.users.get_config(user.id)
            
            # Получение QR-кода
            qrcode = await client.users.get_qrcode(user.id)
            
            return {
                "user_id": user.id,
                "sub_id": user.sub_id,
                "assigned_ip": user.assigned_ip,
                "paid_for": user.paid_for,
                "config": config.config,
                "qrcode": qrcode,
                "private_key": keypair.private_key,
            }
    
    async def get_subscription(self, telegram_id: int) -> dict:
        """
        Получить данные подписки по Telegram ID.
        
        Returns:
            dict: Данные пользователя
        """
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            # Поиск пользователя по telegram_id через список
            result = await client.users.list(page=1, per_page=100)
            
            for user in result.items:
                if user.telegram_id == telegram_id:
                    # Проверка истечения подписки
                    is_active = user.status == "active"
                    is_expired = user.paid_for and user.paid_for < date.today()
                    
                    return {
                        "user_id": user.id,
                        "sub_id": user.sub_id,
                        "status": user.status,
                        "assigned_ip": user.assigned_ip,
                        "paid_for": user.paid_for,
                        "is_active": is_active,
                        "is_expired": is_expired,
                        "days_left": (user.paid_for - date.today()).days if user.paid_for else 0,
                        "rx_bytes": user.rx_bytes,
                        "tx_bytes": user.tx_bytes,
                    }
            
            raise NotFoundError(f"Подписка для Telegram ID {telegram_id} не найдена")
    
    async def renew_subscription(self, telegram_id: int, days: int = SUBSCRIPTION_DAYS) -> dict:
        """
        Продлить подписку.
        
        Returns:
            dict: Обновленные данные
        """
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            # Находим пользователя
            subscription = await self.get_subscription(telegram_id)
            user_id = subscription["user_id"]
            
            # Получаем пользователя
            user = await client.users.get(user_id)
            
            # Вычисляем новую дату
            if user.paid_for and user.paid_for >= date.today():
                new_date = user.paid_for + timedelta(days=days)
            else:
                new_date = date.today() + timedelta(days=days)
            
            # Продлеваем подписку
            user = await client.users.renew_subscription(user_id, new_date)
            
            return {
                "user_id": user.id,
                "paid_for": user.paid_for,
                "status": user.status,
                "days_left": (user.paid_for - date.today()).days,
            }
    
    async def get_config(self, telegram_id: int) -> dict:
        """
        Получить конфиг пользователя.
        
        Returns:
            dict: Конфиг и QR-код
        """
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            # Находим пользователя
            subscription = await self.get_subscription(telegram_id)
            user_id = subscription["user_id"]
            
            # Получаем конфиг и QR-код
            config = await client.users.get_config(user_id)
            qrcode = await client.users.get_qrcode(user_id)
            
            return {
                "config": config.config,
                "qrcode": qrcode,
            }
    
    async def disable_subscription(self, telegram_id: int) -> dict:
        """Отключить подписку."""
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            subscription = await self.get_subscription(telegram_id)
            user = await client.users.disable(subscription["user_id"])
            return {"status": user.status}
    
    async def enable_subscription(self, telegram_id: int) -> dict:
        """Включить подписку."""
        async with AmnezioClient(
            base_url=self.panel_url,
            username=self.username,
            password=self.password
        ) as client:
            subscription = await self.get_subscription(telegram_id)
            user = await client.users.enable(subscription["user_id"])
            return {"status": user.status}


# Пример использования в Telegram боте (aiogram 3.x)
"""
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command

bot = Bot(token="YOUR_BOT_TOKEN")
dp = Dispatcher()
vpn = VPNManager(PANEL_URL, PANEL_USERNAME, PANEL_PASSWORD)


@dp.message(Command("start"))
async def cmd_start(message: types.Message):
    await message.answer(
        "Добро пожаловать! Команды:\n"
        "/buy - Купить подписку\n"
        "/status - Статус подписки\n"
        "/config - Получить конфиг\n"
        "/renew - Продлить подписку"
    )


@dp.message(Command("buy"))
async def cmd_buy(message: types.Message):
    try:
        # Проверяем, нет ли уже подписки
        try:
            sub = await vpn.get_subscription(message.from_user.id)
            await message.answer(f"У вас уже есть подписка! Статус: {sub['status']}")
            return
        except NotFoundError:
            pass
        
        # Создаем подписку
        result = await vpn.create_subscription(
            telegram_id=message.from_user.id,
            telegram_username=message.from_user.username
        )
        
        await message.answer(
            f"✅ Подписка создана!\n"
            f"ID: {result['sub_id']}\n"
            f"IP: {result['assigned_ip']}\n"
            f"Действует до: {result['paid_for']}"
        )
        
        # Отправляем конфиг файлом
        config_file = types.BufferedInputFile(
            result['config'].encode(),
            filename="amneziawg.conf"
        )
        await message.answer_document(config_file, caption="Ваш конфиг AmneziaWG")
        
        # Отправляем QR-код
        qr_file = types.BufferedInputFile(result['qrcode'], filename="qrcode.png")
        await message.answer_photo(qr_file, caption="QR-код для быстрой настройки")
        
    except APIError as e:
        await message.answer(f"❌ Ошибка: {e.message}")


@dp.message(Command("status"))
async def cmd_status(message: types.Message):
    try:
        sub = await vpn.get_subscription(message.from_user.id)
        
        status_emoji = "✅" if sub['is_active'] and not sub['is_expired'] else "❌"
        
        # Форматирование трафика
        rx_gb = sub['rx_bytes'] / (1024**3)
        tx_gb = sub['tx_bytes'] / (1024**3)
        
        await message.answer(
            f"{status_emoji} Статус подписки\n\n"
            f"ID: {sub['sub_id']}\n"
            f"IP: {sub['assigned_ip']}\n"
            f"Статус: {sub['status']}\n"
            f"Действует до: {sub['paid_for']}\n"
            f"Осталось дней: {sub['days_left']}\n\n"
            f"📊 Трафик:\n"
            f"Получено: {rx_gb:.2f} GB\n"
            f"Отправлено: {tx_gb:.2f} GB"
        )
    except NotFoundError:
        await message.answer("❌ У вас нет активной подписки. Используйте /buy")


@dp.message(Command("config"))
async def cmd_config(message: types.Message):
    try:
        result = await vpn.get_config(message.from_user.id)
        
        # Отправляем конфиг
        config_file = types.BufferedInputFile(
            result['config'].encode(),
            filename="amneziawg.conf"
        )
        await message.answer_document(config_file)
        
        # Отправляем QR-код
        qr_file = types.BufferedInputFile(result['qrcode'], filename="qrcode.png")
        await message.answer_photo(qr_file)
        
    except NotFoundError:
        await message.answer("❌ У вас нет активной подписки")
    except APIError as e:
        if e.status_code == 403:
            await message.answer("❌ Ваша подписка истекла. Используйте /renew")
        else:
            await message.answer(f"❌ Ошибка: {e.message}")


@dp.message(Command("renew"))
async def cmd_renew(message: types.Message):
    try:
        # Здесь должна быть логика оплаты
        # После успешной оплаты:
        result = await vpn.renew_subscription(message.from_user.id, days=30)
        
        await message.answer(
            f"✅ Подписка продлена!\n"
            f"Действует до: {result['paid_for']}\n"
            f"Осталось дней: {result['days_left']}"
        )
    except NotFoundError:
        await message.answer("❌ У вас нет подписки. Используйте /buy")


async def main():
    await dp.start_polling(bot)


if __name__ == "__main__":
    asyncio.run(main())
"""
