import json
import os
import time
from aiogram.types import Message, CallbackQuery, FSInputFile
from aiogram.fsm.context import FSMContext
from aiogram import Router, F
from aiogram.utils.i18n import gettext as _
from AsyncPayments.crystalPay import AsyncCrystalPay
from states.state import CreateISPOrderState, ChangeCredentialsState, ChangeStickyState, GetProxyState, \
    ActivatePromoDiscountState, ActivatePromoTrafficState, FindISPState, AddPlanState, CreateCustomOrderState, \
    ChooseProtocolISP, ActionWhiteListState
from keyboards import inline, pagination
from models.user import User
from models.admin import Admin
from config import CRYSTALPAY_SECRET, CRYSTALPAY_SALT, CRYSTALPAY_LOGIN, LightningProxiesAPI_KEY, send_to_admins
from LightningProxiesAPI import LightningProxiesAPI
from utils import helpers, heleket


crystalPay = AsyncCrystalPay(CRYSTALPAY_LOGIN, CRYSTALPAY_SECRET, CRYSTALPAY_SALT)
proxy_api = LightningProxiesAPI(api_key=LightningProxiesAPI_KEY)

router: Router = Router()

user_last_click_time = {}

FLOOD_TIME_LIMIT = 3

async def check_flood(user_id):
    current_time = time.time()
    last_click = user_last_click_time.get(user_id, 0)
    
    if current_time - last_click < FLOOD_TIME_LIMIT:
        return False
    else:
        user_last_click_time[user_id] = current_time
        return True


@router.callback_query(F.data.startswith('change_lang'))
async def change_lang_callback_button(callback_query: CallbackQuery, user_model: User):
    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    return await callback_query.message.edit_text( _('user.message.change_lang'),
                                                   reply_markup=inline.switch_language_menu(user_info['language']))

@router.callback_query(F.data == "back")
async def back_menu(callback_query: CallbackQuery, state: FSMContext, user_model: User, admin_model: Admin):
    await state.clear()

    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)

    orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
    subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

    return await callback_query.message.edit_text(_("common.welcome.message").format(username= user_info["username"],
                        user_id=callback_query.message.from_user.id,
                        plans_count=len(subs_list),
                        orders_count=len(orders),
                        date=user_info["created_at"]),
                        reply_markup=inline.start_menu())

@router.callback_query(F.data == "back_file")
async def back_menu(callback_query: CallbackQuery, state: FSMContext, user_model: User, admin_model: Admin):
    await state.clear()
    await callback_query.message.delete()

    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)

    orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
    subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

    return await callback_query.message.answer(_("common.welcome.message").format(username= user_info["username"],
                        user_id=callback_query.from_user.id,
                        plans_count=len(subs_list),
                        orders_count=len(orders),
                        date=user_info["created_at"]),
                        reply_markup=inline.start_menu())

@router.callback_query(F.data.startswith("order_back_"))
async def back_menu(callback_query: CallbackQuery, state: FSMContext, user_model: User, admin_model: Admin):
    await state.clear()
    order_id: int = int(callback_query.data.split("_")[2])
    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    await admin_model.delete_order_by_id(order_id)

    orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
    subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

    return await callback_query.message.edit_text(_("common.welcome.message").format(username= user_info["username"],
                        user_id=callback_query.from_user.id,
                        plans_count=len(subs_list),
                        orders_count=len(orders),
                        date=user_info["created_at"]),
                        reply_markup=inline.start_menu())

@router.callback_query(F.data.startswith("switch_lang"))
async def switch_lang_callback_button(callback_query: CallbackQuery, user_model: User):
    lang_code: str = callback_query.data.split("_")[2]
    await user_model.update_user(callback_query.from_user.id, 'language', lang_code)

    return await callback_query.message.edit_text(_("user.switch_lang.success_message").format(lang_code=lang_code),
                        reply_markup=inline.back_menu())


@router.callback_query(F.data == "my_referral")
async def my_referral_callback_button(callback_query: CallbackQuery, user_model: User, admin_model: Admin):
    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    get_referral_percent: dict = await admin_model.get_settings_by_key('referral_percent')
    referral_link = f"https://t.me/{(await callback_query.bot.get_me()).username}{user_info['referral_link']}"
    return await callback_query.message.edit_text(_("user.my_referral.callback").format(
                            percent=get_referral_percent['value'],
                            referral_counts=user_info['referral_counts'],
                            balance=user_info['referral_balance'],
                            referral_link=referral_link
                        ),
                        reply_markup=inline.back_menu())


@router.callback_query(F.data == "buy_proxies")
async def process_category_callback_button(callback_query: CallbackQuery, admin_model: Admin):
    products: dict = await admin_model.get_products()
    return await callback_query.message.edit_text(_("user.buy_proxies.callback"),
                                                  reply_markup=inline.products_category_menu(products))

@router.callback_query(F.data.startswith("product_"))
async def process_product_callback_button(callback_query: CallbackQuery, admin_model: Admin):
    product_id = int(callback_query.data.split('_')[1])
    variants: dict = await admin_model.get_variants(product_id)
    product_info: dict = await admin_model.get_product_by_id(product_id)

    custom_button: bool = True
    description = None

    if product_info["name"] == "IPV6 Unlimited" or product_info["name"] == "IPV6 Bandwidth":
        description = _("user.product_description.ipv6")

    if product_info["name"] == "ISP Proxies":
        description = _("user.product_description.isp")

    if product_info["name"] == "Mobile":
        description = _("user.product_description.mobile")

    if product_info["name"] == "Residential":
        description = _("user.product_description.residential")

    if product_info["name"] in ["DATACENTER", "IPV6 Unlimited", "IPV6 Bandwidth"]:
        custom_button = False

    if product_info["name"] == "IPV6 Unlimited":
        return await callback_query.message.edit_text(f'{_("user.process_category.callback")}\n\n {description}'
                                                      f' \n{_("rules.use.proxy")}',
                                                      reply_markup=inline.variants_ipv_category_menu(variants))

    return await callback_query.message.edit_text(f'{_("user.process_category.callback")}\n\n {description}'
                                                  f'\n{_("rules.use.proxy")}',
                                                  reply_markup=inline.variants_category_menu(variants,
                                                                                             custom=custom_button))

