# -*- coding: utf-8 -*-
import io
import asyncio
import logging
import os
import firebase_admin
import time
import openai
import pydantic
import pydub
from pydub import AudioSegment
from firebase_admin import credentials
from firebase_admin import db
from firebase_admin import storage
from datetime import datetime
from aiogram import F
from aiogram.types import LabeledPrice
from aiogram.filters import Text
from aiogram.filters.command import Command
from aiogram.filters.state import StatesGroup, State
from aiogram.fsm.context import FSMContext
from aiogram.types.inline_keyboard_button import InlineKeyboardButton
from aiogram.types.inline_keyboard_markup import InlineKeyboardMarkup
from aiogram.utils.keyboard import ReplyKeyboardMarkup
from aiogram.filters.command import CommandObject
from aiogram.types.keyboard_button import KeyboardButton
from aiogram import Bot, Dispatcher, types

logging.basicConfig(level=logging.INFO)


class Rassilka(StatesGroup):
    mes = State()
    mes1 = State()
    b = State()


class Rassilka1(StatesGroup):
    mes = State()
    mes1 = State()
    b = State()

    def __init__(self, user_id):
        self.user_id = user_id


data = {}
msg_id = 0
but = []

premium_time = {
    2: 172800,
    14: 1209600,
    30: 2592000,
    90: 7776000,
    180: 15552000,
}

channel_id1 = '@kodirovannyj_kalejdoskop'
channel_id2 = -1001869516533
channel_id3 = '@Compasai'
channel_id4 = -1001886859987
channel_id5 = '@Dom_a_i'
channel_id6 = -1001886859987

paybox_token = ''
robokassa_token = '1902332405:LIVE:638181212001057626'

# Задаем параметры цены
PRICE_50 = LabeledPrice(label="50 генераций", amount=81 * 100)
PRICE_100 = LabeledPrice(label="100 генераций", amount=163 * 100)
PRICE_250 = LabeledPrice(label="250 генераций", amount=290 * 100)
PRICE_1000 = LabeledPrice(label="1000 генераций", amount=820 * 100)

PREMIUM_2 = LabeledPrice(label="2 дня Premium", amount=81 * 100)
PREMIUM_14 = LabeledPrice(label="14 дней Premium", amount=147 * 100)
PREMIUM_30 = LabeledPrice(label="30 дней Premium", amount=262 * 100)
PREMIUM_90 = LabeledPrice(label="90 дней Premium", amount=614 * 100)
PREMIUM_180 = LabeledPrice(label="180 дней Premium", amount=1064 * 100)

openai.api_key = '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'

now = datetime.now()
bot_token = "5891239594:AAEgsgbOwm2_GuIX10NmcSEZmTebNRjID1Q"
# Инициализируем бота и диспетчера
bot = Bot(token=bot_token)
dp = Dispatcher()

cred = credentials.Certificate(
    "gpt1-7fc56-firebase-adminsdk-t1jod-7da26928ac.json")
default_app = firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://gpt1-7fc56-default-rtdb.firebaseio.com/',
})

user = {
    'main': 'kk'
}
db.reference('/users_database/' + 'main').set(user)


def clear_dialog(user_id):
    if user_id not in data:
        data[user_id] = []
    if len(data[user_id]) > 10:
        data[user_id] = []
    return


def checking_rassilka():
    buttons = [
        [KeyboardButton(text='Да')],
        [KeyboardButton(text='Нет')]
    ]
    keyboard = ReplyKeyboardMarkup(keyboard=buttons, resize_keyboard=True)
    return keyboard


