"""Moderation handler — comprehensive admin commands: ban/mute/kick/warn/pin/del/purge/gban/admin/title/lock."""
from __future__ import annotations

import asyncio
import json
import logging
import time

from telegram import ChatPermissions, Update
from telegram.constants import ParseMode
from telegram.error import BadRequest, Forbidden
from telegram.ext import CommandHandler, ContextTypes

from bot import db
from bot.config import OWNER_ID, DEFAULT_WARN_LIMIT, DEFAULT_WARN_MODE
from bot.decorators import admin_only, sudo_only, owner_only, bot_can_restrict, bot_can_delete, bot_can_pin
from bot.helpers import resolve_target, parse_time, format_time, user_link, is_chat_admin, timestamp_now
from bot.constants import E, MSG, LOCK_TYPES
from bot.persian_router import register_mixed

logger = logging.getLogger(__name__)


# ───────────────────────── Helper ─────────────────────────
MUTED_PERMS = ChatPermissions(
    can_send_messages=False, can_send_audios=False, can_send_documents=False,
    can_send_photos=False, can_send_videos=False, can_send_video_notes=False,
    can_send_voice_notes=False, can_send_polls=False, can_send_other_messages=False,
    can_add_web_page_previews=False, can_change_info=False, can_invite_users=False,
    can_pin_messages=False, can_manage_topics=False,
)
UNMUTED_PERMS = ChatPermissions(
    can_send_messages=True, can_send_audios=True, can_send_documents=True,
    can_send_photos=True, can_send_videos=True, can_send_video_notes=True,
    can_send_voice_notes=True, can_send_polls=True, can_send_other_messages=True,
    can_add_web_page_previews=True, can_change_info=False, can_invite_users=True,
    can_pin_messages=False, can_manage_topics=False,
)

PROMOTE_KEY = "promote_list"

LOCK_ALIASES = {
    "photo": "photo", "عکس": "photo",
    "video": "video", "فیلم": "video",
    "voice": "voice", "ویس": "voice",
    "videonote": "videonote",
    "audio": "audio", "آهنگ": "audio", "موزیک": "audio",
    "document": "document", "فایل": "document",
    "sticker": "sticker", "استیکر": "sticker",
    "gif": "gif", "گیف": "gif",
    "contact": "contact", "مخاطب": "contact",
    "location": "location", "مکان": "location",
    "game": "game", "بازی": "game",
    "poll": "poll", "نظرسنجی": "poll",
    "link": "link", "لینک": "link",
    "forward": "forward", "فوروارد": "forward",
    "mention": "mention", "منشن": "mention",
    "command": "command", "دستور": "command",
    "webpage": "webpage", "پیش‌نمایش": "webpage",
    "bot": "bot", "ربات": "bot",
    "media": "media", "رسانه": "media",
    "text": "text", "متن": "text",
    "emoji": "emoji", "ایموجی": "emoji",
    "english": "english", "انگلیسی": "english",
    "persian": "persian", "فارسی": "persian",
    "arabic": "arabic", "عربی": "arabic",
    "rtl": "rtl",
}


async def _can_act(bot, chat_id: int, user_id: int) -> bool:
    if await db.is_sudo(user_id) or user_id == OWNER_ID:
        return False
    if await db.vip_check(chat_id, user_id):
        return False
    if user_id == bot.id:
        return False
    try:
        member = await bot.get_chat_member(chat_id, user_id)
        if member.status in ("administrator", "creator"):
            return False
    except BadRequest:
        pass
    return True


async def _ban_user(bot, chat_id: int, user_id: int, until_date: int | None = None, reason: str = "") -> None:
    if until_date:
        await bot.ban_chat_member(chat_id, user_id, until_date=until_date)
    else:
        await bot.ban_chat_member(chat_id, user_id)
    await db.blocklist_add(chat_id, user_id, "ban")