@router.callback_query(F.data.startswith('custom_'))
async def process_custom_callback(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    product_id: int = int(callback_query.data.split('custom_')[1])
    product_info: dict = await admin_model.get_product_by_id(product_id)

    if product_info["name"] == "ISP Proxies":
        await state.update_data(product_id=product_id)
        await callback_query.message.edit_text(_("user.isp.custom_value"), reply_markup=inline.back_menu())
        return await state.set_state(CreateISPOrderState.count)

    if product_info["name"] in ["Mobile", "Residential"]:
        await state.update_data(product_id=product_id)
        await callback_query.message.edit_text(_("user.gb.custom_value"), reply_markup=inline.back_menu())
        return await state.set_state(CreateCustomOrderState.count)

@router.message(CreateCustomOrderState.count)
async def get_custom_gb_value(message: Message, state: FSMContext, admin_model: Admin):
    if not message.text.isdigit():
         return await message.answer(_("user.gb.error.custom"), reply_markup=inline.back_menu())

    data = await state.get_data()
    product_id = data['product_id']
    product_info: dict = await admin_model.get_product_by_id(product_id)
    await state.update_data(count=int(message.text))

    order_id: int = await admin_model.create_order(message.from_user.id, 0)
    payments_systems = await admin_model.get_active_payments_systems()

    price = product_info['per_unit'] * int(message.text)
    discounts = float(helpers.get_discount(json.loads(product_info['discounts']), int(message.text)))

    if discounts > 0:
        discount_amount = price * (discounts / 100)
        price -= discount_amount

    await state.update_data(price=price)
    await admin_model.update_order(order_id, "attributes", json.dumps({"custom": True,
                                                                        "price": price,
                                                                        "product_id": data["product_id"],
                                                                        "bandwidth": int(message.text),
                                                                        "name": 'Custom'}))

    return await message.answer(_("user.process_variant.callback").format(
         variant_name=f"{product_info['name']} Custom",
         price=price),
         reply_markup=inline.payments_systems_menu(order_id, payments_systems))


@router.message(CreateISPOrderState.count)
async def get_custom_isp_value(message: Message, state: FSMContext):
    if not message.text.isdigit():
        return await message.answer(_('user.add.plan.gb.error.callback'), reply_markup=inline.back_menu())

    await state.update_data(count=int(message.text))
    await message.answer(_("user.processISP.callback"),
                                                  reply_markup=inline.isp_proxies_menu())
    return await state.set_state(CreateISPOrderState.country_code)


@router.callback_query(F.data.startswith("variant_"))
async def process_variant_callback_button(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    variant_id = int(callback_query.data.split('_')[1])
    variant_info: dict = await admin_model.get_variant_by_id(variant_id)
    get_product: dict = await admin_model.get_product_by_id(variant_info["product_id"])

    if get_product["name"] == "ISP Proxies":
        await state.update_data(variant_id=variant_id)
        await state.update_data(product_id=variant_info["product_id"])
        await state.set_state(CreateISPOrderState.country_code)
        return await callback_query.message.edit_text(_("user.processISP.callback"),
                                                      reply_markup=inline.isp_proxies_menu())

    payments_systems = await admin_model.get_active_payments_systems()
    order_id: int = await admin_model.create_order(callback_query.from_user.id, variant_id)
    return await callback_query.message.edit_text(_("user.process_variant.callback").format(
        variant_name=f"{get_product['name']} {variant_info['name']}",
        price=variant_info['price']
    ),
    reply_markup=inline.payments_systems_menu(order_id, payments_systems))

@router.callback_query(CreateISPOrderState.country_code)
async def process_get_region_code(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    region_code: str = callback_query.data.split('_')[1]
    data = await state.get_data()
    await state.clear()

    get_product: dict = await admin_model.get_product_by_id(data["product_id"])
    if not 'count' in data:
        variant_info: dict = await admin_model.get_variant_by_id(data["variant_id"])

        order_id: int = await admin_model.create_order(callback_query.from_user.id, data["variant_id"])
        await admin_model.update_order(order_id, "attributes", json.dumps({"region": region_code}))

        payments_systems = await admin_model.get_active_payments_systems()
        return await callback_query.message.edit_text(_("user.process_variant.callback").format(
            variant_name=f"{get_product['name']} {variant_info['name']}",
            price=variant_info['price']
        ),
        reply_markup=inline.payments_systems_menu(order_id, payments_systems))

    order_id: int = await admin_model.create_order(callback_query.from_user.id, 0)
    payments_systems = await admin_model.get_active_payments_systems()

    price = get_product['per_unit'] * data['count']
    discounts = float(helpers.get_discount(json.loads(get_product['discounts']), data['count']))

    if discounts > 0:
        discount_amount = price * (discounts / 100)
        price -= discount_amount

    await admin_model.update_order(order_id, "attributes", json.dumps({"custom": True,
                                                                       "price": price,
                                                                       "product_id": data["product_id"],
                                                                       "region": region_code,
                                                                       "ip": int(data['count'])}))

    await state.update_data(price=price)
    await state.update_data(product_id=data["product_id"])

    await callback_query.message.edit_text(_("user.process_variant.callback").format(
        variant_name=f"{get_product['name']} Custom",
        price=price),
        reply_markup=inline.payments_systems_custom_menu(order_id, payments_systems))
    return await state.set_state(CreateISPOrderState.payment)

@router.callback_query(CreateISPOrderState.payment)
async def process_custom_isp_payment(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin, user_model: User):
    if callback_query.data.startswith('order_back'):
        await state.clear()
        order_id: int = int(callback_query.data.split("order_back_")[1])
        await admin_model.delete_order_by_id(order_id)
        user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
        orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
        subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

        return await callback_query.message.edit_text(_("common.welcome.message").format(username=user_info["username"],
                                                     user_id=callback_query.from_user.id,
                                                     plans_count=len(subs_list),
                                                     orders_count=len(orders),
                                                     date=user_info["created_at"]),
                                                     reply_markup=inline.start_menu())

    data = await state.get_data()
    order_id: int = int(callback_query.data.split('_')[2])
    payment_system = callback_query.data.split('_')[3]
    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    product_info: dict = await admin_model.get_product_by_id(data["product_id"])
    await admin_model.update_order(order_id, "payment_system", payment_system)
    price = data["price"]

    if user_info['discount'] > 0:
        discount_percentage: float = user_info['discount'] / 100
        price = price * (1 - discount_percentage)

    if payment_system == "crystalpay":
        payment = await crystalPay.create_payment(amount=price,
                                        amount_currency="USD",
                                        redirect_url=f"https://t.me/{(await callback_query.bot.get_me()).username}")


        await admin_model.update_order(order_id, "order_id", payment.id)
        await state.clear()

        return await callback_query.message.edit_text(_("user.process_payment.callback").format(
            variant_name=f"{product_info['name']} Custom",
            price=price,
            payment=payment_system.title()
        ),
        reply_markup=inline.check_payment(order_id, payment.url))

    if payment_system == "heleket":
        unique_order_id = await admin_model.generate_unique_order_id()
        payment = await heleket.create_payment(amount=price, order_id=unique_order_id)

        await admin_model.update_order(order_id, "order_id", payment['result']['uuid'])
        await state.clear()

        return await callback_query.message.edit_text(_("user.process_payment.callback").format(
            variant_name=f"{product_info['name']} Custom",
            price=price,
            payment=payment_system.title()
        ),
        reply_markup=inline.check_payment(order_id,  payment['result']['url']))

    if payment_system == 'referral':
        if user_info['referral_balance'] < price:
            return await callback_query.message.edit_text(_("user.ref.error.callback"), reply_markup=inline.back_menu())

        unique_order_id = await admin_model.generate_unique_order_id()
        await admin_model.update_order(order_id, "order_id", unique_order_id)

        return await callback_query.message.edit_text(_("user.process_payment.ref.callback").format(
            variant_name=f"{product_info['name']} Custom",
            price=price,
            payment=payment_system.title()
        ),
        reply_markup=inline.check_referral_payment(order_id))

@router.callback_query(F.data.startswith("payment_"))
async def process_variant_callback_button(callback_query: CallbackQuery, admin_model: Admin, user_model: User):
    order_id: int = int(callback_query.data.split('_')[1])
    payment_system = callback_query.data.split('_')[2]

    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    order_info: dict = await admin_model.get_order_by_id(order_id)
    order_attributes = json.loads(order_info['attributes']) if order_info['attributes'] else {}

    variant_info: dict = await admin_model.get_variant_by_id(order_info["variant_id"])
    if order_attributes.get('custom'):
        variant_info = {
            "price": order_attributes['price'],
            "product_id": order_attributes['product_id'],
            "attributes": json.dumps({}),
            "name": order_attributes['name'],
        }

    get_product: dict = await admin_model.get_product_by_id(variant_info["product_id"])
    await admin_model.update_order(order_id, "payment_system", payment_system)

    if user_info['discount'] > 0:
        variant_info: dict = dict(variant_info)
        discount_percentage: float = user_info['discount'] / 100
        variant_info["price"] = variant_info["price"] * (1 - discount_percentage)

    if payment_system == "crystalpay":
        payment = await crystalPay.create_payment(amount=variant_info['price'],
                                        amount_currency="USD",
                                        redirect_url=f"https://t.me/{(await callback_query.bot.get_me()).username}")


        await admin_model.update_order(order_id, "order_id", payment.id)

        return await callback_query.message.edit_text(_("user.process_payment.callback").format(
            variant_name=f"{get_product['name']} {variant_info['name']}",
            price=variant_info['price'],
            payment=payment_system.title()
        ),
        reply_markup=inline.check_payment(order_id, payment.url))

    if payment_system == "heleket":
        unique_order_id = await admin_model.generate_unique_order_id()
        payment = await heleket.create_payment(amount=variant_info['price'],
                                                          order_id=unique_order_id)
        print(payment)

        await admin_model.update_order(order_id, "order_id",  payment['result']['uuid'])

        return await callback_query.message.edit_text(_("user.process_payment.callback").format(
            variant_name=f"{get_product['name']} {variant_info['name']}",
            price=variant_info['price'],
            payment=payment_system.title()
        ),
        reply_markup=inline.check_payment(order_id,  payment['result']['url']))

    if payment_system == "referral":
        if user_info['referral_balance'] < variant_info['price']:
            return await callback_query.message.edit_text(_("user.ref.error.callback"), reply_markup=inline.back_menu())

        unique_order_id = await admin_model.generate_unique_order_id()
        await admin_model.update_order(order_id, "order_id", unique_order_id)

        return await callback_query.message.edit_text(_("user.process_payment.ref.callback").format(
            variant_name=f"{get_product['name']} {variant_info['name']}",
            price=variant_info['price'],
            payment=payment_system.title()
        ),
        reply_markup=inline.check_referral_payment(order_id))

async def update_referral_balance(user_info: dict, variant_info: dict, admin_model: Admin, user_model: User):
    if user_info["referred_id"] is None:
        return

    percent: dict = await admin_model.get_settings_by_key('referral_percent')
    percent_referred: float = (float(variant_info["price"]) * int(percent["value"])) / 100
    referred_info: dict = await user_model.get_by_user_id(user_info["referred_id"])
    return await user_model.update_user(user_info["referred_id"],
                                        'referral_balance',
                                        (float(referred_info["referral_balance"]) + percent_referred))

async def update_subscribe_attributes(subscription_info: dict, admin_model: Admin):
    attributes = {}
    if subscription_info["plan"] == 'Mobile':
        proxy_info = proxy_api.get_mobile_proxy_info(subscription_info['planID'])
        attributes = {
          "login": proxy_info['user'],
          "password": proxy_info['pass'],
          "port": 8000,
          "host": "eu-mob.proxydream.net",
          "time": 15,
          "country": None,
          "isp": None
        }


    if subscription_info["plan"] == 'IPV6 Bandwidth':
        proxy_info = proxy_api.get_ipv6_proxy_info(subscription_info['planID'])
        attributes = {
          "login": proxy_info['proxies']['username'],
          "password": proxy_info['proxies']['password'],
          "port": 1001,
          "host": "ipv6.proxydream.net",
          "time": 900,
          "country": None,
        }

    if subscription_info['plan'] == 'IPV6 Unlimited':
        proxy_info = proxy_api.get_ipv6_proxy_info(subscription_info['planID'])
        attributes = {
          "login": proxy_info['proxies']['username'],
          "password": proxy_info['proxies']['password'],
          "port": 1001,
          "host": "ipv6.proxydream.net",
          "time": 900,
          "country": None,
        }

    if subscription_info["plan"] == 'Residential':
        proxy_info = proxy_api.get_residential_proxy_info(subscription_info['planID'])
        attributes = {
            "login": proxy_info['user'],
            "password": proxy_info['pass'],
            "port": 9999,
            "host": "eu-res.proxydream.net",
            "time": 15,
            "country": None,
            "isp": None,
            "state": None,
            "city": None,
            "region": None
        }

    await admin_model.update_subscribe(subscription_info['id'], 'attributes', json.dumps(attributes))

@router.callback_query(F.data.startswith("check_"))
async def process_variant_callback_button(callback_query: CallbackQuery, admin_model: Admin, user_model: User):
    order_id = int(callback_query.data.split('_')[1])
    order_info: dict = await admin_model.get_order_by_id(order_id)
    order_attributes = json.loads(order_info['attributes']) if order_info['attributes'] else {}
    variant_info: dict = await admin_model.get_variant_by_id(order_info["variant_id"])
    
    if order_attributes.get('custom'):
        variant_info = {
            "price": order_attributes['price'],
            "product_id": order_attributes['product_id'],
            "attributes": json.dumps({})
        }

    user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
    get_product: dict = await admin_model.get_product_by_id(variant_info["product_id"])

    all_attributes: dict = json.loads(variant_info["attributes"])
    if order_info["attributes"] is not None:
        all_attributes = {**json.loads(variant_info["attributes"]), **json.loads(order_info["attributes"])}

    if order_info["payment_system"] == "heleket":
        payment_info = await heleket.get_payment_info(uuid=order_info["order_id"])
        if payment_info['result']['payment_status'] == "paid" or payment_info['result']['payment_status'] == "paid_over":

            if user_info['discount'] > 0:
                await user_model.update_user(callback_query.from_user.id, 'discount', 0)

            await admin_model.update_order(order_id, "status", True)

            create_purchase = proxy_api.purchase_plan(get_product["name"], **all_attributes)
            proxy_info = proxy_api.get_product_info(create_purchase["PlanID"])

            subscribe_id = await admin_model.create_subscriptions(callback_query.from_user.id,
                                                   order_id,
                                                   get_product["name"],
                                                   create_purchase["PlanID"],
                                                   helpers.convert_iso_time(proxy_info["expiration_date"]))
            subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
            await update_subscribe_attributes(subscribe_info, admin_model)

            await update_referral_balance(user_info, variant_info, admin_model, user_model)

            await send_to_admins(callback_query.message.bot, f'<b>ℹ️Пользователь совершил покупку:</b>\n\n'
                                                            f'🆔: <code>{callback_query.from_user.id}</code>\n'
                                                            f'💳Система оплаты: '
                                                            f'<code>{order_info["payment_system"].title()}</code>\n'
                                                            f'💎Сумма покупки: <code>{variant_info["price"]}</code>\n'
                                                            f'🛒Продукт: <code>{get_product["name"]}</code>\n')

            return await callback_query.message.edit_text(_("user.success_payment.callback"),
                                                      reply_markup=inline.success_payment_menu())
        else:
            return

    if order_info["payment_system"] == "crystalpay":
        payment_info = await crystalPay.get_payment_info(order_info["order_id"])
        print(payment_info)
        if payment_info.state == "payed":

            if user_info['discount'] > 0:
                await user_model.update_user(callback_query.from_user.id, 'discount', 0)

            await admin_model.update_order(order_id, "status", True)

            create_purchase = proxy_api.purchase_plan(get_product["name"], **all_attributes)
            proxy_info = proxy_api.get_product_info(create_purchase["PlanID"])

            subscribe_id = await admin_model.create_subscriptions(callback_query.from_user.id,
                                                   order_id,
                                                   get_product["name"],
                                                   create_purchase["PlanID"],
                                                   helpers.convert_iso_time(proxy_info["expiration_date"]))
            subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

            await update_subscribe_attributes(subscribe_info, admin_model)
            await update_referral_balance(user_info, variant_info, admin_model, user_model)

            await send_to_admins(callback_query.message.bot, f'<b>ℹ️Пользователь совершил покупку:</b>\n\n'
                                                    f'🆔: <code>{callback_query.from_user.id}</code>\n'
                                                    f'💳Система оплаты: '
                                                    f'<code>{order_info["payment_system"].title()}</code>\n'
                                                    f'💎Сумма покупки: <code>{variant_info["price"]}</code>\n'
                                                    f'🛒Продукт: <code>{get_product["name"]}</code>\n')

            try:
                return await callback_query.message.edit_text(_("user.success_payment.callback"),
                                                          reply_markup=inline.success_payment_menu())
            except Exception as e:
                await callback_query.message.delete()
                return await callback_query.message.answer(_("user.success_payment.callback"),
                                                          reply_markup=inline.success_payment_menu())
        else:
            return 

    if order_info["payment_system"] == "referral":
        await user_model.update_user(callback_query.from_user.id, 'referral_balance', 0)

        if user_info['discount'] > 0:
            await user_model.update_user(callback_query.from_user.id, 'discount', 0)

        await admin_model.update_order(order_id, "status", True)

        create_purchase = proxy_api.purchase_plan(get_product["name"], **all_attributes)
        proxy_info = proxy_api.get_product_info(create_purchase["PlanID"])
        subscribe_id = await admin_model.create_subscriptions(callback_query.from_user.id,
                                                              order_id,
                                                              get_product["name"],
                                                              create_purchase["PlanID"],
                                                              helpers.convert_iso_time(proxy_info["expiration_date"]))
        subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

        await update_subscribe_attributes(subscribe_info, admin_model)
        await update_referral_balance(user_info, variant_info, admin_model, user_model)

        await send_to_admins(callback_query.message.bot, f'<b>ℹ️Пользователь совершил покупку:</b>\n\n'
                                                            f'🆔: <code>{callback_query.from_user.id}</code>\n'
                                                            f'💳Система оплаты: '
                                                            f'<code>{order_info["payment_system"].title()}</code>\n'
                                                            f'💎Сумма покупки: <code>{variant_info["price"]}</code>\n'
                                                            f'🛒Продукт: <code>{get_product["name"]}</code>\n')

        return await callback_query.message.edit_text(_("user.success_payment.callback"),
                                                      reply_markup=inline.success_payment_menu())


@router.callback_query(F.data == 'control_panel')
async def control_panel_callback_button(callback_query: CallbackQuery, admin_model: Admin):
    plans: list = await admin_model.get_subscriptions_user(callback_query.from_user.id)
    return callback_query.message.edit_text(_("user.control_panel.callback"),
                                            reply_markup=inline.control_panel_menu(plans))

@router.callback_query(F.data.startswith('plan'))
async def process_control_panel_callback_button(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    plan_id: int = int(callback_query.data.split('_')[1])
    plan_info: dict = await admin_model.get_subscription_by_id(plan_id)
    plan_attributes = None

    await state.clear()

    if plan_info["attributes"] is not None:
        plan_attributes = json.loads(plan_info["attributes"])

    if plan_info["plan"] == "ISP Proxies":
        order_info: dict = await admin_model.get_order_by_id(plan_info["order_id"])
        country: str = helpers.get_country_by_tag(json.loads(order_info["attributes"])["region"])
        isp_proxy_info = proxy_api.get_isp_proxy_info(plan_info["planID"])

        return await callback_query.message.edit_text(_("user.control_isp.callback").format(
            plan_id=plan_info["planID"],
            proxy_type=plan_info["plan"],
            country=country,
            protocol='HTTP port: 50100 / Socks5 Port: 50101',
            counts_proxy=len(isp_proxy_info["proxies"]),
            expires_at=plan_info["expires_at"],
        ),
        reply_markup=inline.plan_menu(plan_info["plan"], plan_id))

    if plan_info["plan"] == "Mobile":
        mobile_proxy_info = proxy_api.get_mobile_proxy_info(plan_info["planID"])
        protocol = 'HTTP' if plan_attributes["port"] == 8000 else 'SOCKS'

        return await callback_query.message.edit_text(_("user.control_mobile.callback").format(
            plan_id=plan_info["planID"],
            proxy_type=plan_info["plan"],
            bandwidth=mobile_proxy_info['bandwidth'],
            bandwidth_left=mobile_proxy_info['bandwidthLeft'],
            credentials=f'{mobile_proxy_info["user"]}:{mobile_proxy_info["pass"]}',
            expires_at=plan_info["expires_at"],
            time=plan_attributes["time"],
            country=plan_attributes["country"],
            isp=plan_attributes["isp"],
            protocol=protocol
        ),
        reply_markup=inline.plan_menu(plan_info["plan"], plan_id))

    if plan_info["plan"] == "IPV6 Bandwidth":
        protocol = 'HTTP' if plan_attributes["port"] == 1001 else 'SOCKS'
        ipv6_proxy_info = proxy_api.get_ipv6_proxy_info(plan_info["planID"])

        return await callback_query.message.edit_text(_("user.control_ipv6_bandwidth.callback").format(
            plan_id=plan_info["planID"],
            proxy_type=plan_info["plan"],
            bandwidth=ipv6_proxy_info["proxies"]["bandwidth"],
            bandwidth_left=ipv6_proxy_info["proxies"]["bandwidthLeft"],
            credentials=f'{plan_attributes["login"]}:{plan_attributes["password"]}',
            expires_at=plan_info["expires_at"],
            time=plan_attributes["time"],
            country=plan_attributes["country"],
            protocol=protocol
        ),
        reply_markup=inline.plan_menu(plan_info["plan"], plan_id))

    if plan_info["plan"] == "IPV6 Unlimited":
        protocol = 'HTTP' if plan_attributes["port"] == 1001 else 'SOCKS'

        return await callback_query.message.edit_text(_("user.control_ipv6_unlimited.callback").format(
            plan_id=plan_info["planID"],
            proxy_type=plan_info["plan"],
            credentials=f'{plan_attributes["login"]}:{plan_attributes["password"]}',
            expires_at=plan_info["expires_at"],
            time=plan_attributes["time"],
            country=plan_attributes["country"],
            protocol=protocol
        ),
        reply_markup=inline.plan_menu(plan_info["plan"], plan_id))


    if plan_info["plan"] == "Residential":
        residential_proxy_info = proxy_api.get_residential_proxy_info(plan_info["planID"])
        region_name: str = helpers.get_region_by_short_name(plan_attributes['region'])

        return await callback_query.message.edit_text(_("user.control_residential.callback").format(
            plan_id=plan_info["planID"],
            proxy_type=plan_info["plan"],
            bandwidth=residential_proxy_info['bandwidth'],
            bandwidth_left=residential_proxy_info['bandwidthLeft'],
            credentials=f'{residential_proxy_info["user"]}:{residential_proxy_info["pass"]}',
            expires_at=plan_info["expires_at"],
            time=plan_attributes["time"],
            country=plan_attributes["country"],
            isp=plan_attributes["isp"],
            protocol='HTTP&SOCKS',
            state=plan_attributes['state'],
            city=plan_attributes['city'],
            region=region_name
        ),
        reply_markup=inline.plan_menu(plan_info["plan"], plan_id))

@router.callback_query(F.data.startswith('change_credentials_'))
async def change_credentials_callback_button(callback_query: CallbackQuery):
    subscribe_id: int = int(callback_query.data.split('change_credentials_')[1])
    return callback_query.message.edit_text(_("user.change_credentials.callback"),
                                            reply_markup=inline.change_credentials_menu(subscribe_id))


@router.callback_query(F.data.startswith('random_credentials_'))
async def random_change_credentials_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('random_credentials_')[1])
    plan_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if plan_info["plan"] == "ISP Proxies":
        login: str = helpers.generate_username()
        password: str = helpers.generate_password()

        protocols: list = ['http', 'socks']
        for protocol in protocols:
            proxy_api.change_credentials(plan_info["planID"],
                                               'isp',
                                                login,
                                                password,
                                                protocol)

        return await callback_query.message.edit_text(_("user.random_credentials.isp.callback").format(
            login=login,
            password=password
        ),
        reply_markup=inline.back_menu())

@router.callback_query(F.data.startswith('yours_credentials_'))
async def yours_change_credentials_callback(callback_query: CallbackQuery, state: FSMContext):
    subscribe_id: int = int(callback_query.data.split('yours_credentials_')[1])
    await state.update_data(subscribe_id=subscribe_id)
    await state.set_state(ChangeCredentialsState.credentials)
    return await callback_query.message.edit_text(_("user.yours_credentials.callback").format())

@router.message(ChangeCredentialsState.credentials)
async def process_change_yours_credentials(message: Message, state: FSMContext, admin_model: Admin):
    data = await state.get_data()
    subscribe_id = data["subscribe_id"]

    credentials: list = message.text.split(':')
    login: str = credentials[0]
    password: str = credentials[1]

    if not helpers.validate_username(login):
        return await message.answer(_("user.yours_credentials.error_callback_username"),
                                    reply_markup=inline.back_menu())

    if not helpers.validate_password(password):
        return await message.answer(_("user.yours_credentials.error_callback_password"),
                                    reply_markup=inline.back_menu())

    await state.clear()
    plan_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if plan_info["plan"] == "ISP Proxies":
        protocols: list = ['http', 'socks']

        for protocol in protocols:
            proxy_api.change_credentials(plan_info["planID"],
                                               'isp',
                                                login,
                                                password,
                                                protocol)

        return await message.answer(_("user.random_credentials.isp.callback").format(
            login=login,
            password=password
        ),
        reply_markup=inline.back_menu())

async def send_proxy_file(callback_query: CallbackQuery, proxy_list: list, subscribe_info: dict):
    file = await helpers.generate_proxy_list(proxy_list, './tempfiles/',
                                             subscribe_info['plan'].replace(" ", "_"))
    
    if file is None:
        await callback_query.message.edit_text(_("user.proxy_get.error.callback"),
                                              reply_markup=inline.back_menu())
        return
    
    try:
        document = FSInputFile(file)

        await callback_query.message.delete()
        await callback_query.message.answer_document(document, caption=_("user.proxy_get.callback"),
                                                     reply_markup=inline.back_file_menu())
        return os.remove(file)
    except Exception as e:
        print(f"Error sending proxy file: {e}")
        # Clean up the file if it exists
        if file and os.path.exists(file):
            os.remove(file)
        await callback_query.message.edit_text(_("user.proxy_get.error.callback"),
                                              reply_markup=inline.back_menu())

@router.callback_query(F.data.startswith('get_proxy_'))
async def get_proxy_callback(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('get_proxy_')[1])
    plan_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if plan_info["plan"] == "ISP Proxies":
        return await callback_query.message.edit_text(_("user.change_protocol.protocol.callback"),
                                               reply_markup=inline.change_protocol_menu(subscribe_id))

    await state.set_state(GetProxyState.settings)
    await state.update_data(subscribe_id=subscribe_id)
    await callback_query.message.edit_text(_("user.proxy_get.select_type.callback"),
                                      reply_markup=inline.get_proxy_menu(subscribe_id, plan_info["plan"]))

@router.callback_query(GetProxyState.settings)
async def get_proxy_settings_callback(callback_query: CallbackQuery, state: FSMContext):
    data = await state.get_data()
    subscribe_id = data["subscribe_id"]

    if callback_query.data in ['country', 'country_isp', 'country_state', 'country_state_city', 'regions']:
        await state.update_data(settings=True)
        await state.update_data(proxy_options=callback_query.data)
        await callback_query.message.edit_text(_("user.proxy_get.sticky.settings.callback"),
                                    reply_markup=inline.choose_active_sticky_menu(subscribe_id))
        return await state.set_state(GetProxyState.sticky)


    if callback_query.data == 'with_settings':
        await state.update_data(settings=True)
        await callback_query.message.edit_text(_("user.proxy_get.sticky.settings.callback"),
                                    reply_markup=inline.choose_active_sticky_menu(subscribe_id))
        return await state.set_state(GetProxyState.sticky)

    if callback_query.data == 'without_settings':
        await state.update_data(settings=False)

    await state.set_state(GetProxyState.proxy_type)
    return await callback_query.message.edit_text(_("user.proxy_get.settings.callback"),
                                                  reply_markup=inline.select_type_proxy_menu(subscribe_id))

@router.message(GetProxyState.counts)
async def proxy_counts_callback(message: Message, state: FSMContext):
    data = await state.get_data()
    subscribe_id = data["subscribe_id"]

    if not message.text.isdigit():
        return await message.answer(_("user.proxy_get.counts.error.callback"), reply_markup=inline.back_menu())

    if not (1 <= int(message.text) <= 2000):
        return await message.answer(_("user.proxy_get.counts.error.callback"), reply_markup=inline.back_menu())

    await state.update_data(counts=int(message.text))
    await state.set_state(GetProxyState.proxy_type)
    return await message.answer(_("user.proxy_get.settings.callback"),
                                                  reply_markup=inline.select_type_proxy_menu(subscribe_id))

@router.callback_query(GetProxyState.sticky)
async def choose_status_sticky(callback_query: CallbackQuery, state: FSMContext):
    data: dict = await state.get_data()
    subscribe_id: int = data["subscribe_id"]
    sticky_status: str = callback_query.data.split('_')[1]

    if sticky_status == "on":
        await state.update_data(sticky=True)
        await state.set_state(GetProxyState.counts)
        return await callback_query.message.edit_text(_("user.proxy_get.counts.callback"),
                                                      reply_markup=inline.back_panel_menu(subscribe_id))

    if sticky_status == "off":
        await state.update_data(sticky=False)

    await callback_query.message.edit_text(_("user.proxy_get.settings.callback"),
                                                  reply_markup=inline.select_type_proxy_menu(subscribe_id))
    return await state.set_state(GetProxyState.proxy_type)

@router.callback_query(GetProxyState.proxy_type)
async def proxy_format_callback(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    data: dict = await state.get_data()
    subscribe_id: int = data["subscribe_id"]
    state_settings: bool = data["settings"]
    proxy_type: int =  int(callback_query.data.split('proxy_type_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    sticky_status = data.get("sticky")

    host: str = subscribe_attributes['host']
    port: int = subscribe_attributes['port']
    password: str = subscribe_attributes['password']

    if subscribe_info['plan'] == 'Residential':
        if not state_settings:
            login: str = f"{subscribe_attributes['login']}-zone-resi"
            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            return await callback_query.message.edit_text(_("user.without_settings.success.callback").format(
                                                    proxy=proxy_format),
                                                    reply_markup=inline.back_control_panel(subscribe_id))

        proxy_options = data['proxy_options']
        proxy_list: list = []

        if subscribe_attributes['region'] is not None:
            if subscribe_attributes['region'] == 'rsa':
                host = "as-res.proxydream.net"
            elif subscribe_attributes['region'] in ['eu', 'africa']:
                host = "eu-res.proxydream.net"
            elif subscribe_attributes['region'] in ['north_america', 'south_america']:
                host = "us-res.proxydream.net"

        if proxy_options == 'country_isp':
            if not sticky_status:
                login: str = ""
                if subscribe_attributes['country'] and subscribe_attributes['isp'] is None:
                    login = f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                elif subscribe_attributes['country'] and subscribe_attributes['isp']:
                    login: str = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                                  f"-asn-{subscribe_attributes['isp']}")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                    proxy=proxy_format),
                    reply_markup=inline.back_control_panel(subscribe_id))

            if subscribe_attributes['country'] is None or subscribe_attributes['isp'] is None:
                return await callback_query.message.edit_text(_("user.get_proxy.error.callback"),
                                                              reply_markup=inline.back_control_panel(subscribe_id))

            counts: int = data['counts']
            session_names: list = helpers.generate_unique_session_names(counts)

            for session_name in session_names:
                login = ""
                if subscribe_attributes['country'] and subscribe_attributes['isp'] is None:
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                              f"-session-{session_name}-sessTime-{subscribe_attributes['time']}")
                elif subscribe_attributes['country'] and subscribe_attributes['isp']:
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                              f"-asn-{subscribe_attributes['isp']}-"
                              f"session-{session_name}-sessTime-{subscribe_attributes['time']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi-"
                              f"session-{session_name}-sessTime-{subscribe_attributes['time']}")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                proxy_list.append(proxy_format)

            return await send_proxy_file(callback_query, proxy_list, subscribe_info)

        if proxy_options == 'country_state':
            if not sticky_status:
                login = ""
                if (subscribe_attributes['country'] and subscribe_attributes['state'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}")
                elif (subscribe_attributes['country'] and subscribe_attributes['state']):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                    proxy=proxy_format),
                    reply_markup=inline.back_control_panel(subscribe_id))

            if subscribe_attributes['country'] is None or subscribe_attributes['state'] is None:
                return await callback_query.message.edit_text(_("user.get_proxy.error.callback"),
                                                              reply_markup=inline.back_control_panel(subscribe_id))

            counts: int = data['counts']
            session_names: list = helpers.generate_unique_session_names(counts)

            for session_name in session_names:
                login = ""
                if (subscribe_attributes['country'] and subscribe_attributes['state'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                              f"-session-{session_name}-sessTime-{subscribe_attributes['time']}")
                elif (subscribe_attributes['country'] and subscribe_attributes['state']):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}-"
                                  f"session-{session_name}-sessTime-{subscribe_attributes['time']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi-"
                              f"session-{session_name}-sessTime-{subscribe_attributes['time']}")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                proxy_list.append(proxy_format)

            return await send_proxy_file(callback_query, proxy_list, subscribe_info)

        if proxy_options == 'country':
            if not sticky_status:
                login = ""
                if subscribe_attributes['country']:
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                    proxy=proxy_format),
                    reply_markup=inline.back_control_panel(subscribe_id))

            if subscribe_attributes['country'] is None:
                return await callback_query.message.edit_text(_("user.get_proxy.error.callback"),
                                                              reply_markup=inline.back_control_panel(subscribe_id))

            counts: int = data['counts']
            session_names: list = helpers.generate_unique_session_names(counts)

            for session_name in session_names:
                login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                          f"-session-{session_name}-sessTime-{subscribe_attributes['time']}")
                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                proxy_list.append(proxy_format)

            return await send_proxy_file(callback_query, proxy_list, subscribe_info)

        if proxy_options == 'country_state_city':
            if not sticky_status:
                login = ""
                if (subscribe_attributes['country'] and subscribe_attributes['state'] is None
                                                                            and subscribe_attributes['city'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}")
                elif (subscribe_attributes['country'] and subscribe_attributes['state']
                                                            and subscribe_attributes['city'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}")
                elif subscribe_attributes['country'] and subscribe_attributes['state'] and subscribe_attributes['city']:
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}-"
                                  f"city-{subscribe_attributes['city']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                    proxy=proxy_format),
                    reply_markup=inline.back_control_panel(subscribe_id))

            if subscribe_attributes['country'] is None or subscribe_attributes['state'] is None\
                    or subscribe_attributes['city'] is None:
                return await callback_query.message.edit_text(_("user.get_proxy.error.callback"),
                                                              reply_markup=inline.back_control_panel(subscribe_id))

            counts: int = data['counts']
            session_names: list = helpers.generate_unique_session_names(counts)

            for session_name in session_names:
                login = ""
                if (subscribe_attributes['country'] and subscribe_attributes['state'] is None
                                                                            and subscribe_attributes['city'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}"
                              f"-session-{session_name}-sessTime-{subscribe_attributes['time']}")
                elif (subscribe_attributes['country'] and subscribe_attributes['state']
                                                            and subscribe_attributes['city'] is None):
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}-"
                                  f"session-{session_name}-sessTime-{subscribe_attributes['time']}")
                elif subscribe_attributes['country'] and subscribe_attributes['state'] and subscribe_attributes['city']:
                    login = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['country']}-"
                                  f"-st-{subscribe_attributes['state']}-"
                                  f"city-{subscribe_attributes['city']}-"
                                  f"session-{session_name}-sessTime-{subscribe_attributes['time']}")
                else:
                    login = (f"{subscribe_attributes['login']}-zone-resi-"
                              f"session-{session_name}-sessTime-{subscribe_attributes['time']}")

                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                proxy_list.append(proxy_format)

            return await send_proxy_file(callback_query, proxy_list, subscribe_info)

        if proxy_options == 'regions':
            if subscribe_attributes['region'] is None:
                return await callback_query.message.edit_text(_("user.get_proxy.error.callback"),
                                                              reply_markup=inline.back_control_panel(subscribe_id))

            if not sticky_status:
                login: str = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['region']}")
                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                    proxy=proxy_format),
                    reply_markup=inline.back_control_panel(subscribe_id))

            counts: int = data['counts']
            session_names: list = helpers.generate_unique_session_names(counts)

            for session_name in session_names:
                login: str = (f"{subscribe_attributes['login']}-zone-resi-region-{subscribe_attributes['region']}-"
                              f"session-{session_name}-sessTime-{subscribe_attributes['time']}")
                proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
                proxy_list.append(proxy_format)

            return await send_proxy_file(callback_query, proxy_list, subscribe_info)

    if subscribe_info['plan'] == 'Mobile':
        if not state_settings:
            login: str = f"{subscribe_attributes['login']}-package-mobile"
            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            return await callback_query.message.edit_text(_("user.without_settings.success.callback").format(
                                                    proxy=proxy_format),
                                                    reply_markup=inline.back_control_panel(subscribe_id))

        if not sticky_status:
            login: str = f"{subscribe_attributes['login']}-package-mobile"
            if subscribe_attributes['country'] and subscribe_attributes['isp'] is None:
                login = (f"{subscribe_attributes['login']}-country-{subscribe_attributes['country']}-"
                         f"package-mobile")
            elif subscribe_attributes['country'] and subscribe_attributes['isp']:
                login = (f"{subscribe_attributes['login']}-country-{subscribe_attributes['country']}-"
                         f"asn-{subscribe_attributes['isp']}-"
                         f"package-mobile")

            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                                                    proxy=proxy_format),
                                                    reply_markup=inline.back_control_panel(subscribe_id))

        counts: int = data['counts']
        session_names: list = helpers.generate_unique_session_names(counts)
        proxy_list: list = []

        for session_name in session_names:
            login = ""
            if subscribe_attributes['country'] and subscribe_attributes['isp']:
                login: str = (f"{subscribe_attributes['login']}-country-"
                              f"{subscribe_attributes['country']}-asn-{subscribe_attributes['isp']}-"
                              f"session-{session_name}-time-{subscribe_attributes['time']}-package-mobile")
            elif subscribe_attributes['country'] and subscribe_attributes['isp'] is None:
                login: str = (f"{subscribe_attributes['login']}-country-"
                              f"{subscribe_attributes['country']}-"
                              f"session-{session_name}-time-{subscribe_attributes['time']}-package-mobile")
            elif subscribe_attributes['country'] is None and subscribe_attributes['isp'] is None:
                login: str = (f"{subscribe_attributes['login']}-"
                              f"session-{session_name}-time-{subscribe_attributes['time']}-package-mobile")

            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            proxy_list.append(proxy_format)

        return await send_proxy_file(callback_query, proxy_list, subscribe_info)

    if subscribe_info['plan'] in ['IPV6 Bandwidth', 'IPV6 Unlimited']:
        if not state_settings:
            login: str = f"{subscribe_attributes['login']}-package-ipv6"
            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            return await callback_query.message.edit_text(_("user.without_settings.success.callback").format(
                                                    proxy=proxy_format),
                                                    reply_markup=inline.back_control_panel(subscribe_id))

        if not sticky_status:
            login: str = ""
            if subscribe_attributes['country']:
                login = (f"{subscribe_attributes['login']}-country-{subscribe_attributes['country']}-"
                          f"package-ipv6")
            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            return await callback_query.message.edit_text(_("user.rotate_per_request.callback").format(
                                                    proxy=proxy_format),
                                                    reply_markup=inline.back_control_panel(subscribe_id))


        counts: int = data['counts']
        proxy_list: list = []
        session_names: list = helpers.generate_unique_session_names(counts)

        for session_name in session_names:
            login = ""
            if subscribe_attributes['country'] is None:
                login = (f"{subscribe_attributes['login']}-session-{session_name}-"
                         f"time-{subscribe_attributes['time']}-package-ipv6")
            else:
                login = (f"{subscribe_attributes['login']}-country-{subscribe_attributes['country']}-"
                          f"session-{session_name}-time-{subscribe_attributes['time']}-package-ipv6")

            proxy_format: str = helpers.format_string_proxy(login, password, host, port, proxy_type)
            proxy_list.append(proxy_format)
        return await send_proxy_file(callback_query, proxy_list, subscribe_info)

