from __future__ import annotations

from aiogram import Bot, F, Router
from aiogram.client.default import DefaultBotProperties
from aiogram.enums import ParseMode
from aiogram.filters import Command
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
from sqlalchemy import select

from app import reseller_runtime
from app.common import money
from app.db import get_session
from app.models import ResellerBot
from app.reseller_common import MIN_PAYOUT, RESELLER_SHARE
from app.states import ResellerCreate

router = Router()

_INTRO = (
    "<b>Create your own shop bot</b>\n\n"
    "You get a real separate Telegram bot with products from our main stock.\n"
    "You set a percent markup yourself. Example: our price is $1, your markup is 20%, "
    "your buyer pays $1.20.\n\n"
    f"You receive <b>{int(RESELLER_SHARE * 100)}%</b> of the markup. "
    f"Payout is available from <b>{money(MIN_PAYOUT)}$</b> via CryptoBot.\n\n"
    "First send the Telegram ID of the admin who will manage this bot."
)


@router.message(F.text == "Create your own bot")
@router.message(Command("create_bot"))
async def create_reseller_start(message: Message, state: FSMContext) -> None:
    await state.clear()
    await state.set_state(ResellerCreate.admin_id)
    await message.answer(_INTRO)


@router.message(ResellerCreate.admin_id)
async def create_reseller_admin_id(message: Message, state: FSMContext) -> None:
    raw = (message.text or "").strip()
    if not raw.isdigit():
        await message.answer("Send the admin Telegram ID as digits only.")
        return
    await state.update_data(admin_user_id=int(raw))
    await state.set_state(ResellerCreate.token)
    await message.answer(
        "Now send the bot token from @BotFather.\n\n"
        "The token is needed so the system can launch your separate shop bot."
    )


@router.message(ResellerCreate.token)
async def create_reseller_token(message: Message, state: FSMContext) -> None:
    token = (message.text or "").strip()
    if ":" not in token or len(token) < 30:
        await message.answer("This does not look like a bot token. Try again.")
        return

    test_bot = Bot(
        token=token,
        default=DefaultBotProperties(parse_mode=ParseMode.HTML),
    )
    try:
        me = await test_bot.get_me()
        await test_bot.delete_webhook(drop_pending_updates=True)
    except Exception as exc:
        await test_bot.session.close()
        await message.answer(
            "I could not connect to this bot token. Check it in @BotFather and send again.\n"
            f"<code>{exc}</code>"
        )
        return
    await test_bot.session.close()

    data = await state.get_data()
    admin_user_id = int(data["admin_user_id"])
    async with get_session() as session:
        existing = (
            await session.execute(
                select(ResellerBot).where(ResellerBot.bot_username == (me.username or ""))
            )
        ).scalar_one_or_none()
        if existing is not None:
            await state.clear()
            await message.answer("This bot is already connected.")
            return
        reseller = ResellerBot(
            owner_user_id=message.from_user.id,
            admin_user_id=admin_user_id,
            bot_token=token,
            bot_username=me.username or "",
        )
        session.add(reseller)
        await session.commit()
        reseller_id = reseller.id

    await reseller_runtime.start_reseller_bot(reseller_id)
    await state.clear()
    username = f"@{me.username}" if me.username else "your bot"
    await message.answer(
        f"Done. Your reseller bot is running: <b>{username}</b>\n\n"
        "Open it, press Start, then use its admin panel to set markup, channel, "
        "product images, broadcasts and payouts."
    )
