"""Extra tools — dice, coinflip, random number, choose, QR code, and more."""
from __future__ import annotations

import logging
import random
from typing import Optional

from telegram import Update
from telegram.constants import ParseMode
from telegram.ext import ContextTypes

from bot.persian_router import register_mixed

logger = logging.getLogger(__name__)


async def dice_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Roll a dice (1-6) or custom N-sided."""
    text = (update.message.text or "").split()
    if len(text) >= 2:
        try:
            sides = int(text[1])
            if sides < 1:
                raise ValueError
            result = random.randint(1, sides)
            await update.message.reply_text(f"🎲 تاس {sides} وجهی: <b>{result}</b>", parse_mode=ParseMode.HTML)
        except (ValueError, TypeError):
            await update.message.reply_text("❌ عدد معتبر وارد کنید.")
    else:
        result = random.randint(1, 6)
        await update.message.reply_text(f"🎲 تاس: <b>{result}</b>", parse_mode=ParseMode.HTML)


async def coinflip_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Flip a coin."""
    result = random.choice(["شیر 🦁", "خط 🇮🇷"])
    await update.message.reply_text(f"🪙 سکه:\n<b>{result}</b>", parse_mode=ParseMode.HTML)


async def random_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Random number between two values."""
    text = (update.message.text or "").split()
    if len(text) >= 3:
        try:
            a, b = int(text[1]), int(text[2])
            if a > b:
                a, b = b, a
            result = random.randint(a, b)
            await update.message.reply_text(
                f"🔢 عدد تصادفی بین <b>{a}</b> و <b>{b}</b>: <code>{result}</code>",
                parse_mode=ParseMode.HTML,
            )
        except (ValueError, TypeError):
            await update.message.reply_text("❌ دو عدد معتبر وارد کنید.")
    else:
        await update.message.reply_text(
            "🎲 <b>عدد تصادفی</b>\n\n"
            "استفاده: <code>random 1 100</code>\n"
            "فارسی: <code>عدد تصادفی 1 100</code>",
            parse_mode=ParseMode.HTML,
        )


async def choose_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Choose randomly between given options."""
    text = (update.message.text or "").split(maxsplit=1)
    if len(text) >= 2:
        options = [o.strip() for o in text[1].split("|") if o.strip()]
        if len(options) >= 2:
            chosen = random.choice(options)
            await update.message.reply_text(
                f"🤔 <b>انتخاب:</b>\n\n{chr(10).join(f'• {o}' for o in options)}\n\n"
                f"✅ من <b>«{chosen}»</b> رو انتخاب می‌کنم!",
                parse_mode=ParseMode.HTML,
            )
        else:
            await update.message.reply_text("❌ حداقل ۲ گزینه با | جدا کنید.\nمثال: <code>choose پیتزا | کباب | سالاد</code>", parse_mode=ParseMode.HTML)
    else:
        await update.message.reply_text(
            "❓ <b>انتخاب تصادفی</b>\n\n"
            "استفاده: <code>choose گزینه۱ | گزینه۲ | گزینه۳</code>\n"
            "فارسی: <code>انتخاب برگر | پیتزا | سوشی</code>",
            parse_mode=ParseMode.HTML,
        )


async def color_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Show a random color."""
    colors = [
        ("قرمز", "🔴"), ("آبی", "🔵"), ("سبز", "🟢"), ("زرد", "🟡"),
        ("نارنجی", "🟠"), ("بنفش", "🟣"), ("قهوه‌ای", "🟤"), ("سفید", "⚪"),
        ("سیاه", "⚫"), ("صورتی", "🩷"), ("خاکستری", "🔘"), ("فیروزه‌ای", "🩵"),
    ]
    name, emoji = random.choice(colors)
    await update.message.reply_text(f"{emoji} رنگ تصادفی: <b>{name}</b>", parse_mode=ParseMode.HTML)


async def lucky_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Show today's lucky number and color."""
    import time
    seed = int(time.time() / 86400)
    rng = random.Random(seed)
    lucky_num = rng.randint(1, 99)
    lucky_color = rng.choice(["قرمز 🔴", "آبی 🔵", "سبز 🟢", "طلایی 🏆", "بنفش 🟣"])
    await update.message.reply_text(
        f"🍀 <b>شانس امروز شما</b>\n\n"
        f"🔢 عدد شانس: <code>{lucky_num}</code>\n"
        f"🎨 رنگ شانس: {lucky_color}\n\n"
        f"✨ روز خوبی داشته باشی!",
        parse_mode=ParseMode.HTML,
    )