async def _extract_target_and_reason(bot, message) -> tuple[int | None, str]:
    if message.reply_to_message and message.reply_to_message.from_user:
        target = message.reply_to_message.from_user.id
        parts = (message.text or "").split(maxsplit=1)
        reason = parts[1] if len(parts) > 1 else ""
        return target, reason.strip()
    args = (message.text or "").split()
    if len(args) < 2:
        return None, ""
    for i, arg in enumerate(args[1:], 1):
        arg = arg.strip()
        if arg.startswith("@"):
            try:
                chat = await bot.get_chat(arg)
                target = chat.id
                reason = " ".join(args[i+1:]).strip()
                return target, reason
            except BadRequest:
                continue
        elif arg.lstrip("-").isdigit():
            target = int(arg)
            reason = " ".join(args[i+1:]).strip()
            return target, reason
    return None, ""


async def _is_promoted(chat_id: int, user_id: int) -> bool:
    raw = await db.get_setting(chat_id, PROMOTE_KEY, default="[]")
    try:
        lst = json.loads(raw)
    except (json.JSONDecodeError, TypeError):
        lst = []
    return user_id in lst


async def _add_promoted(chat_id: int, user_id: int) -> None:
    raw = await db.get_setting(chat_id, PROMOTE_KEY, default="[]")
    try:
        lst = json.loads(raw)
    except (json.JSONDecodeError, TypeError):
        lst = []
    if not isinstance(lst, list):
        lst = []
    if user_id not in lst:
        lst.append(user_id)
    await db.set_setting(chat_id, PROMOTE_KEY, json.dumps(lst))


async def _remove_promoted(chat_id: int, user_id: int) -> None:
    raw = await db.get_setting(chat_id, PROMOTE_KEY, default="[]")
    try:
        lst = json.loads(raw)
    except (json.JSONDecodeError, TypeError):
        lst = []
    if not isinstance(lst, list):
        lst = []
    if user_id in lst:
        lst.remove(user_id)
    await db.set_setting(chat_id, PROMOTE_KEY, json.dumps(lst))


async def _list_promoted(chat_id: int) -> list[int]:
    raw = await db.get_setting(chat_id, PROMOTE_KEY, default="[]")
    try:
        lst = json.loads(raw)
    except (json.JSONDecodeError, TypeError):
        return []
    return lst if isinstance(lst, list) else []


def _resolve_lock(name: str) -> str | None:
    return LOCK_ALIASES.get(name.lower().strip())


async def _delete_message_job(context: ContextTypes.DEFAULT_TYPE) -> None:
    d = context.job.data
    try:
        await context.bot.delete_message(d["chat_id"], d["message_id"])
    except (BadRequest, Forbidden):
        pass


# ───────────────────────── 1. Ban / Tban ─────────────────────────
@admin_only
@bot_can_restrict
async def ban_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target, reason = await _extract_target_and_reason(context.bot, msg)
    if not target:
        await msg.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await msg.reply_text(MSG["user_not_admin"])
        return
    try:
        await _ban_user(context.bot, chat.id, target, reason=reason)
        text = f"🔨 {user_link(None, str(target))} بن شد و رفت!"
        if reason: text += f"\n📝 دلیل: {reason}"
        await msg.reply_text(text, parse_mode=ParseMode.HTML)
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


@admin_only
@bot_can_restrict
async def tban_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target, reason = await _extract_target_and_reason(context.bot, msg)
    if not target:
        await msg.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await msg.reply_text(MSG["user_not_admin"])
        return
    args = (msg.text or "").split()
    seconds = None
    for arg in args[1:]:
        seconds = parse_time(arg)
        if seconds:
            break
    if not seconds:
        await msg.reply_text(MSG["invalid_time"])
        return
    until_ts = int(time.time()) + seconds
    try:
        await _ban_user(context.bot, chat.id, target, until_date=until_ts, reason=reason)
        text = f"⏱ {user_link(None, str(target))} به مدت {format_time(seconds)} بن شد"
        if reason: text += f"\n📝 دلیل: {reason}"
        await msg.reply_text(text, parse_mode=ParseMode.HTML)
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 2. Unban ─────────────────────────
@admin_only
async def unban_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    try:
        await context.bot.unban_chat_member(chat.id, target)
        await db.blocklist_remove(chat.id, target)
        await update.message.reply_text(
            f"✅ {user_link(None, str(target))} از بن درومد، خوش اومدی!",
            parse_mode=ParseMode.HTML,
        )
    except (BadRequest, Forbidden) as e:
        await update.message.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 3. Mute / Tmute ─────────────────────────