@router.callback_query(F.data.startswith('change_protocol_'))
async def protocol_choose_callback(callback_query: CallbackQuery):
    plan_id: int = int(callback_query.data.split('change_protocol_')[1])
    return await callback_query.message.edit_text(_("user.change_protocol.protocol.callback"),
                                                  reply_markup=inline.change_protocol_menu(plan_id))

@router.callback_query(F.data.startswith('set_protocol_'))
async def process_set_protocol(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('_')[2])
    protocol: str = callback_query.data.split('_')[3]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if subscribe_info['plan'] == 'ISP Proxies':
        if protocol == 'socks':
            proxies: list = proxy_api.get_isp_proxy_info(subscribe_info["planID"])['proxies']
            return await send_proxy_file(callback_query, proxies, subscribe_info)

        if protocol == 'http':
            proxies: list = proxy_api.get_isp_proxy_info(subscribe_info["planID"])['proxies']
            updated_proxies: list = [proxy.replace(":50101", ":50100") for proxy in proxies]
            return await send_proxy_file(callback_query, updated_proxies, subscribe_info)

    subscribe_attributes = json.loads(subscribe_info["attributes"])
    if subscribe_info['plan'] == 'Mobile':
        if protocol == "http":
            subscribe_attributes['port'] = 8000

        if protocol == "socks":
            subscribe_attributes['port'] = 8001

    if subscribe_info['plan'] in ["IPV6 Bandwidth", "IPV6 Unlimited"]:
        if protocol == "http":
            subscribe_attributes['port'] = 1001

        if protocol == "socks":
            subscribe_attributes['port'] = 999

    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.set_protocol.protocol.callback").format(
                                                        protocol=protocol
                                                    ),
                                                    reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_sticky_'))