async def id_generator_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Generate a random ID."""
    text = (update.message.text or "").split()
    length = 8
    if len(text) >= 2:
        try:
            length = max(4, min(64, int(text[1])))
        except (ValueError, TypeError):
            pass
    import secrets
    chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    rid = "".join(secrets.choice(chars) for _ in range(length))
    await update.message.reply_text(
        f"🆔 <b>شناسه تصادفی</b> ({length} کاراکتر):\n<code>{rid}</code>",
        parse_mode=ParseMode.HTML,
    )


async def password_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Generate a strong random password."""
    text = (update.message.text or "").split()
    length = 16
    if len(text) >= 2:
        try:
            length = max(8, min(64, int(text[1])))
        except (ValueError, TypeError):
            pass
    import secrets
    chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*"
    pw = "".join(secrets.choice(chars) for _ in range(length))
    await update.message.reply_text(
        f"🔑 <b>رمز عبور تصادفی</b> ({length} کاراکتر):\n"
        f"<code>{pw}</code>\n\n"
        f"⚠️ این رمز فقط یکبار نمایش داده می‌شود!",
        parse_mode=ParseMode.HTML,
    )


async def uuid_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Generate a UUID v4."""
    import uuid
    u = uuid.uuid4()
    await update.message.reply_text(
        f"🆔 <b>UUID:</b>\n<code>{u}</code>",
        parse_mode=ParseMode.HTML,
    )


async def countdown_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Countdown from a number."""
    text = (update.message.text or "").split()
    if len(text) >= 2:
        try:
            n = int(text[1])
            if n < 1 or n > 100:
                await update.message.reply_text("❌ عدد بین ۱ تا ۱۰۰ وارد کنید.")
                return
            nums = " ".join(str(i) for i in range(n, 0, -1))
            await update.message.reply_text(f"⏳ شمارش معکوس از {n}:\n{nums}\n🚀 بریم!", parse_mode=ParseMode.HTML)
        except (ValueError, TypeError):
            await update.message.reply_text("❌ عدد معتبر وارد کنید.")
    else:
        await update.message.reply_text("🔢 <b>شمارش معکوس</b>\nاستفاده: <code>countdown 10</code>", parse_mode=ParseMode.HTML)


async def len_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Count characters in replied text."""
    msg = update.message
    if not msg:
        return
    target = msg.reply_to_message
    if not target or not (target.text or target.caption):
        await msg.reply_text("❌ روی یک متن ریپلای کنید.")
        return
    text = target.text or target.caption or ""
    await msg.reply_text(
        f"📏 <b>طول متن:</b> {len(text)} کاراکتر\n"
        f"📝 <b>تعداد کلمات:</b> {len(text.split())}\n"
        f"🔤 <b>بدون فاصله:</b> {len(text.replace(' ', ''))}",
        parse_mode=ParseMode.HTML,
    )


async def reverse_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Reverse text or replied message."""
    msg = update.message
    text = (msg.text or "").split(maxsplit=1)
    content = ""
    if len(text) >= 2:
        content = text[1]
    elif msg.reply_to_message:
        content = msg.reply_to_message.text or msg.reply_to_message.caption or ""
    if not content:
        await msg.reply_text("❌ متن را بنویسید یا روی پیام ریپلای کنید.\n<code>reverse متن</code>", parse_mode=ParseMode.HTML)
        return
    reversed_text = content[::-1]
    await msg.reply_text(
        f"🔄 <b>برعکس:</b>\n{reversed_text}",
        parse_mode=ParseMode.HTML,
    )


