"""Tag/admins/report — reporting and tagging helpers."""
from __future__ import annotations

import asyncio
import time

from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.constants import ParseMode
from telegram.error import BadRequest, Forbidden
from telegram.ext import CallbackQueryHandler, CommandHandler, ContextTypes

from bot import db
from bot.decorators import admin_only
from bot.helpers import chunk_list
from bot.persian_router import register_mixed


@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:
        await update.message.reply_text("❌ نمی‌تونم لیست ادمین‌ها رو بگیرم. مطمئنی منو ادمین کردی؟")
        return
    mentions = []
    for admin in admins:
        u = admin.user
        if u.is_bot:
            continue
        mentions.append(f"<a href='tg://user?id={u.id}'>{u.first_name}</a>")
    if not mentions:
        await update.message.reply_text("❌ هیچ ادمینی پیدا نکردم غیر از خودم!")
        return
    text = f"👮 <b>ادمین‌های گروه ({len(mentions)} نفر):</b>\n\n" + " ".join(mentions[:50])
    await update.message.reply_text(text, parse_mode=ParseMode.HTML)


@admin_only
async def tag_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    chat = update.effective_chat
    if chat.type == "private":
        await update.message.reply_text("❌ این دستور فقط تو گروه کار میکنه!")
        return
    args = (update.message.text or "").split(maxsplit=1)
    text = args[1] if len(args) > 1 else "📣 توجه همه اعضا!"

    # Check group size
    try:
        count = await context.bot.get_chat_member_count(chat.id)
    except BadRequest:
        count = 0

    if count > 100:
        await update.message.reply_text(
            f"⚠️ گروه {count} تا عضو داره! برای جلوگیری از اسپم، تگ همگانی محدود شده.\n"
            f"فقط ادمین‌ها و کاربران اخیر تگ می‌شن.",
            parse_mode=ParseMode.HTML,
        )
        return

    await _do_tag(context.bot, chat.id, text, update.effective_user.id, exclude_admins=False)


@admin_only
async def tag_no_admin_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """Tag all members except admins."""
    chat = update.effective_chat
    if chat.type == "private":
        await update.message.reply_text("❌ این دستور فقط تو گروه کار میکنه!")
        return
    args = (update.message.text or "").split(maxsplit=1)
    text = args[1] if len(args) > 1 else "📣 توجه به همه کاربران!"
    await _do_tag(context.bot, chat.id, text, update.effective_user.id, exclude_admins=True)


async def _do_tag(bot, chat_id: int, text: str, by_user_id: int, exclude_admins: bool = False) -> None:
    """Mention members in batches."""
    try:
        members_count = await bot.get_chat_member_count(chat_id)
    except BadRequest:
        members_count = 0

    if members_count > 200:
        await bot.send_message(
            chat_id,
            f"⚠️ گروه {members_count} عضو داره! برای تگ همگانی زیادی بزرگه.\n"
            f"از دستور «تگ ادمین‌ها» یا «تگ بدون ادمین» استفاده کن.",
            parse_mode=ParseMode.HTML,
        )
        return

    exclude_ids = set()
    if exclude_admins:
        try:
            admins = await bot.get_chat_administrators(chat_id)
            for a in admins:
                if not a.user.is_bot:
                    exclude_ids.add(a.user.id)
        except (BadRequest, Forbidden):
            pass

    try:
        admins = await bot.get_chat_administrators(chat_id)
    except BadRequest:
        admins = []

    mentions = []
    for admin in admins:
        u = admin.user
        if u.is_bot or u.id in exclude_ids:
            continue
        mentions.append(f"<a href='tg://user?id={u.id}'>{u.first_name}</a>")

    if not mentions:
        if exclude_admins:
            await bot.send_message(chat_id, "❌ غیر از ادمین‌ها کسی پیدا نکردم!")
        else:
            await bot.send_message(chat_id, "❌ کسی برای تگ کردن پیدا نکردم!")
        return

    # Send in batches of 50 mentions per message
    batch_size = 50
    sender_name = "مدیر گروه"
    try:
        chat = await bot.get_chat(chat_id)
        sender_name = chat.title or "مدیر گروه"
    except (BadRequest, Forbidden):
        pass

    header = f"📣 <b>{text}</b>\n\n" + ("─" * 20) + "\n"

    for i in range(0, len(mentions), batch_size):
        chunk = mentions[i:i + batch_size]
        msg = header + " ".join(chunk)
        try:
            await bot.send_message(chat_id, msg, parse_mode=ParseMode.HTML)
        except (BadRequest, Forbidden) as e:
            await bot.send_message(chat_id, f"❌ خطا در ارسال تگ: {e}")
            break
        await asyncio.sleep(1)  # avoid flood