def owner_button():
    buttons = [
        [InlineKeyboardButton(text='Написать', url='https://t.me/Victor11V')]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def subscribe2_button():
    buttons = [
        [InlineKeyboardButton(text='Перейти', url='https://t.me/MidjourneyV5_kk')],
        [InlineKeyboardButton(text='Подписался', callback_data='subscribe4')]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard

def subscribe_button():
    buttons = [
        [
            InlineKeyboardButton(text='Перейти 1', url='https://t.me/+ArtOZ6MIJXM2MDEy'),
            InlineKeyboardButton(text='Перейти 2', url='https://t.me/MidjourneyV5_kk'),
            InlineKeyboardButton(text='Перейти 3', url='https://t.me/Dom_a_i')
        ],
        [
            InlineKeyboardButton(text='Подписался', callback_data='subscribe1'),
            InlineKeyboardButton(text='Подписался', callback_data='subscribe2'),
            InlineKeyboardButton(text='Подписался', callback_data='subscribe3'),
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def channels_url():
    buttons = [
        [
            InlineKeyboardButton(text='Channel 1', url="https://t.me/kodirovannyj_kalejdoskop"),
            InlineKeyboardButton(text='Channel 2', url="https://t.me/+TznrkCIBWzs5ZTFk"),
            InlineKeyboardButton(text='Channel 3', url='https://t.me/+s13usg9dzh80Mzhk')
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def catalog_keyboard():
    buttons = [
        [
            InlineKeyboardButton(text='Стандарт', callback_data='standart'),
        ],
        [
            InlineKeyboardButton(text='Гопник', callback_data='gopnik'),
            InlineKeyboardButton(text='Комик', callback_data='comic')
        ],
        [
            InlineKeyboardButton(text='Писатель', callback_data='writer'),
            InlineKeyboardButton(text='Психолог', callback_data='psycho')
        ],
        [
            InlineKeyboardButton(text='Копирайтер', callback_data='copywriter'),
            InlineKeyboardButton(text='SEO-помощник', callback_data='seo-helper')
        ],
        [
            InlineKeyboardButton(text='Пикап тренер', callback_data='pikap'),
            InlineKeyboardButton(text='Маркетолог', callback_data='marketolog')
        ],
        [
            InlineKeyboardButton(text='ГДЗ', callback_data='gdz'),
            InlineKeyboardButton(text='Программист', callback_data='programmist')
        ],
        [
            InlineKeyboardButton(text='Генератор бизнес идей', callback_data='generator'),
            InlineKeyboardButton(text='В двух словах', callback_data='2-words')
        ],
        [
            InlineKeyboardButton(text='Переводчик', callback_data='translate'),
            InlineKeyboardButton(text='Бухгалтер', callback_data='buchgalter')
        ],
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_premium_selection():
    buttons = [
        [
            InlineKeyboardButton(text='Robokassa', callback_data='robokassa_prem'),
            InlineKeyboardButton(text='Paybox', callback_data='paybox_prem')
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_generations_selection():
    buttons = [
        [
            InlineKeyboardButton(text='Robokassa', callback_data='robokassa_gen'),
            InlineKeyboardButton(text='Paybox', callback_data='paybox_gen')
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_premium_robokassa():
    buttons = [
        [
            InlineKeyboardButton(text='2 дня - 1$', callback_data='2-prem-robo'),
            InlineKeyboardButton(text='1 Неделя - 1.8$', callback_data='14-prem-robo'),

        ],
        [
            InlineKeyboardButton(text='1 Месяц - 3.2$', callback_data='30-prem-robo'),
            InlineKeyboardButton(text='3 Месяца - 7.5$', callback_data='90-prem-robo')
        ],
        [
            InlineKeyboardButton(text='6 Месяцев - 13$', callback_data='180-prem-robo'),
        ]

    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_generations_robokassa():
    buttons = [
        [
            InlineKeyboardButton(text='50 - 1$', callback_data='50-gen-robo'),
            InlineKeyboardButton(text='100 - 2$', callback_data='100-gen-robo'),

        ],
        [
            InlineKeyboardButton(text='250 - 3.5$', callback_data='250-gen-robo'),
            InlineKeyboardButton(text='1000 - 10$', callback_data='1000-gen-robo')
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_premium_paybox():
    buttons = [
        [
            InlineKeyboardButton(text='2 дня - 1$', callback_data='2-prem-paybox'),
            InlineKeyboardButton(text='1 Неделя - 1.8$', callback_data='14-prem-paybox'),

        ],
        [
            InlineKeyboardButton(text='1 Месяц - 3.2$', callback_data='30-prem-paybox'),
            InlineKeyboardButton(text='3 Месяца - 7.5$', callback_data='90-prem-paybox')
        ],
        [
            InlineKeyboardButton(text='6 Месяцев - 13$', callback_data='180-prem-paybox'),
        ]

    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def payment_generations_paybox():
    buttons = [
        [
            InlineKeyboardButton(text='50 - 1$', callback_data='50-gen-paybox'),
            InlineKeyboardButton(text='100 - 2$', callback_data='100-gen-paybox'),

        ],
        [
            InlineKeyboardButton(text='250 - 3.5$', callback_data='250-gen-paybox'),
            InlineKeyboardButton(text='1000 - 10$', callback_data='1000-gen-paybox')
        ]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def channels():
    buttons = [
        [InlineKeyboardButton(text='Stable Diffusion', url='https://t.me/stablediffusion1_bot')],
        [InlineKeyboardButton(text='Midjourney V5', url='https://t.me/Midjourney_kk1_bot')]
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def checking_premium(id: int):
    n = time.time()
    if db.reference('/users_database/' + str(id)).get()['premium'] == 'Yes':
        if db.reference('/users_database/' + str(id)).get()['premium_time'] + premium_time[
            db.reference('/users_database/' + str(id)).get()['premium_type']] <= n:
            user = {
                'premium': 'No',
                'premium_time': 0,
                'premium_type': 0,
            }
            db.reference('/users_database/' + str(id)).update(user)
            return False
        else:
            return True
    else:
        return False


def free_menu():
    buttons = [
        [InlineKeyboardButton(text='Бесплатные генерации картинок каждые 24 часа', callback_data='free_24_generations')],
        [InlineKeyboardButton(text='Генерации картинок за подписку', callback_data='2_generations')],
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def generation_keyboard():
    buttons = [
        [InlineKeyboardButton(text='???? Бесплатные генерации картинок', callback_data='free_generations')],
        [InlineKeyboardButton(text='???? Купить генерации', callback_data='buy_generations')],
    ]
    keyboard = InlineKeyboardMarkup(inline_keyboard=buttons)
    return keyboard


def reply_keyboard():
    buttons = [
        [
            KeyboardButton(text='???? Инфо'),
            KeyboardButton(text='???? Каталог'),

        ],

        [
            KeyboardButton(text='???? Новый диалог'),
            KeyboardButton(text='???? Нарисовать картинку'),
            KeyboardButton(text='Мой ID ????')
        ],
        [
            KeyboardButton(text='???? Midjourney V5.1')
        ]
    ]
    keyboard = ReplyKeyboardMarkup(keyboard=buttons, resize_keyboard=True)
    return keyboard


def generate_answer(message_text, user_id):
    try:
        if user_id not in data:
            data[user_id] = []
        data[user_id].append({'role': 'user', 'content': message_text})
        answer = openai.ChatCompletion.create(
            model='gpt-3.5-turbo',
            messages=data[user_id],
            temperature=db.reference('/users_database/' + str(user_id)).get()['temperature']
        )
        data[user_id].append(answer.choices[0].message)
    except Exception as e:
        print(e)
        return "Произошла ошибка во время генерации запроса ⚠️.\nПопробуйте написать /start или повторите попытку позже"
    else:
        return answer.choices[0].message['content']


def generate_image(message_text, user_id):
    answer = openai.Image.create(
        prompt=message_text,
        n=1,
        size="1024x1024"
    )
    updating = {
        'generation': db.reference('/users_database/' + str(user_id)).get()['generation'] - 1
    }
    db.reference('/users_database/' + str(user_id)).update(updating)
    return answer['data'][0]['url']


def generate_answer_voice(user_id):
    try:
        AudioSegment.from_file(f'audio/ogg/{user_id}.ogg').export(f'audio/mp3/{user_id}.mp3',
                                                                  format='mp3')
        audio_file = open(f'audio/mp3/{user_id}.mp3', 'rb')
        transcript = openai.Audio.transcribe("whisper-1", audio_file)
        audio_file.close()
        os.remove(f'audio/mp3/{user_id}.mp3')
        os.remove(f'audio/ogg/{user_id}.ogg')
        if user_id not in data:
            data[user_id] = []
        data[user_id].append({'role': 'user', 'content': transcript['text']})
        answer = openai.ChatCompletion.create(
            model='gpt-3.5-turbo',
            messages=data[user_id],
            temperature=db.reference('/users_database/' + str(user_id)).get()['temperature']
        )
        data[user_id].append(answer.choices[0].message)
    except:
        return "Произошла ошибка во время генерации запроса ⚠️.\nПопробуйте написать /start или повторите попытку позже"
    else:
        return answer.choices[0].message['content']


@dp.callback_query(Text('paybox_prem'))
async def paybox_prem(query: types.CallbackQuery):
    await query.message.answer('Выберите план:', reply_markup=payment_premium_paybox())


@dp.callback_query(Text('paybox_gen'))
async def paybox_gen(query: types.CallbackQuery):
    await query.message.answer('Выберите количевство генераций:', reply_markup=payment_generations_paybox())


@dp.callback_query(Text('2-prem-paybox'))
async def prem_20_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='2 дня Premium',
        description="Покупка 2 дня Premium",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PREMIUM_2],
        start_parameter='2-premium',
        payload="2-p",
    )


@dp.callback_query(Text('14-prem-paybox'))
async def prem_14_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='14 дней Premium',
        description="Покупка 14 дня Premium",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PREMIUM_14],
        start_parameter='14-premium',
        payload="14-p",
    )


@dp.callback_query(Text('30-prem-paybox'))
async def prem_30_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='30 дня Premium',
        description="Покупка 30 дня Premium",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PREMIUM_30],
        start_parameter='30-premium',
        payload="30-p",
    )


@dp.callback_query(Text('90-prem-paybox'))
async def prem_90_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='90 дней Premium',
        description="Покупка 90 дня Premium",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PREMIUM_90],
        start_parameter='90-premium',
        payload="90-p",
    )


@dp.callback_query(Text('180-prem-paybox'))
async def prem_180_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='180 дней Premium',
        description="Покупка 180 дня Premium",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PREMIUM_180],
        start_parameter='180-premium',
        payload="180-p",
    )


@dp.callback_query(Text('50-gen-paybox'))
async def gen_50_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='50 генераций',
        description="Покупка 50 генераций",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PRICE_50],
        start_parameter='50-gen',
        payload="50-g",
    )


@dp.callback_query(Text('100-gen-paybox'))
async def gen_100_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='100 генераций',
        description="Покупка 100 генераций",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PRICE_100],
        start_parameter='100-gen',
        payload="100-g",
    )


@dp.callback_query(Text('250-gen-paybox'))
async def gen_250_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='250 генераций',
        description="Покупка 250 генераций",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PRICE_250],
        start_parameter='250-gen',
        payload="250-g",
    )


@dp.callback_query(Text('1000-gen-paybox'))
async def gen_1000_paybox(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='1000 генераций',
        description="Покупка 1000 генераций",
        provider_token=paybox_token,
        currency='USD',
        is_flexible=False,
        prices=[PRICE_1000],
        start_parameter='1000-gen',
        payload="1000-g",
    )


@dp.callback_query(Text('robokassa_prem'))
async def robo_prem(query: types.CallbackQuery):
    await query.message.answer('Выберите план:', reply_markup=payment_premium_robokassa())


@dp.callback_query(Text('robokassa_gen'))
async def robo_gen(query: types.CallbackQuery):
    await query.message.answer('Выберите количевство генераций:', reply_markup=payment_generations_robokassa())


@dp.callback_query(Text('2-prem-robo'))
async def prem_20_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='2 дня Premium',
        description="Покупка 2 дня Premium",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PREMIUM_2],
        start_parameter='2-premium',
        payload="2-p",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "Премиум 2","quantity": 1,"sum": 81,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('14-prem-robo'))