async def qr_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Generate a QR code from text."""
    text = (update.message.text or "").split(maxsplit=1)
    content = ""
    if len(text) >= 2:
        content = text[1]
    elif update.message.reply_to_message:
        content = update.message.reply_to_message.text or ""
    if not content:
        await update.message.reply_text(
            "📱 <b>ساخت QR کد</b>\n\n"
            "استفاده: <code>qr https://example.com</code>\n"
            "فارسی: <code>کیوآر متن من</code>",
            parse_mode=ParseMode.HTML,
        )
        return
    try:
        import qrcode
        from io import BytesIO
        img = qrcode.make(content)
        bio = BytesIO()
        img.save(bio, "PNG")
        bio.seek(0)
        await update.message.reply_photo(
            photo=bio,
            caption=f"📱 QR کد:\n{content[:100]}{'...' if len(content) > 100 else ''}",
        )
    except Exception as e:
        logger.error("QR generation error: %s", e)
        await update.message.reply_text("⚠️ خطا در ساخت QR کد.")


async def time_calc_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Calculate time difference."""
    from bot.helpers import parse_time, format_time
    text = (update.message.text or "").split(maxsplit=2)
    if len(text) >= 3:
        try:
            seconds = int(text[1])
            unit = text[2]
            multipliers = {"ثانیه": 1, "دقیقه": 60, "ساعت": 3600, "روز": 86400, "هفته": 604800}
            mult = multipliers.get(unit, None)
            if mult:
                result = seconds * mult
                await update.message.reply_text(
                    f"⏱ <b>محاسبه زمان:</b>\n{seconds} {unit} = <code>{result}</code> ثانیه",
                    parse_mode=ParseMode.HTML,
                )
            else:
                await update.message.reply_text("❌ واحد نامعتبر. یکی از: ثانیه, دقیقه, ساعت, روز, هفته")
        except (ValueError, TypeError):
            await update.message.reply_text("❌ عدد معتبر وارد کنید.")
    else:
        await update.message.reply_text(
            "⏱ <b>محاسبه زمان</b>\nمثال: <code>timecalc 2 ساعت</code>\nفارسی: <code>محاسبه زمان 3 روز</code>",
            parse_mode=ParseMode.HTML,
        )


def register(app) -> None:
    register_mixed(
        app,
        {
            "dice": dice_cmd,
            "coinflip": coinflip_cmd,
            "flip": coinflip_cmd,
            "random": random_cmd,
            "choose": choose_cmd,
            "color": color_cmd,
            "luck": lucky_cmd,
            "lucky": lucky_cmd,
            "id": id_generator_cmd,
            "generateid": id_generator_cmd,
            "password": password_cmd,
            "genpassword": password_cmd,
            "uuid": uuid_cmd,
            "countdown": countdown_cmd,
            "len": len_cmd,
            "strlen": len_cmd,
            "reverse": reverse_cmd,
            "qr": qr_cmd,
            "qrcode": qr_cmd,
            "timecalc": time_calc_cmd,
        },
        {
            "تاس": dice_cmd,
            "تاس انداختن": dice_cmd,
            "تاس بنداز": dice_cmd,
            "بینداز تاس": dice_cmd,
            "سکه": coinflip_cmd,
            "سکه بنداز": coinflip_cmd,
            "شیر یا خط": coinflip_cmd,
            "بنداز سکه": coinflip_cmd,
            "عدد تصادفی": random_cmd,
            "عدد رندوم": random_cmd,
            "یک عدد بده": random_cmd,
            "انتخاب": choose_cmd,
            "انتخاب کن": choose_cmd,
            "بین اینا": choose_cmd,
            "یکی رو انتخاب کن": choose_cmd,
            "رنگ": color_cmd,
            "رنگ تصادفی": color_cmd,
            "یک رنگ بده": color_cmd,
            "شانس": lucky_cmd,
            "شانس امروز": lucky_cmd,
            "بخت": lucky_cmd,
            "شانس من": lucky_cmd,
            "شناسه": id_generator_cmd,
            "ساخت شناسه": id_generator_cmd,
            "شناسه بساز": id_generator_cmd,
            "رمز": password_cmd,
            "رمز تصادفی": password_cmd,
            "ساخت رمز": password_cmd,
            "رمز بساز": password_cmd,
            "پسورد": password_cmd,
            "شمارش معکوس": countdown_cmd,
            "شمارش معکوس کن": countdown_cmd,
            "کاانت داون": countdown_cmd,
            "طول متن": len_cmd,
            "اندازه متن": len_cmd,
            "تعداد کاراکتر": len_cmd,
            "برعکس": reverse_cmd,
            "برعکس کن": reverse_cmd,
            "وارونه": reverse_cmd,
            "کیوآر": qr_cmd,
            "کیو آر": qr_cmd,
            "کیو آر کد": qr_cmd,
            "کیوآر کد": qr_cmd,
            "qr": qr_cmd,
            "qrcode": qr_cmd,
            "محاسبه زمان": time_calc_cmd,
            "محاسبه تاریخ": time_calc_cmd,
            "زمان": time_calc_cmd,
        },
    )
