import asyncio

from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart
from aiogram.types import (
    Message,
    ReplyKeyboardMarkup,
    KeyboardButton
)
from aiogram.client.session.aiohttp import AiohttpSession

from database import (
    add_user,
    add_balance,
    get_balance,
    accept_rules,
    check_rules
)

from config import BOT_TOKEN, ADMIN_ID


# ==============================
# Proxy
# ==============================

PROXY = "http://127.0.0.1:12334"

session = AiohttpSession(
    proxy=PROXY
)


bot = Bot(
    token=BOT_TOKEN,
    session=session
)


dp = Dispatcher()



# ==============================
# Keyboards
# ==============================

main_keyboard = ReplyKeyboardMarkup(
    keyboard=[
        [
            KeyboardButton(text="🎬 Send Video"),
            KeyboardButton(text="📁 My Videos")
        ],
        [
            KeyboardButton(text="💰 Wallet"),
            KeyboardButton(text="💳 Wallet Address")
        ]
    ],
    resize_keyboard=True
)



rules_keyboard = ReplyKeyboardMarkup(
    keyboard=[
        [
            KeyboardButton(
                text="✅ I Agree"
            )
        ]
    ],
    resize_keyboard=True
)



# ==============================
# User State
# ==============================

waiting_for_video = set()
waiting_for_wallet = set()



# ==============================
# Start
# ==============================

@dp.message(CommandStart())
async def start(message: Message):

    add_user(
        message.from_user.id,
        message.from_user.username
    )


    if not check_rules(message.from_user.id):

        await message.answer(
            """
📜 Bot Rules

1️⃣ Upload only jerking off your own content.

2️⃣ The video must show the date of the same day somewhere in the video; otherwise, the video will not be approved (2020 February 28).

3️⃣ The video must not be shorter than 1 minute or longer than 3 minutes. Videos outside this duration will not be approved.

4️⃣ Fake information may result in account restriction.

5️⃣ Wallet information must be correct. Only TON (GRAM) wallet addresses are accepted.

6️⃣ By using this bot you agree to these terms.

Please accept the rules to continue.
""",
            reply_markup=rules_keyboard
        )

        return



    await message.answer(
        "Welcome back 👋\n\nChoose an option:",
        reply_markup=main_keyboard
    )



# ==============================
# Accept Rules
# ==============================

@dp.message(F.text == "✅ I Agree")
async def agree_rules(message: Message):

    accept_rules(
        message.from_user.id
    )


    await message.answer(
        "✅ Rules accepted.\n\nWelcome!",
        reply_markup=main_keyboard
    )



# ==============================
# Send Video
# ==============================

@dp.message(F.text == "🎬 Send Video")
async def send_video_button(message: Message):

    if not check_rules(message.from_user.id):

        await message.answer(
            "Please accept rules first.",
            reply_markup=rules_keyboard
        )
        return


    waiting_for_video.add(
        message.from_user.id
    )


    await message.answer(
        "Please send your video 🎥"
    )



# ==============================
# Receive Video / File
# ==============================

@dp.message(F.video | F.document)
async def receive_video(message: Message):

    user_id = message.from_user.id


    if not check_rules(user_id):

        await message.answer(
            "Please accept rules first.",
            reply_markup=rules_keyboard
        )
        return



    if user_id not in waiting_for_video:

        await message.answer(
            "Please click 🎬 Send Video first.",
            reply_markup=main_keyboard
        )
        return



    waiting_for_video.remove(user_id)


    username = (
        f"@{message.from_user.username}"
        if message.from_user.username
        else "No username"
    )


    try:

        await bot.send_message(
            ADMIN_ID,
            f"""
🎥 New Video Received

🆔 User ID:
{user_id}

📛 Username:
{username}
"""
        )


        if message.video:

            await bot.send_video(
                ADMIN_ID,
                message.video.file_id
            )


        elif message.document:

            await bot.send_document(
                ADMIN_ID,
                message.document.file_id
            )



        await message.answer(
            "✅ Your video has been received.",
            reply_markup=main_keyboard
        )


    except Exception as e:

        print("UPLOAD ERROR:", e)

# ==============================
# Admin Add Balance
# ==============================

@dp.message(F.text.startswith("/addwallet"))
async def add_wallet(message: Message):

    if message.from_user.id != ADMIN_ID:
        await message.answer("❌ Not allowed")
        return


    try:

        data = message.text.split()


        if len(data) != 3:
            raise Exception()


        user_id = int(data[1])
        amount = float(data[2])


        add_user(
            user_id,
            None
        )


        add_balance(
            user_id,
            amount
        )


        await message.answer(
            f"""
✅ Balance Added

👤 User:
{user_id}

💰 Amount:
${amount}
"""
        )


        await bot.send_message(
            user_id,
            f"""
💰 Your wallet has been updated.

Added:
${amount}

Thank you.
"""
        )


    except Exception as e:

        print("ADD WALLET ERROR:", e)

        await message.answer(
            """
❌ Wrong format

Use:

/addwallet USER_ID AMOUNT

Example:

/addwallet 123456789 10
"""
        )

# ==============================
# Wallet
# ==============================

@dp.message(F.text == "💰 Wallet")
async def wallet(message: Message):

    if not check_rules(message.from_user.id):
        return


    balance = get_balance(
        message.from_user.id
    )


    await message.answer(
        f"""
💰 Wallet

Balance: ${balance}
""",
        reply_markup=main_keyboard
    )



# ==============================
# Wallet Address
# ==============================

@dp.message(F.text == "💳 Wallet Address")
async def wallet_address_button(message: Message):

    if not check_rules(message.from_user.id):
        return


    waiting_for_wallet.add(
        message.from_user.id
    )


    await message.answer(
        "Please send your wallet address 💳"
    )



@dp.message(F.text)
async def receive_wallet_address(message: Message):

    user_id = message.from_user.id


    if user_id not in waiting_for_wallet:
        return


    waiting_for_wallet.remove(user_id)


    username = (
        f"@{message.from_user.username}"
        if message.from_user.username
        else "No username"
    )


    await bot.send_message(
        ADMIN_ID,
        f"""
💳 New Wallet Address

🆔 User ID:
{user_id}

📛 Username:
{username}

💰 Wallet Address:

{message.text}
"""
    )


    await message.answer(
        "✅ Wallet address received.",
        reply_markup=main_keyboard
    )



# ==============================
# Admin Add Balance
# ==============================

@dp.message(F.text.startswith("/addwallet"))
async def add_wallet(message: Message):

    if message.from_user.id != ADMIN_ID:
        return


    try:

        data = message.text.split()

        user_id = int(data[1])
        amount = float(data[2])


        add_balance(
            user_id,
            amount
        )


        await message.answer(
            f"✅ Added ${amount} to user {user_id}"
        )


    except:

        await message.answer(
            "Format:\n/addwallet USER_ID AMOUNT"
        )



# ==============================
# My Videos
# ==============================

@dp.message(F.text == "📁 My Videos")
async def my_videos(message: Message):

    await message.answer(
        "📁 Your videos\n\nNo videos found yet.",
        reply_markup=main_keyboard
    )



# ==============================
# Other
# ==============================

@dp.message()
async def other(message: Message):

    await message.answer(
        "Please choose an option.",
        reply_markup=main_keyboard
    )



# ==============================
# Run
# ==============================

async def main():

    print("🤖 Bot Started...")

    await dp.start_polling(bot)



if __name__ == "__main__":
    asyncio.run(main())