async def prem_14_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='14 дней Premium',
        description="Покупка 14 дня Premium",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PREMIUM_14],
        start_parameter='14-premium',
        payload="14-p",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "Премиум 14","quantity": 1,"sum": 147,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('30-prem-robo'))
async def prem_30_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='30 дня Premium',
        description="Покупка 30 дня Premium",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PREMIUM_30],
        start_parameter='30-premium',
        payload="30-p",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "Премиум 30","quantity": 1,"sum": 262,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('90-prem-robo'))
async def prem_90_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='90 дней Premium',
        description="Покупка 90 дня Premium",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PREMIUM_90],
        start_parameter='90-premium',
        payload="90-p",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "Премиум 90","quantity": 1,"sum": 614,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('180-prem-robo'))
async def prem_180_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='180 дней Premium',
        description="Покупка 180 дня Premium",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PREMIUM_180],
        start_parameter='180-premium',
        payload="180-p",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "Премиум 180","quantity": 1,"sum": 1064,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('50-gen-robo'))
async def gen_50_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='50 генераций',
        description="Покупка 50 генераций",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PRICE_50],
        start_parameter='50-gen',
        payload="50-g",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "50 генераций","quantity": 1,"sum": 81,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('100-gen-robo'))
async def gen_100_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='100 генераций',
        description="Покупка 100 генераций",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PRICE_100],
        start_parameter='100-gen',
        payload="100-g",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "100 генераций","quantity": 1,"sum": 162,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('250-gen-robo'))
async def gen_250_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='250 генераций',
        description="Покупка 250 генераций",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PRICE_250],
        start_parameter='250-gen',
        payload="250-g",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "250 генераций","quantity": 1,"sum": 290,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('1000-gen-robo'))