async def change_sticky_time(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_sticky_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    await state.set_state(ChangeStickyState.time)
    await state.update_data(subscribe_id=subscribe_id)

    if subscribe_info["plan"] in ["Mobile", "Residential"]:
        return await callback_query.message.edit_text(_("user.change_sticky.callback"))

    if subscribe_info["plan"] in ['IPV6 Bandwidth', 'IPV6 Unlimited']:
        return await callback_query.message.edit_text(_("user.change_sticky.ipv.callback"))

@router.message(ChangeStickyState.time)
async def process_change_sticky_time(message: Message, state: FSMContext, admin_model: Admin):
    data = await state.get_data()
    subscribe_id: int = data["subscribe_id"]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if not message.text.isdigit():
        if subscribe_info["plan"] == "Mobile":
            return await message.answer(_("user.change_sticky.error.callback"),
                                    reply_markup=inline.back_menu())

        if subscribe_info['plan'] in ['IPV6 Bandwidth', 'IPV6 Unlimited']:
            return await message.answer(_("user.change_sticky.ipv.error.callback"),
                                        reply_markup=inline.back_menu())

    if subscribe_info["plan"] == "Mobile":
        if int(message.text) > 1440 or int(message.text) < 1:
            return await message.answer(_("user.change_sticky.error.callback"),
                                        reply_markup=inline.back_menu())

    if subscribe_info['plan'] in ['IPV6 Bandwidth', 'IPV6 Unlimited']:
        if int(message.text) > 86400 or int(message.text) < 60:
            return await message.answer(_("user.change_sticky.ipv.error.callback"),
                                        reply_markup=inline.back_menu())

    await state.clear()

    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['time'] = int(message.text)

    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await message.answer(_("user.change_sticky.success.callback").format(
                                            time=message.text),
                                            reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_loc_'))
async def change_country_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_loc_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    country_data = None

    if subscribe_info['plan'] == 'Mobile':
        country_data = proxy_api.get_mobile_countries()

    if subscribe_info['plan'] in ['IPV6 Bandwidth', 'IPV6 Unlimited']:
        country_data = helpers.get_ipv_countries()

    if subscribe_info['plan'] == 'Residential':
        return await callback_query.message.edit_text(_("user.change_loc.country.callback"),
                                                      reply_markup=inline.change_residential_country_menu(subscribe_id))

    return await callback_query.message.edit_text(_("user.change_loc.country.callback"),
                                                  reply_markup=inline.change_country_menu(country_data, subscribe_id))

@router.callback_query(pagination.Pagination.filter())
async def country_pagination_callback(callback_query: CallbackQuery):
    page: int = int(callback_query.data.split(':')[1])
    subscribe_id: int = int(callback_query.data.split(':')[2])

    return await callback_query.message.edit_reply_markup(
        reply_markup=inline.change_residential_country_menu(subscribe_id, page=page)
    )

@router.callback_query(pagination.PaginationISP.filter())
async def isp_pagination_callback(callback_query: CallbackQuery, admin_model: Admin):
    page: int = int(callback_query.data.split(':')[1])
    subscribe_id: int = int(callback_query.data.split(':')[2])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])

    if subscribe_info['plan'] == 'Mobile':
        isp_data = proxy_api.get_mobile_countries()
        paris_isp = helpers.get_asn_pairs_by_iso2(isp_data, subscribe_attributes['country'])

        return await callback_query.message.edit_reply_markup(
            reply_markup=inline.change_isp_menu(paris_isp, subscribe_id, page=page)
        )

    if subscribe_info['plan'] == 'Residential':
        isp_data = proxy_api.get_residential_isp_list(subscribe_attributes['country'])
        return await callback_query.message.edit_reply_markup(
            reply_markup=inline.change_isp_menu(isp_data, subscribe_id, page=page)
        )