@admin_only
@bot_can_restrict
async def mute_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target = await resolve_target(context.bot, msg)
    if not target:
        await msg.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await msg.reply_text(MSG["user_not_admin"])
        return
    try:
        await context.bot.restrict_chat_member(chat.id, target, permissions=MUTED_PERMS)
        await db.silent_add(chat.id, target)
        await msg.reply_text(
            f"🔇 {user_link(None, str(target))} ساکت شد، دیگه چیزی نمی‌نویسه",
            parse_mode=ParseMode.HTML,
        )
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


@admin_only
@bot_can_restrict
async def tmute_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target = await resolve_target(context.bot, msg)
    if not target:
        await msg.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await msg.reply_text(MSG["user_not_admin"])
        return
    args = (msg.text or "").split()
    seconds = None
    for arg in args[1:]:
        seconds = parse_time(arg)
        if seconds:
            break
    if not seconds:
        await msg.reply_text(MSG["invalid_time"])
        return
    until_ts = int(time.time()) + seconds
    try:
        await context.bot.restrict_chat_member(chat.id, target, permissions=MUTED_PERMS, until_date=until_ts)
        await db.silent_add(chat.id, target, until_ts)
        await msg.reply_text(
            f"⏱ {user_link(None, str(target))} به مدت {format_time(seconds)} ساکت شد",
            parse_mode=ParseMode.HTML,
        )
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 4. Unmute ─────────────────────────
@admin_only
@bot_can_restrict
async def unmute_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    try:
        await context.bot.restrict_chat_member(chat.id, target, permissions=UNMUTED_PERMS)
        await db.silent_remove(chat.id, target)
        await update.message.reply_text(
            f"🔊 {user_link(None, str(target))} از سکوت درومد، حالا می‌تونه حرف بزنه",
            parse_mode=ParseMode.HTML,
        )
    except (BadRequest, Forbidden) as e:
        await update.message.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 5. Kick ─────────────────────────
@admin_only
@bot_can_restrict
async def kick_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await update.message.reply_text(MSG["user_not_admin"])
        return
    try:
        await context.bot.ban_chat_member(chat.id, target)
        await context.bot.unban_chat_member(chat.id, target)
        await update.message.reply_text(
            f"👢 {user_link(None, str(target))} پرید بیرون!",
            parse_mode=ParseMode.HTML,
        )
    except (BadRequest, Forbidden) as e:
        await update.message.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 6. Warn / Warns / Reset / Set ─────────────────────────
@admin_only
async def warn_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target, reason = await _extract_target_and_reason(context.bot, msg)
    if not target:
        await msg.reply_text(MSG["reply_or_user"])
        return
    if not await _can_act(context.bot, chat.id, target):
        await msg.reply_text(MSG["user_not_admin"])
        return
    if not reason:
        reason = "بدون دلیل"
    await db.add_warn(chat.id, target, reason, update.effective_user.id)
    count = await db.get_warns_count(chat.id, target)
    settings = await db.get_all_settings(chat.id)
    warn_limit = int(settings.get("warn_limit", DEFAULT_WARN_LIMIT))
    warn_mode = settings.get("warn_mode", DEFAULT_WARN_MODE)
    if count >= warn_limit:
        try:
            if warn_mode == "ban":
                await context.bot.ban_chat_member(chat.id, target)
                action_text = "بن"
            elif warn_mode == "kick":
                await context.bot.ban_chat_member(chat.id, target)
                await context.bot.unban_chat_member(chat.id, target)
                action_text = "اخراج"
            else:
                await context.bot.restrict_chat_member(chat.id, target, permissions=MUTED_PERMS)
                action_text = "سکوت"
            await db.reset_warns(chat.id, target)
            await msg.reply_text(
                f"🚨 {user_link(None, str(target))} به {warn_limit} تا اخطار رسید و {action_text} شد",
                parse_mode=ParseMode.HTML,
            )
        except (BadRequest, Forbidden) as e:
            await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")
    else:
        await msg.reply_text(
            f"⚠️ {user_link(None, str(target))} یک اخطار گرفت\n{count}/{warn_limit} — {reason}",
            parse_mode=ParseMode.HTML,
        )