async def gen_1000_robo(query: types.CallbackQuery):
    await bot.send_invoice(
        chat_id=query.from_user.id,
        title='1000 генераций',
        description="Покупка 1000 генераций",
        provider_token=robokassa_token,
        currency='RUB',
        is_flexible=False,
        prices=[PRICE_1000],
        start_parameter='1000-gen',
        payload="1000-g",
        provider_data='{"sno":"usn_income", "InvoiceId": 0, "Receipt": {"items": [{"name": "1000 генераций","quantity": 1,"sum": 820,"tax": "none","payment_method": "full_payment"}]}}'
    )


@dp.callback_query(Text('buy_generations'))
async def buy_gen(query: types.CallbackQuery):
    await query.message.answer('----Покупка генераций----\n',
                               reply_markup=payment_generations_selection())


@dp.callback_query(Text('subscribe4'))
async def subscribe4_func(query: types.CallbackQuery):
    is_subscribed = await bot.get_chat_member(channel_id4, query.from_user.id)
    if is_subscribed.status != 'left':
        await query.message.answer('Успешно подписались на канал ✔')
    elif is_subscribed.status == 'left':
        await query.message.answer('Вы не подписались на канал ❌')

@dp.callback_query(Text('subscribe1'))
async def subscribe_func(query: types.CallbackQuery):
    try:
        if db.reference('/users_database/' + str(query.from_user.id)).get()['2_generation1'] == 1:
            await query.message.answer('Вы уже получили 2 генерации за этот канал')
            return
    except KeyError:
        is_subscribed3 = await bot.get_chat_member(channel_id3, query.from_user.id)
        if not is_subscribed3.status == 'left':
            user1 = {
                'generation': db.reference('/users_database/' + str(query.from_user.id)).get()['generation'] + 2,
                '2_generation1': 1
            }
            db.reference('/users_database/' + str(query.from_user.id)).update(user1)
            await query.message.answer('Успешно получено 2 генерации')
        else:
            await query.message.answer('Вы не подписались на канал')


@dp.callback_query(Text('subscribe2'))
async def subscribe2_func(query: types.CallbackQuery):
    try:
        if db.reference('/users_database/' + str(query.from_user.id)).get()['2_generation2'] == 1:
            await query.message.answer('Вы уже получили 2 генерации за этот канал')
            return
    except KeyError:
        is_subscribed4 = await bot.get_chat_member(channel_id4, query.from_user.id)
        if not is_subscribed4.status == 'left':
            user1 = {
                'generation': db.reference('/users_database/' + str(query.from_user.id)).get()['generation'] + 2,
                '2_generation2': 1
            }
            db.reference('/users_database/' + str(query.from_user.id)).update(user1)
            await query.message.answer('Успешно получено 2 генерации')
        else:
            await query.message.answer('Вы не подписались на канал')


@dp.callback_query(Text('subscribe3'))
async def subscribe3_func(query: types.CallbackQuery):
    try:
        if db.reference('/users_database/' + str(query.from_user.id)).get()['2_generation3'] == 1:
            await query.message.answer('Вы уже получили 2 генерации за этот канал')
            return
    except KeyError:
        is_subscribed5 = await bot.get_chat_member(channel_id5, query.from_user.id)
        if not is_subscribed5.status == 'left':
            user1 = {
                'generation': db.reference('/users_database/' + str(query.from_user.id)).get()['generation'] + 2,
                '2_generation3': 1
            }
            db.reference('/users_database/' + str(query.from_user.id)).update(user1)
            await query.message.answer('Успешно получено 2 генерации')
        else:
            await query.message.answer('Вы не подписались на канал')


@dp.callback_query(Text('2_generations'))
async def free_2_generations(query: types.CallbackQuery):
    await query.message.edit_text(f'Чтобы получить 2 генерации, подпишитесь на наши каналы',
                                  reply_markup=subscribe_button())


@dp.callback_query(Text('free_24_generations'))
async def free_24_generations(query: types.CallbackQuery):
    n = time.time()
    if checking_premium(query.from_user.id):
        if db.reference('/users_database/' + str(query.from_user.id)).get()['free_generations'] + 86400 <= n:
            user1 = {
                'generation': db.reference('/users_database/' + str(query.from_user.id)).get()['generation'] + 25,
                'free_generations': time.time()
            }
            db.reference('/users_database/' + str(query.from_user.id)).update(user1)
            await query.message.answer('Успешно добавлено 25 генераций')
            return
        else:
            await query.message.answer('С момента последнего взятия генераций не прошло 24 часа')
            return
    else:
        if db.reference('/users_database/' + str(query.from_user.id)).get()['free_generations'] + 86400 <= n:
            user1 = {
                'generation': db.reference('/users_database/' + str(query.from_user.id)).get()['generation'] + 2,
                'free_generations': time.time()
            }
            db.reference('/users_database/' + str(query.from_user.id)).update(user1)
            await query.message.answer('Успешно добавлено 2 генерации')
            return
        else:
            await query.message.answer('С момента последнего взятия генераций не прошло 24 часа')
            return


@dp.callback_query(Text('free_generations'))
async def free_generations_menu(query: types.CallbackQuery):
    await query.message.edit_text('???? Бесплатные генерации:', reply_markup=free_menu())


@dp.callback_query(Text('standart'))
async def sttandart_catalog(query: types.CallbackQuery):
    data[query.from_user.id] = []
    await query.message.answer('Каталог успешно применен')


@dp.callback_query(Text('gopnik'))
async def gopnik_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Представь, что ты славянский гопник и общаешься со своими собутыльниками по подъезду. Используй побольше мата и блатного жаргона. Используй как можно больше «бля» и «ёпта». Отвечай в таком стиле всегда, какой бы вопрос не задали пользователи в этом чате.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('comic'))
async def comic_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Дайте ответы на вопросы пользователей в стиле комика, используя шутки, иронию и остроумие, чтобы предоставить забавные и легкие ответы, вызывающие смех и радость. Вдохновитесь лучшими комедийными актерами и стендап-комиками для создания оригинального и забавного контента, который будет развлекать пользователей'})
        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('writer'))