@router.callback_query(F.data.startswith('find_isp_'))
async def find_isp_callback(callback_query: CallbackQuery, state: FSMContext):
    subscribe_id: int = int(callback_query.data.split('find_isp_')[1])

    await callback_query.message.edit_text(_("user.find_isp.get_isp.callback"),
                                           reply_markup=inline.back_control_panel(subscribe_id))
    await state.update_data(subscribe_id=subscribe_id)
    return await state.set_state(FindISPState.isp)

@router.message(FindISPState.isp)
async def find_isp_callback(message: Message, state: FSMContext, admin_model: Admin):
    data = await state.get_data()
    subscribe_id: int = data['subscribe_id']
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])

    filtered_isp = list
    if subscribe_info['plan'] == 'Mobile':
        isp_data = proxy_api.get_mobile_countries()
        paris_isp = helpers.get_asn_pairs_by_iso2(isp_data, subscribe_attributes['country'])
        filtered_isp = helpers.search_asn_pairs(paris_isp, message.text)

    if subscribe_info['plan'] == 'Residential':
        isp_data = proxy_api.get_residential_isp_list(subscribe_attributes['country'])
        filtered_isp = helpers.search_asn_pairs(isp_data, message.text)

    return await message.answer(_("user.find_isp.success.callback"),
            reply_markup=inline.change_isp_menu(filtered_isp, subscribe_id)
        )