@admin_only
async def warns_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message) or update.effective_user.id
    warns = await db.get_warns(chat.id, target)
    if not warns:
        await update.message.reply_text(
            f"✅ {user_link(None, str(target))} هیچ اخطاری نداره، آفرین!",
            parse_mode=ParseMode.HTML,
        )
        return
    text = f"⚠️ اخطارهای {user_link(None, str(target))}:\n\n"
    for i, w in enumerate(warns, 1):
        text += f"{i}. {w['reason']}\n"
    await update.message.reply_text(text, parse_mode=ParseMode.HTML)


@admin_only
async def unwarn_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    await db.reset_warns(chat.id, target)
    await update.message.reply_text(
        f"✅ اخطارهای {user_link(None, str(target))} پاک شد، یه فرصت دوباره!",
        parse_mode=ParseMode.HTML,
    )


@admin_only
async def resetwarns_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await unwarn_cmd(update, context)


@admin_only
async def setwarnlimit_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    args = (update.message.text or "").split()
    n = None
    for arg in args[1:]:
        if arg.isdigit():
            n = int(arg)
            break
    if n is None:
        await update.message.reply_text(f"مثال: <code>تعداد اخطار 5</code>", parse_mode=ParseMode.HTML)
        return
    if n < 3 or n > 10:
        await update.message.reply_text("❌ تعداد باید بین ۳ تا ۱۰ باشه")
        return
    await db.set_setting(update.effective_chat.id, "warn_limit", n)
    await update.message.reply_text(f"✅ سقف اخطار روی {n} تنظیم شد")


@admin_only
async def setwarnmode_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    args = (update.message.text or "").split()
    mode = None
    for arg in args[1:]:
        a = arg.lower().strip()
        if a in ("ban", "mute", "kick"):
            mode = a
            break
    if not mode:
        await update.message.reply_text("مثال: <code>حالت اخطار ban</code> یا <code>حالت اخطار mute</code>", parse_mode=ParseMode.HTML)
        return
    await db.set_setting(update.effective_chat.id, "warn_mode", mode)
    mode_names = {"ban": "بن", "mute": "سکوت", "kick": "اخراج"}
    await update.message.reply_text(f"✅ حالت اخطار روی «{mode_names[mode]}» تنظیم شد")


# ───────────────────────── 7. Pin / Unpin / Unpinall ─────────────────────────
@admin_only
@bot_can_pin
async def pin_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    msg = update.message
    if not msg.reply_to_message:
        await msg.reply_text(MSG["no_reply"])
        return
    silent = "سکوت" in (msg.text or "") or "silent" in (msg.text or "")
    try:
        await context.bot.pin_chat_message(msg.chat_id, msg.reply_to_message.message_id, disable_notification=silent)
        await msg.reply_text(f"📌 پیام سنجاق شد{' (بی صدا)' if silent else ''}")
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


@admin_only
@bot_can_pin
async def unpin_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    try:
        await context.bot.unpin_chat_message(update.effective_chat.id)
        await update.message.reply_text("✅ پیام از سنجاق درومد")
    except (BadRequest, Forbidden) as e:
        await update.message.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


@admin_only
@bot_can_pin
async def unpinall_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    try:
        await context.bot.unpin_all_chat_messages(update.effective_chat.id)
        await update.message.reply_text("✅ همه پیام‌های سنجاق شده پاک شدن")
    except (BadRequest, Forbidden) as e:
        await update.message.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 8. Delete ─────────────────────────
@admin_only
@bot_can_delete
async def del_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    msg = update.message
    if not msg.reply_to_message:
        await msg.reply_text(MSG["no_reply"])
        return
    try:
        await msg.reply_to_message.delete()
        await msg.delete()
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['error']}\n{str(e)[:100]}")