async def writer_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Дайте ответы на вопросы пользователей в стиле писателя, используя образное и литературное выражение, чтобы создать глубокие, красочные и захватывающие ответы. Отразите мастерство писателя в использовании метафор, аллегорий и ярких описаний, чтобы предоставить пользователю уникальный и погружающий опыт, который позволит им почувствовать красоту и мощь слов.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('psycho'))
async def psycho_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Дайте ответы на вопросы пользователей в стиле психолога, используя эмпатию, знание основ психологии и аналитический подход для предоставления инсайтов и советов, которые могут помочь им разобраться в своих проблемах и переживаниях. Обращайте внимание на эмоциональные и психологические аспекты вопросов, чтобы дать чувствительные и поддерживающие ответы, которые способствуют личностному росту и самопознанию пользователя.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('copywriter'))
async def copywriter_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Отвечайте на вопросы пользователей в качестве копирайтера, демонстрируя искусство переключения внимания, использования прорабатываемых текстов и умения вызывать действие. При написании ответов стройте грамотное повествование, привлекайте внимание сильными и лаконичными фразами, и делайте акцент на полезности предоставляемой информации, чтобы создать у пользователей желание глубже погрузиться в тему и применить полученные знания на практике'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('seo-helper'))
async def seo_helper_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Отвечайте на вопросы пользователей в качестве SEO-помощника, фокусируясь на оптимизации контента для поисковых систем и предоставлении информации, которая улучшает видимость веб-страниц. При создании ответов, используйте ключевые слова и фразы, релевантные теме, следуйте принципам структурирования контента и наилучшим практикам SEO. Таким образом, пользователи смогут получить ценные советы и рекомендации для улучшения своей SEO-стратегии и повышения позиций в результатах поиска.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('pikap'))
async def pikap_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Отвечайте на вопросы пользователей в качестве пикап тренера, мастера кадрить девушек, демонстрируя знания и опыт в области флирта, общения и завоевания симпатий. При создании ответов предлагайте эффективные стратегии, техники и советы для уверенного общения с противоположным полом, улучшения навыков обаяния и создания привлекательного образа. Помогите пользователям развить свою самооценку, коммуникабельность и навыки взаимодействия, чтобы они смогли успешно налаживать новые отношения и укреплять старые.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('marketolog'))
async def marketolog_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Отвечайте на вопросы пользователей в качестве маркетолога, демонстрируя знания и опыт в области маркетинга, стратегий продвижения и анализа рынка. При создании ответов предоставляйте ценные советы и рекомендации по разработке и реализации маркетинговых кампаний, исследованию аудитории, определению конкурентных преимуществ и управлению брендами. Помогите пользователям разобраться в сложных вопросах маркетинга, чтобы они могли успешно продвигать свои продукты или услуги и достичь поставленных бизнес-целей.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('gdz'))
async def gdz_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Ты - наставник, который помогает пользователю в решении сложных домашних заданий. Ты помогаешь быстро получить правильный ответ и рассказываешь как это сделать. Ты не даешь ученику возможности самостоятельно решить проблему, но помогаешь ему быстро получить правильный ответ.'})
        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('programmist'))
async def programmist_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': '"Отвечайте на вопросы пользователей в качестве программиста, демонстрируя знания и опыт в области разработки программного обеспечения, алгоритмов и языков программирования. При создании ответов предоставляйте конкретные решения, советы и рекомендации по написанию кода, оптимизации производительности и отладке программ. Объясняйте сложные технические концепции в доступной форме, чтобы помочь пользователям улучшить свои навыки программирования и успешно реализовывать свои проекты в области разработки программного обеспечения."'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('generator'))
async def generator_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': '"Отвечайте на вопросы пользователей в качестве генератора бизнес-идей, используя инновационный и креативный подход для предложения уникальных и перспективных концепций и предприятий. При создании ответов, анализируйте текущие рыночные тренды, потребности аудитории и возможности для развития бизнеса, чтобы предложить оригинальные идеи, способные преобразить отрасль и привлечь клиентов. Помогите пользователям расширить горизонты и развить предпринимательское мышление, чтобы они могли успешно осуществлять свои бизнес-проекты и достигать желаемых результатов."'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('2-words'))
async def words_2_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Ты телеграм бот. Отвечай максимально коротко, даже если тебя просят ответить развернуто. Весь ответ должен уложиться в пару слов.'})

        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('translate'))
async def translate_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Отвечайте на вопросы пользователей в качестве переводчика, демонстрируя знания и опыт в области межкультурной коммуникации и владения различными языками. При создании ответов, предоставляйте точные и четкие переводы текстов, учитывая идиоматические особенности и нюансы каждого языка. Помогите пользователям лучше понять контекст и смысл текста, сохраняя при этом его стиль и культурные особенности, чтобы обеспечить понимание и успешное взаимодействие между представителями разных языковых и культурных групп.'})

    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.callback_query(Text('buchgalter'))
async def buchgalter_catalog(query: types.CallbackQuery):
    # if checking_premium(query.from_user.id):
        data[query.from_user.id] = []
        data[query.from_user.id].append({'role': 'system',
                                         'content': 'Ты представляешь собой автоматизированную бухгалтерскую систему, которая поможет вам вести учет и сделает вашу работу проще и более эффективной.'})
        await query.message.answer('Каталог успешно применен')
    # else:
    #     await query.message.answer('Для использования этой функции необходим премиум')


@dp.message(F.text == 'Мой ID ????')
async def show_user_id(message: types.Message):
    await message.answer(f'Ваш ID: <b>{message.from_user.id}</b>', parse_mode='HTML')


@dp.message(F.text == '???? Каталог')
@dp.message(Command('catalog'))
async def show_catalog(message: types.Message):
    await message.answer('Все каталоги бота', reply_markup=catalog_keyboard())