@router.callback_query(F.data.startswith('country_'))
async def process_change_country(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('_')[1])
    country_iso: str = callback_query.data.split('_')[2]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['country'] = country_iso
    flag = helpers.iso2_to_flag(country_iso.lower())

    if subscribe_info['plan'] in ['Mobile', 'Residential']:
        subscribe_attributes['isp'] = None

        if subscribe_info['plan'] == 'Residential':
            subscribe_attributes['state'] = None
            subscribe_attributes['city'] = None

    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.change_loc.country.process").format(
                                            country=f'{flag}{country_iso.upper()}'),
                                            reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_isp_'))
async def change_isp_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_isp_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])

    if subscribe_attributes['country'] is None:
        return await callback_query.message.edit_text(_("user.change_isp.error.callback"),
                                                      reply_markup=inline.back_menu())


    if subscribe_info['plan'] == 'Mobile':
        isp_data = proxy_api.get_mobile_countries()
        paris_isp = helpers.get_asn_pairs_by_iso2(isp_data, subscribe_attributes['country'])
        return await callback_query.message.edit_text(_("user.change_isp.callback"),
                                                  reply_markup=inline.change_isp_menu(paris_isp, subscribe_id))

    if subscribe_info['plan'] == 'Residential':
        isp_data = proxy_api.get_residential_isp_list(subscribe_attributes['country'])
        return await callback_query.message.edit_text(_("user.change_isp.callback"),
                                                  reply_markup=inline.change_isp_menu(isp_data, subscribe_id))