# ───────────────────────── 9. Purge ─────────────────────────
@admin_only
@bot_can_delete
async def purge_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    msg = update.message
    if not msg.reply_to_message:
        await msg.reply_text(MSG["no_reply"])
        return
    args = (msg.text or "").split()
    count = 100
    for arg in args[1:]:
        if arg.isdigit():
            count = min(int(arg), 10000)
            break
    chat_id = msg.chat_id
    start_id = msg.reply_to_message.message_id
    end_id = msg.message_id - 1
    msg_ids = list(range(start_id, min(start_id + count, end_id + 1)))
    deleted = 0
    for i in range(0, len(msg_ids), 100):
        batch = msg_ids[i:i + 100]
        try:
            await context.bot.delete_messages(chat_id, batch)
            deleted += len(batch)
        except (BadRequest, Forbidden):
            for mid in batch:
                try:
                    await context.bot.delete_message(chat_id, mid)
                    deleted += 1
                except (BadRequest, Forbidden):
                    continue
    try:
        await msg.delete()
    except (BadRequest, Forbidden):
        pass
    notice = await context.bot.send_message(chat_id, f"🧹 {deleted} تا پیام پاک شد")
    context.job_queue.run_once(_delete_message_job, when=3, data={"chat_id": chat_id, "message_id": notice.message_id})


# ───────────────────────── 10. Global Ban ─────────────────────────
@sudo_only
async def gban_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    target, reason = await _extract_target_and_reason(context.bot, msg)
    if not target:
        await msg.reply_text("❌ روی پیام ریپلای کن یا آیدی/یوزرنیم بده", parse_mode=ParseMode.HTML)
        return
    if target == context.bot.id:
        await msg.reply_text("🤖 به خودم دست نزن :)")
        return
    await db.add_global_ban(target, reason or None, update.effective_user.id)
    text = f"🚫 کاربر <code>{target}</code> به صورت سراسری بن شد"
    if reason: text += f"\n📝 دلیل: {reason}"
    await msg.reply_text(text, parse_mode=ParseMode.HTML)
    try:
        await context.bot.ban_chat_member(chat.id, target)
    except (BadRequest, Forbidden):
        pass


@sudo_only
async def ungban_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text("❌ روی پیام ریپلای کن یا آیدی/یوزرنیم بده", parse_mode=ParseMode.HTML)
        return
    await db.remove_global_ban(target)
    await update.message.reply_text(f"✅ کاربر <code>{target}</code> از لیست بن سراسری خارج شد", parse_mode=ParseMode.HTML)


@sudo_only
async def gbanlist_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    rows = await db._fetchall("SELECT user_id, reason, created_at FROM global_bans ORDER BY created_at DESC LIMIT 100")
    if not rows:
        await update.message.reply_text("ℹ️ لیست بن سراسری خالیه")
        return
    text = "🚫 <b>لیست بن سراسری (۱۰۰ تای آخر):</b>\n\n" + "\n".join(
        f"• <code>{r['user_id']}</code>" + (f" — {r['reason']}" if r['reason'] else "") for r in rows
    )
    await update.message.reply_text(text, parse_mode=ParseMode.HTML)


# ───────────────────────── 11. Admin Management ─────────────────────────
@admin_only
async def promote_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    if target == context.bot.id:
        await update.message.reply_text("به توپم دست نزن :)")
        return
    if await _is_promoted(chat.id, target):
        await update.message.reply_text(f"ℹ️ کاربر {user_link(None, str(target))} از قبل مدیر ربات است", parse_mode=ParseMode.HTML)
        return
    await _add_promoted(chat.id, target)
    await update.message.reply_text(f"➕ کاربر {user_link(None, str(target))} به لیست مدیران ربات اضافه شد", parse_mode=ParseMode.HTML)


@admin_only
async def demote_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    target = await resolve_target(context.bot, update.message)
    if not target:
        await update.message.reply_text(MSG["reply_or_user"])
        return
    if target == context.bot.id:
        return
    if not await _is_promoted(chat.id, target):
        await update.message.reply_text(f"ℹ️ کاربر {user_link(None, str(target))} مدیر ربات نیست", parse_mode=ParseMode.HTML)
        return
    await _remove_promoted(chat.id, target)
    await update.message.reply_text(f"➖ کاربر {user_link(None, str(target))} از لیست مدیران ربات حذف شد", parse_mode=ParseMode.HTML)


@admin_only
async def admins_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    try:
        admins = await context.bot.get_chat_administrators(chat.id)
    except (BadRequest, Forbidden):
        await update.message.reply_text(MSG["bot_admin"])
        return
    text = f"👮 <b>لیست ادمین‌های گروه ({len(admins)}):</b>\n\n"
    for i, admin in enumerate(admins, 1):
        u = admin.user
        name = f"@{u.username}" if u.username else f'<a href="tg://user?id={u.id}">{u.first_name}</a>'
        icon = "👑" if admin.status == "creator" else "🛡"
        title = admin.custom_title or ""
        text += f"{i}. {icon} {name} <code>{u.id}</code>"
        if title: text += f" - {title}"
        text += "\n"
    await update.message.reply_text(text, parse_mode=ParseMode.HTML)