async def report_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    """گزارش پیام به ادمین‌ها"""
    if not update.message.reply_to_message:
        await update.message.reply_text("❌ روی پیام مورد نظر ریپلای کنید.")
        return
    chat = update.effective_chat
    try:
        admins = await context.bot.get_chat_administrators(chat.id)
    except BadRequest:
        await update.message.reply_text("❌ خطا.")
        return
    reporter = update.effective_user
    reported_msg = update.message.reply_to_message

    mentions = []
    for admin in admins:
        u = admin.user
        if u.is_bot:
            continue
        mentions.append(f"<a href='tg://user?id={u.id}'>{u.first_name}</a>")
    if not mentions:
        await update.message.reply_text("❌ ادمینی یافت نشد.")
        return

    # Forward the reported message
    try:
        await reported_msg.forward(chat.id)
    except BadRequest:
        pass
    text = (
        f"🚨 <b>گزارش!</b>\n\n"
        f"گزارش‌دهنده: {reporter.mention_html()}\n"
        f"متخلف: {reported_msg.from_user.mention_html() if reported_msg.from_user else 'نامشخص'}\n"
        f"پیام: <a href='{reported_msg.link}'>لینک</a>\n\n"
        f"ادمین‌ها: " + " ".join(mentions[:5])
    )

    # Inline action buttons
    target_id = reported_msg.from_user.id if reported_msg.from_user else 0
    keyboard = [[
        InlineKeyboardButton("🔨 بن", callback_data=f"rpt_ban:{chat.id}:{target_id}"),
        InlineKeyboardButton("⚠️ اخطار", callback_data=f"rpt_warn:{chat.id}:{target_id}"),
        InlineKeyboardButton("❌ صرف نظر", callback_data="rpt_ignore"),
    ]]
    reply_markup = InlineKeyboardMarkup(keyboard)

    try:
        await update.message.reply_text(text, parse_mode=ParseMode.HTML, reply_markup=reply_markup)
    except BadRequest as e:
        await update.message.reply_text(f"❌ خطا: {e}")


async def report_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    q = update.callback_query
    await q.answer()
    if not q.data or not q.data.startswith("rpt_"):
        return
    parts = q.data.split(":")
    action = parts[0]
    if action == "rpt_ignore":
        await q.edit_message_text("✅ گزارش نادیده گرفته شد.", parse_mode=ParseMode.HTML)
        return
    if len(parts) < 3:
        await q.edit_message_text("❌ خطا در داده.", parse_mode=ParseMode.HTML)
        return
    chat_id = int(parts[1])
    user_id = int(parts[2])
    if user_id == 0:
        await q.answer("❌ کاربر نامشخص", show_alert=True)
        return
    try:
        if action == "rpt_ban":
            await context.bot.ban_chat_member(chat_id, user_id)
            await q.edit_message_text("✅ کاربر بن شد.", parse_mode=ParseMode.HTML)
        elif action == "rpt_warn":
            await db.add_warn(chat_id, user_id, "گزارش", q.from_user.id)
            await q.edit_message_text("✅ اخطار ثبت شد.", parse_mode=ParseMode.HTML)
    except (BadRequest, Forbidden) as e:
        await q.edit_message_text(f"❌ خطا: {e}", parse_mode=ParseMode.HTML)


def register(app) -> None:
    register_mixed(
        app,
        {
            "admins": admins_cmd,
            "tagadmins": admins_cmd,
            "tag": tag_cmd,
            "report": report_cmd,
            "tagall": tag_cmd,
            "tagwithoutadmin": tag_no_admin_cmd,
        },
        {
            "تگ": tag_cmd,
            "تگ کن": tag_cmd,
            "تگ همگانی": tag_cmd,
            "همه": tag_cmd,
            "همه رو تگ کن": tag_cmd,
            "همگانی": tag_cmd,
            "صدا کن": tag_cmd,
            "تگ بدون ادمین": tag_no_admin_cmd,
            "تگ بجز ادمین": tag_no_admin_cmd,
            "همه بجز ادمین": tag_no_admin_cmd,
            "کاربرا": tag_no_admin_cmd,
            "کاربران": tag_no_admin_cmd,
            "گزارش": report_cmd,
            "گزارش کن": report_cmd,
            "شکایت": report_cmd,
            "شکایت کن": report_cmd,
            "ادمینا": admins_cmd,
            "ادمین‌ها": admins_cmd,
            "ادمین ها": admins_cmd,
            "ادمینا رو صدا کن": admins_cmd,
            "ادمین": admins_cmd,
        },
    )
    app.add_handler(CallbackQueryHandler(report_callback, pattern=r"^rpt_"))