@router.callback_query(F.data.startswith('isp_'))
async def change_isp_process(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('_')[1])
    isp_asn: str = callback_query.data.split('_')[2]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['isp'] = isp_asn

    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.change_isp.success.callback").format(
                                                        asn=isp_asn),
                                                        reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_state_'))
async def change_state_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_state_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if subscribe_info['plan'] == 'Residential':
        subscribe_attributes = json.loads(subscribe_info["attributes"])

        if subscribe_attributes['country'] is None:
            return await callback_query.message.edit_text(_("user.change_state.error.callback"),
                                                          reply_markup=inline.back_control_panel(subscribe_id))

        states = proxy_api.get_residential_states(subscribe_attributes['country'])
        return await callback_query.message.edit_text(_("user.change.state.callback"),
                                                      reply_markup=inline.change_state_menu(states, subscribe_id))

@router.callback_query(F.data.startswith('state_'))
async def process_change_state(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('_')[1])
    state_code: str = callback_query.data.split('_')[2]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['state'] = state_code


    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.change.state.process").format(
                                            state=f'{state_code.capitalize()}'),
                                            reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_city_'))
async def change_city_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_city_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if subscribe_info['plan'] == 'Residential':
        subscribe_attributes = json.loads(subscribe_info["attributes"])

        if subscribe_attributes['country'] is None:
            return await callback_query.message.edit_text(_("user.change_state.error.callback"),
                                                          reply_markup=inline.back_control_panel(subscribe_id))

        if subscribe_attributes['state'] is None:
            return await callback_query.message.edit_text(_("user.change_isp.error.state.callback"),
                                                          reply_markup=inline.back_control_panel(subscribe_id))

        cities = proxy_api.get_residential_cities(subscribe_attributes['country'], subscribe_attributes['state'])
        return await callback_query.message.edit_text(_("user.change.city.callback"),
                                                      reply_markup=inline.change_city_menu(cities, subscribe_id))

@router.callback_query(F.data.startswith('city_'))
async def process_change_state(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('_')[1])
    city: str = callback_query.data.split('_')[2]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['city'] = city


    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.change.city.process").format(
                                            state=f'{city.capitalize()}'),
                                            reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('change_region_'))
async def change_region_callback(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('change_region_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if subscribe_info['plan'] == 'Residential':
        regions = helpers.get_residential_regions()
        return await callback_query.message.edit_text(_("user.change.region.callback"),
                                                      reply_markup=inline.change_region_menu(regions, subscribe_id))

@router.callback_query(F.data.startswith('region:'))
async def process_change_state(callback_query: CallbackQuery, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split(':')[1])
    region: str = callback_query.data.split(':')[2]
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])
    subscribe_attributes['region'] = region
    region_name: str = helpers.get_region_by_short_name(region)

    await admin_model.update_subscribe(subscribe_id,'attributes', json.dumps(subscribe_attributes))
    return await callback_query.message.edit_text(_("user.change.region.process").format(
                                            state=f'{region_name.capitalize()}'),
                                            reply_markup=inline.back_panel_menu(subscribe_id))

@router.callback_query(F.data.startswith('add_plan_'))
async def add_plan_callback(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    subscribe_id: int = int(callback_query.data.split('add_plan_')[1])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    await state.update_data(subscribe_id=subscribe_id)

    if subscribe_info['plan'] in ['Residential', 'Mobile']:
        await callback_query.message.edit_text(_("user.add.plan.gb.callback"),
                                               reply_markup=inline.back_panel_menu(subscribe_id))
        return await state.set_state(AddPlanState.value)

    if subscribe_info['plan'] == 'IPV6 Bandwidth':
        await callback_query.message.edit_text(_("user.add.plan.ipv6.callback"), reply_markup=inline.add_plan_ipv6())
        return await state.set_state(AddPlanState.ipv_six)

@router.callback_query(AddPlanState.ipv_six)
async def get_accept_extend_plan_callback(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin, user_model: User):
    if callback_query.data == 'back':
        orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
        subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

        user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
        await state.clear()

        return await callback_query.message.edit_text(_("common.welcome.message").format(username=user_info["username"],
                                                        user_id=callback_query.from_user.id,
                                                        plans_count=len(subs_list),
                                                        orders_count=len(orders),
                                                        date=user_info["created_at"]),
                                                        reply_markup=inline.start_menu())

    data = await state.get_data()
    subscribe_id: int = data['subscribe_id']
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    if subscribe_info['plan'] == 'IPV6 Bandwidth':
        payments_systems = await admin_model.get_active_payments_systems()
        order_info: dict = await admin_model.get_order_by_id(subscribe_info['order_id'])
        variant_info: dict = await admin_model.get_variant_by_id(order_info['variant_id'])
        order_id: int = await admin_model.create_order(callback_query.message.from_user.id, order_info['variant_id'])

        await state.update_data(price=variant_info['price'])
        await callback_query.message.edit_text(_("user.add_plan.choose_payment").format(
            price=variant_info['price']),
            reply_markup=inline.payments_systems_add_menu(order_id, payments_systems))

        return await state.set_state(AddPlanState.payment)

@router.message(AddPlanState.value)
async def get_gb_add_plan(message: Message, state: FSMContext, admin_model: Admin):
    if not message.text.isdigit():
        return await message.answer(_("user.add.plan.gb.error.callback"), reply_markup=inline.back_menu())

    data = await state.get_data()
    subscribe_id: int = data['subscribe_id']
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    product_info: dict = await admin_model.get_product_by_name(subscribe_info['plan'])

    if subscribe_info['plan'] in ['Residential', 'Mobile']:
        price = float(product_info['per_unit']) * float(message.text)
        discounts = float(helpers.get_discount(json.loads(product_info['discounts']), int(message.text)))

        if discounts > 0:
            discount_amount = price * (discounts / 100)
            price -= discount_amount

        await state.update_data(value=int(message.text))
        payments_systems = await admin_model.get_active_payments_systems()
        order_info: dict = await admin_model.get_order_by_id(subscribe_info['order_id'])

        if order_info is None:
            order_id: int = await admin_model.create_order(message.from_user.id, 0)
        else: 
            order_id: int = await admin_model.create_order(message.from_user.id, order_info['variant_id'])

        await state.update_data(price=price)
        await message.answer(_("user.add_plan.choose_payment").format(
            price=price),
            reply_markup=inline.payments_systems_add_menu(order_id, payments_systems))

        return await state.set_state(AddPlanState.payment)



@router.callback_query(AddPlanState.payment)
async def process_add_payment(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin, user_model: User):
    if callback_query.data == 'back':
        user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
        await state.clear()

        orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
        subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

        return await callback_query.message.edit_text(_("common.welcome.message").format(username=user_info["username"],
                                                        user_id=callback_query.from_user.id,
                                                        plans_count=len(subs_list),
                                                        orders_count=len(orders),
                                                        date=user_info["created_at"]),
                                                        reply_markup=inline.start_menu())

    data = await state.get_data()
    order_id: int = int(callback_query.data.split('_')[2])
    payment_system = callback_query.data.split('_')[3]
    subscribe_id: int = data['subscribe_id']
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)

    await admin_model.update_order(order_id, "payment_system", payment_system)

    username = (await callback_query.bot.get_me()).username

    if payment_system == "crystalpay":
        payment = await crystalPay.create_payment(amount=data['price'],
                                                  amount_currency="USD",
                                                  redirect_url=f"https://t.me/"
                                                               f"{username}")

        await admin_model.update_order(order_id, "order_id", payment.id)
        await state.set_state(AddPlanState.check_payment)

        return await callback_query.message.edit_text(_("user.process_payment.add_plan.callback").format(
            plan=subscribe_info['plan'],
            price=data['price'],
            payment=payment_system.title()),
            reply_markup=inline.check_add_payment(order_id, payment.url))

    if payment_system == "heleket":
        unique_order_id = await admin_model.generate_unique_order_id()
        payment = await heleket.create_payment(amount=data['price'],
                                                          order_id=unique_order_id)

        await admin_model.update_order(order_id, "order_id",  payment['result']['uuid'])
        await state.set_state(AddPlanState.check_payment)

        return await callback_query.message.edit_text(_("user.process_payment.add_plan.callback").format(
            plan=subscribe_info['plan'],
            price=data['price'],
            payment=payment_system.title()),
            reply_markup=inline.check_add_payment(order_id,  payment['result']['url']))