# ───────────────────────── 12. Nickname / Title ─────────────────────────
@admin_only
async def settitle_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    if not msg.reply_to_message or not msg.reply_to_message.from_user:
        await msg.reply_text(MSG["no_reply"])
        return
    from bot.helpers import get_text_args
    title = get_text_args(update, context)[:16]
    if not title:
        await msg.reply_text("❌ روی پیام ریپلای کن و بنویس: <code>settitle لقب</code>", parse_mode=ParseMode.HTML)
        return
    target = msg.reply_to_message.from_user.id
    if target == context.bot.id:
        await msg.reply_text("به توپم دست نزن :)")
        return
    try:
        await context.bot.set_chat_administrator_custom_title(chat.id, target, title)
        await msg.reply_text(f"✅ لقب کاربر {user_link(msg.reply_to_message.from_user)} به «{title}» تغییر یافت", parse_mode=ParseMode.HTML)
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['bot_no_perm']}\n{str(e)[:80]}")


@admin_only
async def removetitle_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    msg = update.message
    if not msg.reply_to_message or not msg.reply_to_message.from_user:
        await msg.reply_text(MSG["no_reply"])
        return
    target = msg.reply_to_message.from_user.id
    if target == context.bot.id:
        return
    try:
        await context.bot.set_chat_administrator_custom_title(chat.id, target, "")
        await msg.reply_text(f"✅ لقب {user_link(msg.reply_to_message.from_user)} حذف شد", parse_mode=ParseMode.HTML)
    except (BadRequest, Forbidden) as e:
        await msg.reply_text(f"{MSG['bot_no_perm']}\n{str(e)[:80]}")


# ───────────────────────── 13. Lock / Unlock ─────────────────────────
@admin_only
async def lock_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    args = (update.message.text or "").split(maxsplit=1)
    if len(args) < 2:
        await update.message.reply_text("❌ باید بگی چی رو قفل کنم! مثلاً: قفل کن لینک", parse_mode=ParseMode.HTML)
        return
    name = _resolve_lock(args[1])
    if not name:
        await update.message.reply_text("❌ این نوع قفل رو نمی‌شناسم!", parse_mode=ParseMode.HTML)
        return
    await db.add_lock(chat.id, name)
    label = LOCK_TYPES.get(name, (name, "🔒"))[0]
    await update.message.reply_text(f"🔒 قفل «{label}» فعال شد")


@admin_only
async def unlock_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    args = (update.message.text or "").split(maxsplit=1)
    if len(args) < 2:
        await update.message.reply_text("❌ باید بگی چی رو باز کنم! مثلاً: باز کن لینک", parse_mode=ParseMode.HTML)
        return
    name = _resolve_lock(args[1])
    if not name:
        await update.message.reply_text("❌ این نوع قفل رو نمی‌شناسم")
        return
    await db.remove_lock(chat.id, name)
    label = LOCK_TYPES.get(name, (name, "🔓"))[0]
    await update.message.reply_text(f"🔓 قفل «{label}» باز شد. از این به بعد آزاده!")


# ───────────────────────── Registration ─────────────────────────
ENGLISH_CMDS = {
    "ban": ban_cmd,
    "tban": tban_cmd,
    "unban": unban_cmd,
    "mute": mute_cmd,
    "tmute": tmute_cmd,
    "unmute": unmute_cmd,
    "kick": kick_cmd,
    "warn": warn_cmd,
    "warns": warns_cmd,
    "unwarn": unwarn_cmd,
    "resetwarns": resetwarns_cmd,
    "setwarnlimit": setwarnlimit_cmd,
    "setwarnmode": setwarnmode_cmd,
    "pin": pin_cmd,
    "unpin": unpin_cmd,
    "unpinall": unpinall_cmd,
    "del": del_cmd,
    "purge": purge_cmd,
    "gban": gban_cmd,
    "ungban": ungban_cmd,
    "gbanlist": gbanlist_cmd,
    "promote": promote_cmd,
    "demote": demote_cmd,
    "admins": admins_cmd,
    "settitle": settitle_cmd,
    "removetitle": removetitle_cmd,
    "lock": lock_cmd,
    "unlock": unlock_cmd,
}