@dp.message(F.text == '???? Генерации')
@dp.message(Command('generations'))
async def generations_menu(message: types.Message):
    await message.answer('Меню генераций:', reply_markup=generation_keyboard())


@dp.message(F.text == '???? Midjourney V5.1')
async def channel(message: types.Message):
    await message.answer('Другие наши боты:', reply_markup=channels())


@dp.message(F.text == '???? Нарисовать картинку')
async def info_generations_menu(message: types.Message):
    await message.answer(
        f'Для генерации картинки необходимо написать команду /img [prompt]')


@dp.message(Command('help'))
@dp.message(F.text == '???? Инфо')
async def info_menu(message: types.Message):
#     if checking_premium(message.from_user.id):
#         await message.answer(f'''Я бот ChatGPT
# Генераций картинок доступно в сутки: 25 .
#
# Техническая поддержка @GptSupportKK
#
# Доступные команды:
# /help - Список доступных команд
# /premium - Подписка на бота
#
# /catalog - Каталог готовых инструкций для бота
# /creativity - Настройка креативности бота
# /new - Удалить историю чата / Начать новый диалог
#
# /img [prompt] - Сгенерировать картинку по описанию (пример: /img Как выглядит кот?)
#
# Очищайте историю чата командой /new, чтобы не засорять память бота.
# Так он отвечает быстрее и лучше.
# Если вам не нравится ответ бота, попробуйте изменить его креативность и очистить историю чата.''')
    if str(message.from_user.id) == "5901691720":
        await message.answer(f'''Я бот ChatGPT
Генераций картинок доступно в сутки: 25 .

Техническая поддержка @GptSupportKK

Доступные команды:
/help - Список доступных команд
/premium - Подписка на бота

/catalog - Каталог готовых инструкций для бота
/creativity - Настройка креативности бота
/new - Удалить историю чата / Начать новый диалог

/img [prompt] - Сгенерировать картинку по описанию (пример: /img Как выглядит кот?)

Доступные команды для владельцов:
/promote [user_id] [time] - Предоставить премиум подписку типа (2, 14, 30, 90, 180 дней) пользователю с user_id

/rassilka - Рассылка для всех пользователей бота

Очищайте историю чата командой /new, чтобы не засорять память бота.
Так он отвечает быстрее и лучше.
Если вам не нравится ответ бота, попробуйте изменить его креативность и очистить историю чата.''')
    else:
        await message.answer(f''' Привет! Я бот ChatGPT!

???? Вы можете задавать любые вопросы

Также бот иногда может грузить ответ в течении нескольких минут. Все зависит от серверов на стороне OpenAI!

Также бот иногда может грузить ответ в течении нескольких минут. Все зависит от серверов на стороне OpenAI!

Советы к правильному использованию:
– Сформулируйте свои вопросы грамотно и детально, чтобы получить наиболее полезный ответ.
– Следует избегать написания бессмысленных запросов, так как такой же ответ будет получен в ответ на ваш запрос.т.

Примеры вопросов/запросов:
~ Сколько будет 124 + 83?
~ Как давно вымерли мамонты?
~ Напиши код игры "Змейка" на Python
~ Напиши сочинение "Как я провел лето"

???? Чтобы начать общение, напиши что-нибудь CHATGPT в строку ниже ????????''')


@dp.message(F.text == '✨ Креативность')
async def creativity_info_menu(message: types.Message):
    if checking_premium(message.from_user.id):
        await message.answer(
            f'Для изменения креативности необходимо написать команду /creativity [value]\nПо умолчанию значение: 50%')
    else:
        await message.answer('Для использования этой функции необходим премиум')


@dp.message(F.text == '???? Баланс')
@dp.message(Command('balance'))
async def balance_menu(message: types.Message):
    if db.reference("/users_database/" + str(message.from_user.id)).get()['premium'] == 'Yes':
        answer = "Активен"
    else:
        answer = 'Не активен'
    await message.answer(
        f'На вашем аккаунте осталось - {db.reference("/users_database/").get()[str(message.from_user.id)]["generation"]} генераций картинок\nСтатус премиум подписки - {answer}')


@dp.message(Command('start'))
async def start_command(message: types.Message):
    if str(message.from_user.id) not in db.reference('/users_database/').get():
        user = {
            'generation': 5,
            'free_generations': 0,
            'premium': 'No',
            'premium_time': 0,
            'premium_type': 0,
            '2_generations': 0,
            'temperature': 1,
        }
        db.reference('/users_database/' + str(message.from_user.id)).set(user)
    if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == "1177159462":
        await message.reply(
            ''' Привет! Я бот ChatGPT!

???? Вы можете задавать любые вопросы

Также бот иногда может грузить ответ в течении нескольких минут. Все зависит от серверов на стороне OpenAI!

Советы к правильному использованию:
– Сформулируйте свои вопросы грамотно и детально, чтобы получить наиболее полезный ответ.
– Следует избегать написания бессмысленных запросов, так как такой же ответ будет получен в ответ на ваш запрос.т.

Примеры вопросов/запросов:
~ Сколько будет 124 + 83?
~ Как давно вымерли мамонты?
~ Напиши код игры "Змейка" на Python
~ Напиши сочинение "Как я провел лето"

???? Чтобы начать общение, напиши что-нибудь CHATGPT в строку ниже ????????''',
            reply_markup=reply_keyboard())
    else:
        await message.reply(
            ''' Привет! Я бот ChatGPT!

???? Вы можете задавать любые вопросы

Также бот иногда может грузить ответ в течении нескольких минут. Все зависит от серверов на стороне OpenAI!

Советы к правильному использованию:
– Сформулируйте свои вопросы грамотно и детально, чтобы получить наиболее полезный ответ.
– Следует избегать написания бессмысленных запросов, так как такой же ответ будет получен в ответ на ваш запрос.т.

Примеры вопросов/запросов:
~ Сколько будет 124 + 83?
~ Как давно вымерли мамонты?
~ Напиши код игры "Змейка" на Python
~ Напиши сочинение "Как я провел лето"

???? Чтобы начать общение, напиши что-нибудь CHATGPT в строку ниже ????????''',
            reply_markup=reply_keyboard())