@router.callback_query(AddPlanState.check_payment)
async def check_add_plan_payment(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin, user_model: User):
    if callback_query.data == 'back':
        user_info: dict = await user_model.get_by_user_id(callback_query.from_user.id)
        await state.clear()
        orders = await admin_model.get_orders_by_user_id(callback_query.from_user.id)
        subs_list = await admin_model.get_subscriptions_user(callback_query.from_user.id)

        return await callback_query.message.edit_text(_("common.welcome.message").format(username=user_info["username"],
                                                        user_id=callback_query.from_user.id,
                                                        plans_count=len(subs_list),
                                                        orders_count=len(orders),
                                                        date=user_info["created_at"]),
                                                        reply_markup=inline.start_menu())
    data = await state.get_data()
    subscribe_id: int = data['subscribe_id']
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    order_id = int(callback_query.data.split('_')[2])
    order_info: dict = await admin_model.get_order_by_id(order_id)

    if order_info["payment_system"] == "heleket":
        payment_info = await heleket.get_payment_info(uuid=order_info["order_id"])
        if payment_info['result']['payment_status'] == "paid" or payment_info['result']['payment_status'] == "paid_over":
            await admin_model.update_order(order_id, "status", True)

            if subscribe_info['plan'] == 'Mobile':
                proxy_api.manage_mobile_gigabyte('add', subscribe_info['planID'], data['value'])

            if subscribe_info['plan'] == 'Residential':
                proxy_api.manage_residential_gigabyte('add', subscribe_info['planID'], data['value'])

            if subscribe_info['plan'] == 'IPV6 Bandwidth':
                proxy_api.manage_ipv6_gigabyte('add', subscribe_info['planID'], 50)

            await state.clear()
            return await callback_query.message.edit_text(_("user.success.add_plan.callback"),
                                                          reply_markup=inline.back_control_panel(subscribe_id))
    if order_info["payment_system"] == "crystalpay":
        payment_info = await crystalPay.get_payment_info(order_info["order_id"])
        if payment_info.state == "payed":
            await admin_model.update_order(order_id, "status", True)

            if subscribe_info['plan'] == 'Mobile':
                proxy_api.manage_mobile_gigabyte('add', subscribe_info['planID'], data['value'])

            if subscribe_info['plan'] == 'Residential':
                proxy_api.manage_residential_gigabyte('add', subscribe_info['planID'], data['value'])

            if subscribe_info['plan'] == 'IPV6 Bandwidth':
                proxy_api.manage_ipv6_gigabyte('add', subscribe_info['planID'], 50)

            await state.clear()
            return await callback_query.message.edit_text(_("user.success.add_plan.callback"),
                                                          reply_markup=inline.back_control_panel(subscribe_id))


@router.callback_query(F.data == 'activate_promo')
async def activate_promo_code_callback(callback_query: CallbackQuery):
    return await callback_query.message.edit_text(_("user.activate.promo.callback"),
                                                  reply_markup=inline.promo_type_menu())

@router.callback_query(F.data == 'discount')
async def activate_discount_callback(callback_query: CallbackQuery, state: FSMContext):
    await callback_query.message.edit_text(_("user.activate.discount.callback"), reply_markup=inline.back_menu())
    return await state.set_state(ActivatePromoDiscountState.promo)

@router.message(ActivatePromoDiscountState.promo)
async def process_activate_discount(message: Message, state: FSMContext, admin_model: Admin, user_model: User):
    promo_info: dict = await admin_model.get_promo_discount_by_promo(message.text)

    if promo_info is None:
        return await message.answer(_("user.activate.promo.error.callback"), reply_markup=inline.back_menu())

    if promo_info['activations'] >= promo_info['total_activations']:
        return await message.answer(_("user.activate.promo.error.activations.callback"),
                                                        reply_markup=inline.back_menu())
    await state.clear()
    await user_model.update_user(message.from_user.id, 'discount', int(promo_info['discount']))
    await admin_model.update_promo_discount(promo_info['id'], 'activations', int(promo_info['activations']) + 1)

    await send_to_admins(message.bot, f'<b>ℹ️Пользователь активировал промокод:</b>\n\n'
                                                f'🆔: <code>{message.from_user.id}</code>\n'
                                                f'💳Промокод на скидку: <code>{promo_info["promo"]}</code>\n')

    return await message.answer(_("user.activate.promo.success").format(promo=promo_info['promo'],
                                                                        discount=int(promo_info['discount'])),
                                    reply_markup=inline.back_menu())

@router.callback_query(F.data == 'traffic')
async def activate_traffic_callback(callback_query: CallbackQuery, state: FSMContext):
    await callback_query.message.edit_text(_("user.activate.discount.callback"), reply_markup=inline.back_menu())
    return await state.set_state(ActivatePromoTrafficState.promo)

@router.message(ActivatePromoTrafficState.promo)
async def process_activate_traffic(message: Message, state: FSMContext, admin_model: Admin):
    promo_info: dict = await admin_model.get_promo_traffic_by_promo(message.text)

    if promo_info is None:
        return await message.answer(_("user.activate.promo.error.callback"), reply_markup=inline.back_menu())

    is_exits = await admin_model.is_promo_traffic_active_exits(promo_info['id'])
    if is_exits is not None:
        return await message.answer(_("user.activate.promo.error.activations.callback"), reply_markup=inline.back_menu())

    await state.clear()
    await admin_model.use_promo_traffic(message.from_user.id, promo_info['id'])
    await send_to_admins(message.bot, f'<b>ℹ️Пользователь активировал промокод:</b>\n\n'
                                                    f'🆔: <code>{message.from_user.id}</code>\n'
                                                    f'💳Промокод traffic: <code>{promo_info["promo"]}</code>\n')

    promo_attributes: dict = json.loads(promo_info['attributes'])
    product_info: dict = await admin_model.get_product_by_id(promo_attributes['product_id'])

    if product_info['name'] in ['Mobile', 'Residential', 'IPV6 Bandwidth', 'IPV6 Unlimited']:
        plan_id: str = proxy_api.purchase_plan(product_info['name'], **promo_attributes)['PlanID']
        proxy_info = proxy_api.get_product_info(plan_id)

        subscribe_id: int = await admin_model.create_subscriptions(message.from_user.id, 0,
                                               product_info['name'],
                                               plan_id,
                                               helpers.convert_iso_time(proxy_info["expiration_date"]))
        subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
        await update_subscribe_attributes(subscribe_info, admin_model)
        return await message.answer(_("user.traffic_success.callback"), reply_markup=inline.success_payment_menu())

    if product_info['name'] == 'ISP Proxies':
        order_unique_id: str = helpers.generate_order_id()
        order_id: int = await admin_model.create_order(message.from_user.id,
                                                       0,
                                                       'crystalpay',
                                                       order_unique_id)
        await admin_model.update_order(order_id,
                                       "attributes",
                                       json.dumps({"region": promo_attributes['region']}))

        plan_id: str = proxy_api.purchase_plan(product_info['name'], **promo_attributes)['PlanID']
        proxy_info = proxy_api.get_product_info(plan_id)
        await admin_model.create_subscriptions(message.from_user.id,
                                                               order_id,
                                                               product_info['name'],
                                                               plan_id,
                                                               helpers.convert_iso_time(proxy_info["expiration_date"]))
        return await message.answer(_("user.traffic_success.callback"), reply_markup=inline.success_payment_menu())

@router.callback_query(F.data.startswith('deleted_'))
async def process_deleted_values_callback(callback_query: CallbackQuery, admin_model: Admin):
    option_delete: str = callback_query.data.split('_')[1]
    subscribe_id: int = int(callback_query.data.split('_')[2])
    subscribe_info: dict = await admin_model.get_subscription_by_id(subscribe_id)
    subscribe_attributes = json.loads(subscribe_info["attributes"])

    subscribe_attributes[option_delete] = None
    await admin_model.update_subscribe(subscribe_info['id'], 'attributes', json.dumps(subscribe_attributes))

    return await callback_query.message.edit_text(_("user.deleted.success.callback"),
                                                  reply_markup=inline.back_control_panel(subscribe_id))

@router.callback_query(F.data.startswith('add_whitelist_'))
async def add_whitelist_callback(callback_query: CallbackQuery):
    plan_id: str = callback_query.data.split('_')[2]
    return await callback_query.message.edit_text(_("user.whitelist.success.callback"),
                                                  reply_markup=inline.add_whitelist_menu(plan_id))

@router.callback_query(F.data.startswith('whitelist_'))
async def process_action_whitelist(callback_query: CallbackQuery, state: FSMContext, admin_model: Admin):
    action: str = callback_query.data.split('_')[1]
    plan_id: str = callback_query.data.split('_')[2]
    plan_info: dict = await admin_model.get_subscription_by_id(int(plan_id))

    await state.set_state(ActionWhiteListState.ip)
    await state.update_data(action=action)
    await state.update_data(subs_id=plan_info['planID'])
    await state.update_data(plan_id=plan_id)
    return await callback_query.message.edit_text(_("user.whitelist.action.callback"),
                                                  reply_markup=inline.back_control_panel(int(plan_id)))


@router.message(ActionWhiteListState.ip)
async def process_whitelist(message: Message, state: FSMContext):
    data = await state.get_data()

    try:
        proxy_api.manage_ipv6_whitelist(data['action'], data['subs_id'], message.text)
        return await message.answer(_("user.whitelist.action.success").format(
            action=data['action'],
            ip=message.text
        ), reply_markup=inline.back_control_panel(int(data['plan_id'])))
    except Exception as e:
        print(e)
        return await message.answer(_("user.whitelist.action.bad"),
                                    reply_markup=inline.back_control_panel(int(data['plan_id'])))