PERSIAN_CMDS = {
    "بن کن": ban_cmd,
    "بنش کن": ban_cmd,
    "اخراجش کن": ban_cmd,
    "بن": ban_cmd,
    "بنداز": ban_cmd,
    "بنداز بیرون": ban_cmd,
    "ممنوع": ban_cmd,
    "ممنوعش کن": ban_cmd,
    "برو بیرون": tban_cmd,
    "بن موقت": tban_cmd,
    "اخراج موقت": tban_cmd,
    "حذف بن": unban_cmd,
    "رفع بن": unban_cmd,
    "آنبن": unban_cmd,
    "بازکردن": unban_cmd,
    "آزادش کن": unban_cmd,
    "ساکت کن": mute_cmd,
    "سکوت کن": mute_cmd,
    "میوت کن": mute_cmd,
    "سکوت": mute_cmd,
    "گنگش کن": mute_cmd,
    "سکوت موقت": tmute_cmd,
    "میوت موقت": tmute_cmd,
    "حذف سکوت": unmute_cmd,
    "رفع سکوت": unmute_cmd,
    "آنمیوت": unmute_cmd,
    "صدا داره": unmute_cmd,
    "بندازش بیرون": kick_cmd,
    "اخراج": kick_cmd,
    "کیک": kick_cmd,
    "بیرون کن": kick_cmd,
    "اخراج کن": kick_cmd,
    "اخطار بده": warn_cmd,
    "تذکر بده": warn_cmd,
    "اخطار": warn_cmd,
    "تذکر": warn_cmd,
    "اخطارها": warns_cmd,
    "لیست اخطار": warns_cmd,
    "تذکرها": warns_cmd,
    "حذف اخطار": unwarn_cmd,
    "پاکسازی اخطار": resetwarns_cmd,
    "تعداد اخطار": setwarnlimit_cmd,
    "حالت اخطار": setwarnmode_cmd,
    "سنجاق کن": pin_cmd,
    "پین کن": pin_cmd,
    "نگه دار": pin_cmd,
    "سنجاق": pin_cmd,
    "حذف سنجاق": unpin_cmd,
    "برداشتن سنجاق": unpin_cmd,
    "آنپین": unpin_cmd,
    "حذف همه سنجاق‌ها": unpinall_cmd,
    "پاکسازی سنجاق": unpinall_cmd,
    "حذف کن": del_cmd,
    "پاکش کن": del_cmd,
    "حذف": del_cmd,
    "پاک کن": del_cmd,
    "پاک کردن": purge_cmd,
    "پاکسازی": purge_cmd,
    "حذف گروهی": purge_cmd,
    "پاکسازی کن": purge_cmd,
    "بن سراسری": gban_cmd,
    "گلوبال بن": gban_cmd,
    "حذف بن سراسری": ungban_cmd,
    "رفع گلوبال بن": ungban_cmd,
    "لیست بن سراسری": gbanlist_cmd,
    "گلوبال بن‌ها": gbanlist_cmd,
    "مدیر کن": promote_cmd,
    "ادمینش کن": promote_cmd,
    "مدیر": promote_cmd,
    "ادمین کن": promote_cmd,
    "عزل": demote_cmd,
    "حذف مدیر": demote_cmd,
    "برکنار": demote_cmd,
    "مدیران": admins_cmd,
    "لیست مدیران": admins_cmd,
    "ادمین‌ها": admins_cmd,
    "ادمینا": admins_cmd,
    "تنظیم لقب": settitle_cmd,
    "لقب": settitle_cmd,
    "حذف لقب": removetitle_cmd,
    "قفل کن": lock_cmd,
    "ببند": lock_cmd,
    "قفل": lock_cmd,
    "بستن": lock_cmd,
    "باز کن": unlock_cmd,
    "وا کن": unlock_cmd,
    "باز": unlock_cmd,
    "بازش کن": unlock_cmd,
}


def register(app) -> None:
    register_mixed(app, ENGLISH_CMDS, PERSIAN_CMDS)