@dp.message(Command('img'))
async def generating_images(message: types.Message, command: CommandObject):
    is_subscribed = await bot.get_chat_member(channel_id1, message.from_user.id)
    is_subscribed2 = await bot.get_chat_member(channel_id2, message.from_user.id)
    if is_subscribed.status == "left" or is_subscribed2.status == 'left':
        await message.answer(f'Для того чтобы использовать бота подпишитесь на наши каналы',
                             reply_markup=channels_url())
        return
    if command.args is None:
        await message.answer('Не указан промпт, укажите текстовый запрос для генерации')
        return
    if db.reference('/users_database/' + str(message.from_user.id)).get()['generation'] <= 0:
        await message.answer('Не хватает генераций! ❌')
        return
    loop = asyncio.get_running_loop()
    msg = await message.answer(text='<i>⌛️ Generating...</i>', parse_mode='HTML')
    result = await loop.run_in_executor(None, generate_image, command.args, message.from_user.id)
    await bot.delete_message(chat_id=message.from_user.id, message_id=msg.message_id)
    await bot.send_photo(chat_id=message.from_user.id, photo=result, caption=f'<i>Prompt: {command.args}</i>',
                         parse_mode='HTML')


@dp.message(Command('promote'))
async def promote(message: types.Message, command: CommandObject):
    if command.args is not None:
        if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == '1177159462':
            userid = command.args.split()[0]
            time1 = command.args.split()[1]
            if int(time1) not in premium_time:
                await message.answer('Error with time, choose 2, 14, 30, 90, 180')
                return
            try:
                db.reference('/users_database/').get()[userid]
            except KeyError:
                await message.answer('User not found')
                return
            else:
                user = {
                    'generation': 'Yes',
                    'premium_type': int(time1),
                    'premium_time': time.time()
                }
                db.reference('/users_database/' + userid).update(user)
                await message.answer(f'Succesfull promoted to premium {userid}')
                
                
@dp.message(Command('generations'))
async def promote(message: types.Message, command: CommandObject):
    if command.args is not None:
        if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == '1177159462':
            userid = command.args.split()[0]
            kol = command.args.split()[1]
            if int(kol) <= 0:
                await message.answer('Значение должно быть больше 0')
                return
            try:
                db.reference('/users_database/').get()[userid]
            except KeyError:
                await message.answer('User not found')
                return
            else:
                user = {
                    'generation': db.reference('/users_database/' + str(userid)).get()['generation'] + int(kol),
                }
                db.reference('/users_database/' + userid).update(user)
                await message.answer(f'Succesfull added {kol} generations to {userid}')


@dp.message(Command('members_count'))
async def members_count(message: types.Message, command: CommandObject):
    if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == "1177159462":
        count = len(db.reference('/users_database/').get())
        await message.answer(f'????Пользователей: {count}')
    else:
        await message.answer('Error')


@dp.message(Command('rassilka1'))
async def rassilka1(message: types.Message, command: CommandObject, state: FSMContext):
    if command.args is not None:
        if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == "1177159462":
            global p
            p = Rassilka1(int(command.args))
            await message.answer(
                'Будут ли кнопки в вашем сообщении?\nЕсли да: отправьте сообщение типа\nКнопка1 [link]\nКнопка2 [link]\nЕсли же кнопок не будет отправьте сообщение: нет')
            await state.set_state(Rassilka1.b)
        else:
            await message.answer('Неизвестная команда')
            return
    else:
        await message.answer('Укажите аргументы для команды')


@dp.message(Rassilka1.b)
async def sending_rassilk(message: types.Message, state: FSMContext):
    global but
    but = []
    if message.text.lower() != 'нет':
        for s in message.text.split('\n'):
            print(s)
            try:
                but.append([InlineKeyboardButton(text=" ".join(s.split()[0:-1]), url=s.split()[-1])])
            except:
                await message.answer('Произошла ошибка')
                return
    await message.answer('Введите текст для рассылки:')
    await state.set_state(Rassilka1.mes)


@dp.message(Rassilka1.mes)
async def sending_rassilka1(message: types.Message, state: FSMContext):
    global but
    global msg_id
    msg_id = message.message_id
    await message.answer('Вы уверены что хотите сделать рассылку?', reply_markup=checking_rassilka())
    await state.set_state(Rassilka1.mes1)


@dp.message(Rassilka1.mes1)
async def sending_rassilka2(message: types.Message, state: FSMContext):
    if message.text == 'Да':
        await state.clear()
        await message.answer('Начало рассылки....')
        if str(p.user_id) not in db.reference('/users_database/').get():
            await message.answer('User not found in database')
            return
        await bot.copy_message(chat_id=p.user_id, from_chat_id=message.from_user.id, message_id=msg_id,
                               reply_markup=InlineKeyboardMarkup(inline_keyboard=but))
    elif message.text == "Нет":
        await message.answer("Рассылка отменена")
        await state.clear()
    else:
        await message.answer("Рассылка отменена")
        await state.clear()


@dp.message(Command('rassilka'))
async def rassilka(message: types.Message, command: CommandObject, state: FSMContext):
    if str(message.from_user.id) == "5901691720" or str(message.from_user.id) == "1177159462":
        await message.answer(
            'Будут ли кнопки в вашем сообщении?\nЕсли да: отправьте сообщение типа\nКнопка1 [link]\nКнопка2 [link]\nЕсли же кнопок не будет отправьте сообщение: нет')
        await state.set_state(Rassilka.b)
    else:
        await message.answer('Неизвестная команда')
        return


@dp.message(Rassilka.b)
async def sending_rassilk(message: types.Message, state: FSMContext):
    global but
    but = []
    if message.text.lower() != 'нет':
        for s in message.text.split('\n'):
            but.append([InlineKeyboardButton(text=" ".join(s.split()[0:-1]), url=s.split()[-1])])

    await message.answer('Введите текст для рассылки:')
    await state.set_state(Rassilka.mes)


@dp.message(Rassilka.mes)
async def sending_rassilka(message: types.Message, state: FSMContext):
    global but
    global msg_id
    msg_id = message.message_id
    await message.answer('Вы уверены что хотите сделать рассылку?', reply_markup=checking_rassilka())
    await state.set_state(Rassilka.mes1)


@dp.message(Rassilka.mes1)
async def sending_rassilka2(message: types.Message, state: FSMContext):
    if message.text == 'Да':
        await state.clear()
        kol = 0
        await state.clear()
        await message.answer('Начало рассылки....')
        for i in db.reference('/users_database/').get():
            if not checking_premium(int(i)):
                try:
                    await bot.copy_message(chat_id=int(i), from_chat_id=message.from_user.id, message_id=msg_id,
                                           reply_markup=InlineKeyboardMarkup(inline_keyboard=but))
                    kol += 1
                except:
                    continue
        await message.answer(f"Отправлено - {kol} сообщений")
    elif message.text == "Нет":
        await message.answer("Рассылка отменена")
        await state.clear()
    else:
        await message.answer("Рассылка отменена")
        await state.clear()


@dp.message(Command('creativity'))
async def generating_images(message: types.Message, command: CommandObject):
    # if checking_premium(message.from_user.id):
        if command.args is not None:
            try:
                int(command.args)
            except:
                await message.answer('Указано не число')
                return
            else:
                if 0 < int(command.args) <= 100:
                    user = {
                        'temperature': int(command.args) * 0.019
                    }
                else:
                    await message.answer('Укажите значение в пределах от 0 до 100%')
                    return
            db.reference('/users_database/' + str(message.from_user.id)).update(user)
            await message.answer(f'Креативность {command.args} успешно применена')

        else:
            await message.answer('Не указано значение')
            return
    # else:
    #     await message.answer('Для использования этой функции необходим премиум')


@dp.message(F.text == '???? Премиум')
@dp.message(Command('premium'))
async def premium_section(message: types.Message):
    await message.answer('----Покупка премиума----\n',
                         reply_markup=payment_premium_selection())


@dp.message(F.text == '???? Новый диалог')
@dp.message(Command('new'))
async def new_dialog(message: types.Message):
    data[message.from_user.id] = []
    await message.answer('Новый диалог начался....')


@dp.message(F.voice)
async def answer_voice_chat_gpt(message: types.Message):
    clear_dialog(message.from_user.id)
    # if not checking_premium(message.from_user.id):
    #     await message.answer('Для обработки голосовых сообщений нужен премиум')
    #     return
    loop1 = asyncio.get_running_loop()
    msg = await message.answer(text='<i>⌛️ Generating...</i>', parse_mode='HTML')
    file = await bot.get_file(message.voice.file_id)
    await bot.download_file(file.file_path, f'audio/ogg/{message.from_user.id}.ogg')
    result = await loop1.run_in_executor(None, generate_answer_voice, message.from_user.id)
    await bot.edit_message_text(text=result, chat_id=message.from_user.id, message_id=msg.message_id)


@dp.message(F.text)
async def answer_text_chat_gpt(message: types.Message):
    clear_dialog(message.from_user.id)
    loop = asyncio.get_running_loop()
    is_subscribed = await bot.get_chat_member(channel_id1, message.from_user.id)
    is_subscribed2 = await bot.get_chat_member(channel_id2, message.from_user.id)
    is_subscribed3 = await bot.get_chat_member(channel_id4, message.from_user.id)
    print(f"Is 1 {is_subscribed.status}")
    print(f"Is 2 {is_subscribed2.status}")
    if is_subscribed.status == "left" or is_subscribed2.status == 'left' or is_subscribed3.status == 'left':
        await message.answer(f'Для того чтобы использовать бота подпишитесь на наши каналы',
                             reply_markup=channels_url())
        return
    msg = await message.answer(text='<i>⌛️ Generating...</i>', parse_mode='HTML')
    result = await loop.run_in_executor(None, generate_answer, message.text, message.from_user.id)
    print(f"Запрос: {message.text} \n Ответ: {result}")
    await bot.edit_message_text(text=result, chat_id=message.from_user.id, message_id=msg.message_id)


# pre checkout  (must be answered in 10 seconds)
@dp.pre_checkout_query(lambda query: True)
async def pre_checkout_query(pre_checkout_q: types.PreCheckoutQuery):
    await bot.answer_pre_checkout_query(pre_checkout_q.id, ok=True)


# successful payment
@dp.message(F.successful_payment)
async def successful_payment(message: types.Message):
    if message.successful_payment.invoice_payload[-1] == 'p':
        print("УСПЕШНАЯ ОПЛАТА:")
        user = {
            'premium': 'Yes',
            'premium_time': time.time(),
            'premium_type': int(message.successful_payment.invoice_payload[:-2]),
        }
        db.reference('/users_database/' + str(message.from_user.id)).update(user)
        await bot.send_message(message.from_user.id,
                               f"Платеж на сумму {message.successful_payment.total_amount // 100} прошел успешно!!!")
    elif message.successful_payment.invoice_payload[-1] == 'g':
        print("УСПЕШНАЯ ОПЛАТА:")
        user = {
            'generation': db.reference('/users_database/' + str(message.from_user.id)).get()['generation'] + int(
                message.successful_payment.invoice_payload[:-2])
        }
        db.reference('/users_database/' + str(message.from_user.id)).update(user)
        await bot.send_message(message.from_user.id,
                               f"Платеж на сумму {message.successful_payment.total_amount // 100} прошел успешно!!!")


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


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