"""Settings handler with modern sticker panel."""
from __future__ import annotations

import logging
from typing import Optional

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.constants import E, LOCK_TYPES
from bot.persian_router import register_mixed
from bot.sticker_panel import SEPARATOR

logger = logging.getLogger(__name__)


# ───── Helper: pretty setting row ─────
def _row(label: str, icon: str, enabled: bool) -> str:
    dot = "✅" if enabled else "❌"
    return f"{dot} {icon} {label}"


def _toggle_btn(key: str, label: str, enabled: bool) -> InlineKeyboardButton:
    action = "غیرفعال کن" if enabled else "فعال کن"
    dot = "❌" if enabled else "✅"
    return InlineKeyboardButton(f"{dot} {action}", callback_data=f"toggle_{key}")


def _section_btn(label: str, cb: str) -> InlineKeyboardButton:
    return InlineKeyboardButton(f"📂 {label}", callback_data=cb)


# Categories: max 3 buttons per row for mobile readability
CATEGORIES = [
    ("👋 ورود و خروج", [
        ("st_welcome", "خوش‌آمدگویی"),
        ("st_goodbye", "خداحافظی"),
        ("st_rules", "قوانین"),
    ]),
    ("🛡 امنیت", [
        ("st_flood", "ضد فلود"),
        ("st_antiraid", "ضد ریپ"),
        ("st_antilink", "ضد لینک"),
    ]),
    ("🔧 سایر", [
        ("st_locks", "قفل‌ها"),
        ("st_antispam", "ضد اسپم"),
        ("st_captcha", "کپچا"),
    ]),
    ("⚙️ پیشرفته", [
        ("st_reports", "گزارش‌ها"),
        ("st_log", "لاگ"),
        ("st_clean", "پاکسازی"),
    ]),
]


@admin_only
async def settings_cmd(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    from bot.sticker_panel import send_panel_sticker, get_panel_header, status_dot

    chat = update.effective_chat
    settings = await db.get_all_settings(chat.id)
    locks = set(await db.get_locks(chat.id))
    await send_panel_sticker(update, context)

    w_enabled = settings.get("welcome_enabled", True)
    g_enabled = settings.get("goodbye_enabled", False)
    af_enabled = settings.get("antiflood", False)
    ar_enabled = settings.get("antiraid", False)
    cap_enabled = settings.get("captcha_enabled", False)
    link_locked = "link" in locks
    flood_limit = settings.get("flood_limit", 10)
    warn_limit = settings.get("warn_limit", 3)
    antispam = settings.get("antispam_enabled", False)

    text = get_panel_header("⚙️", "مرکز تنظیمات گروه", "از دکمه‌های زیر یکی رو انتخاب کن")
    text += "\n"

    rows = [
        _row("خوش‌آمدگویی", "👋", w_enabled),
        _row("خداحافظی", "😢", g_enabled),
        _row("ضد فلود", "🌊", af_enabled),
        _row("ضد لینک", "🔗", link_locked),
        _row("ضد ریپ", "🌀", ar_enabled),
        _row("کپچا", "🧩", cap_enabled),
        _row("ضد اسپم", "🤖", antispam),
        _row("سقف اخطار", "⚠️", True),
    ]
    text += "\n".join(rows)

    text += f"\n\n💡 <i>✅ = فعال | ❌ = غیرفعال</i>"

    # Build clean category-based keyboard
    kb_rows: list[list[InlineKeyboardButton]] = []
    for cat_name, items in CATEGORIES:
        btn_row: list[InlineKeyboardButton] = []
        for cb, label in items:
            btn_row.append(_section_btn(label, cb))
        kb_rows.append(btn_row)
    kb_rows.append([InlineKeyboardButton("✖️ بستن", callback_data="close")])
    kb = InlineKeyboardMarkup(kb_rows)

    try:
        await update.message.reply_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden) as e:
        logger.warning(f"settings_cmd send failed: {e}")


async def settings_callback(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    from bot.sticker_panel import get_panel_header, status_dot, lock_emoji

    query = update.callback_query
    await query.answer()
    data = query.data
    if data == "close":
        try:
            await query.message.delete()
        except (BadRequest, Forbidden):
            pass
        return
    if not query.message or not query.message.chat:
        return
    chat_id = query.message.chat.id
    user = query.from_user

    # Admin check
    try:
        member = await context.bot.get_chat_member(chat_id, user.id)
        if member.status not in ("administrator", "creator"):
            await query.answer("❌ فقط ادمین", show_alert=True)
            return
    except (BadRequest, Forbidden):
        return

    if data == "st_main" or data == "st_back":
        await _refresh_main(query, context, chat_id)
    elif data == "st_welcome":
        await _show_welcome(query, context, chat_id)
    elif data == "st_goodbye":
        await _show_goodbye(query, context, chat_id)
    elif data == "st_rules":
        await _show_rules(query, context, chat_id)
    elif data == "st_rulesaccept":
        await _show_rules_accept(query, context, chat_id)
    elif data == "st_flood":
        await _show_flood(query, context, chat_id)
    elif data == "st_captcha":
        await _show_captcha(query, context, chat_id)
    elif data == "st_antilink":
        await _show_antilink(query, context, chat_id)
    elif data == "st_antiraid":
        await _show_antiraid(query, context, chat_id)
    elif data == "st_antispam":
        await _show_antispam(query, context, chat_id)
    elif data == "st_reports":
        await _show_reports(query, context, chat_id)
    elif data == "st_log":
        await _show_log(query, context, chat_id)
    elif data == "st_clean":
        await _show_clean(query, context, chat_id)
    elif data == "st_locks":
        await _show_locks_inline(query, context, chat_id)
    elif data.startswith("tglock_"):
        await _toggle_lock(query, context, chat_id, data[7:])
    elif data.startswith("toggle_"):
        await _toggle_setting(query, context, chat_id, data[7:])
    elif data.startswith("flood_"):
        await _adjust_flood(query, context, chat_id, data[6:])


async def _refresh_main(query, context, chat_id: int) -> None:
    settings = await db.get_all_settings(chat_id)
    locks = set(await db.get_locks(chat_id))
    text = get_panel_header("⚙️", "مرکز تنظیمات", "از دکمه‌های پایین انتخاب کن")
    text += "\n" + "━" * 22
    items = [
        ("👋 خوش‌آمد", status_dot(settings.get("welcome_enabled", True))),
        ("😢 خداحافظی", status_dot(settings.get("goodbye_enabled", False))),
        ("🌊 ضد فلود", status_dot(settings.get("antiflood", False))),
        ("🔗 ضد لینک", status_dot("link" in locks)),
        ("🌀 ضد ریپ", status_dot(settings.get("antiraid", False))),
        ("🧩 کپچا", status_dot(settings.get("captcha_enabled", False))),
        ("🤖 ضد اسپم", status_dot(settings.get("antispam_enabled", False))),
    ]
    for emoji, dot in items:
        text += f"\n{dot} {emoji}"
    text += "\n" + "━" * 22
    text += "\n💡 🟢=فعال 🔴=غیرفعال"

    kb_rows: list[list[InlineKeyboardButton]] = []
    for cat_name, sub_items in CATEGORIES:
        btn_row: list[InlineKeyboardButton] = []
        for cb, label in sub_items:
            btn_row.append(_section_btn(label, cb))
        kb_rows.append(btn_row)
    kb_rows.append([InlineKeyboardButton("✖️ بستن", callback_data="close")])
    kb = InlineKeyboardMarkup(kb_rows)
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_welcome(query, context, chat_id: int) -> None:
    cur = await db.get_setting(chat_id, "welcome_enabled", True)
    text = get_panel_header("👋", "تنظیمات خوش‌آمدگویی", "فعال/غیرفعال کردن پیام خوش‌آمد")
    text += f"\n{'━' * 22}"
    text += f"\n{'🟢' if cur else '🔴'} وضعیت: {'فعال' if cur else 'غیرفعال'}"
    text += f"\n💡 پیام خوش‌آمد هنگام ورود کاربر جدید فرستاده می‌شه"
    text += f"\nبرای تغییر متن از /setwelcome استفاده کن"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if cur else '🔴'} فعال/غیرفعال", callback_data=f"toggle_welcome")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_flood(query, context, chat_id: int) -> None:
    enabled = await db.get_setting(chat_id, "antiflood", False)
    limit = await db.get_setting(chat_id, "flood_limit", 10)
    mode = await db.get_setting(chat_id, "flood_mode", "mute")
    mode_fa = {"mute": "سکوت", "kick": "اخراج", "ban": "بن", "warn": "اخطار"}.get(mode, mode)
    text = get_panel_header("🌊", "ضد فلود", "کنترل پیام‌های تکراری")
    text += f"\n{'✅' if enabled else '❌'} وضعیت: {'فعال' if enabled else 'غیرفعال'}"
    text += f"\n📊 محدودیت: {limit} پیام"
    text += f"\n⚡ حالت: {mode_fa}"
    kb = InlineKeyboardMarkup([
        [_toggle_btn("antiflood", "فعال/غیرفعال", enabled)],
        [InlineKeyboardButton("➕ افزایش", callback_data="flood_+1"),
         InlineKeyboardButton("➖ کاهش", callback_data="flood_-1")],
        [InlineKeyboardButton(f"{E['back']} بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_captcha(query, context, chat_id: int) -> None:
    cur = await db.get_setting(chat_id, "captcha_enabled", False)
    text = get_panel_header("🧩", "کپچا", "تأیید ورود کاربران جدید")
    text += "\n" + "━" * 22
    text += f"\n{'🟢' if cur else '🔴'} وضعیت: {'فعال' if cur else 'غیرفعال'}"
    text += "\n💡 کاربران جدید باید کپچا رو حل کنن تا بتونن پیام بفرستن"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if cur else '🔴'} فعال/غیرفعال", callback_data="toggle_captcha")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_goodbye(query, context, chat_id: int) -> None:
    cur = await db.get_setting(chat_id, "goodbye_enabled", False)
    text = get_panel_header("😢", "تنظیمات خداحافظی", "وقتی کاربر میره")
    text += "\n" + "━" * 22
    text += f"\n{'🟢' if cur else '🔴'} وضعیت: {'فعال' if cur else 'غیرفعال'}"
    text += "\n💡 پیام خداحافظی موقع خروج کاربر فرستاده می‌شه"
    text += "\nبرای تغییر متن از /setgoodbye استفاده کن"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if cur else '🔴'} فعال/غیرفعال", callback_data="toggle_goodbye")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_rules(query, context, chat_id: int) -> None:
    rules = await db.get_setting(chat_id, "rules", default="")
    has_rules = bool(rules and rules.strip())
    text = get_panel_header("📜", "قوانین گروه", "مدیریت قوانین گروه")
    text += "\n" + "━" * 22
    if has_rules:
        text += f"\n📋 قوانین فعلی:\n{rules[:500]}"
    else:
        text += "\n❌ هنوز قانونی تنظیم نشده"
    text += "\n💡 با «تنظیم قوانین [متن]» قانون جدید بزار"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_rules_accept(query, context, chat_id: int) -> None:
    enabled = await db.get_setting(chat_id, "rules_accept_enabled", False)
    accepted_count = await db.get_rules_accept_count(chat_id)
    text = get_panel_header("✅", "قبول قوانین", "کاربرا موقع ورود قوانین رو ببینن و قبول کنن")
    text += "\n" + "━" * 22
    text += f"\n📌 وضعیت: {'🟢 فعال' if enabled else '🔴 غیرفعال'}"
    text += f"\n👥 تعداد قبول‌کنندگان: {accepted_count}"
    text += "\n\n💡 وقتی فعال باشه، عضو جدید باید قوانین رو ببینه و دکمه قبول رو بزنه تا بتونه پیام بفرسته"
    text += "\n💡 اول باید قوانین رو با «تنظیم قوانین» مشخص کنی"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if enabled else '🔴'} فعال/غیرفعال", callback_data="toggle_rulesaccept")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_clean(query, context, chat_id: int) -> None:
    enabled = await db.get_setting(chat_id, "auto_clean_enabled", False)
    text = get_panel_header("🧹", "پاکسازی خودکار", "پاک کردن پیام دستورات بعد از اجرا")
    text += "\n" + "━" * 22
    text += f"\n📌 وضعیت: {'🟢 فعال' if enabled else '🔴 غیرفعال'}"
    text += "\n\n💡 وقتی فعال باشه، بعد از اینکه یه دستور اجرا میشه، پیام دستوری که فرستادی خودکار پاک میشه"
    text += "\n💡 مثلاً اگه بگی «قوانین»، ربات قوانین رو می‌فرسته و پیام «قوانین» رو پاک می‌کنه"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if enabled else '🔴'} فعال/غیرفعال", callback_data="toggle_clean")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_log(query, context, chat_id: int) -> None:
    log_ch = await db.get_log_channel(chat_id)
    text = get_panel_header("📢", "لاگ و گزارش‌گیری", "تنظیم کانال لاگ")
    text += "\n" + "━" * 22
    text += f"\n📢 کانال لاگ: {log_ch if log_ch else '❌ تنظیم نشده'}"
    text += "\n💡 با /logchannel [آیدی کانال] یک کانال برای گزارش‌ها تنظیم کن"
    text += "\n💡 همه گزارش‌ها، بن‌ها، میوت‌ها و اخطارها اونجا ثبت می‌شه"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_antilink(query, context, chat_id: int) -> None:
    locks = set(await db.get_locks(chat_id))
    locked = "link" in locks
    text = get_panel_header("🔗", "ضد لینک", "مسدود کردن لینک در گروه")
    text += "\n" + "━" * 22
    text += f"\n{'🟢' if locked else '🔴'} وضعیت: {'مسدود' if locked else 'آزاد'}"
    text += "\n💡 اگر فعال باشه، هیچ لینکی فرستاده نمی‌شه"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if locked else '🔴'} فعال/غیرفعال", callback_data="tglock_link")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_antiraid(query, context, chat_id: int) -> None:
    cur = await db.get_setting(chat_id, "antiraid", False)
    text = get_panel_header("🌀", "ضد ریپ", "جلوگیری از حمله ناگهانی")
    text += "\n" + "━" * 22
    text += f"\n{'🟢' if cur else '🔴'} وضعیت: {'فعال' if cur else 'غیرفعال'}"
    text += "\n💡 اگه فعال باشه، جوین شدن ناگهانی محدود می‌شه"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if cur else '🔴'} فعال/غیرفعال", callback_data="toggle_antiraid")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_antispam(query, context, chat_id: int) -> None:
    cur = await db.get_setting(chat_id, "antispam_enabled", False)
    text = get_panel_header("🤖", "ضد اسپم هوشمند", "تشخیص اسپم با AI")
    text += "\n" + "━" * 22
    text += f"\n{'🟢' if cur else '🔴'} وضعیت: {'فعال' if cur else 'غیرفعال'}"
    text += "\n💡 اسپم، متن تکراری و لینک رو تشخیص می‌ده"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton(f"{'🟢' if cur else '🔴'} فعال/غیرفعال", callback_data="toggle_antispam")],
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_reports(query, context, chat_id: int) -> None:
    log_ch = await db.get_log_channel(chat_id)
    text = get_panel_header("📊", "گزارش و لاگ", "تنظیمات گزارش‌گیری")
    text += "\n" + "━" * 22
    text += f"\n📢 کانال گزارش: {log_ch if log_ch else 'تنظیم نشده'}"
    text += "\n💡 با /logchannel یک کانال برای گزارش تنظیم کن"
    kb = InlineKeyboardMarkup([
        [InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")],
    ])
    try:
        await query.edit_message_text(text, parse_mode=ParseMode.HTML, reply_markup=kb)
    except (BadRequest, Forbidden):
        pass


async def _show_locks_inline(query, context, chat_id: int) -> None:
    locks = set(await db.get_locks(chat_id))
    rows: list[list[InlineKeyboardButton]] = []
    items = list(LOCK_TYPES.items())
    for i in range(0, len(items), 2):
        row: list[InlineKeyboardButton] = []
        for j in range(2):
            if i + j >= len(items):
                break
            k, (label, icon) = items[i + j]
            locked = k in locks
            status = "🔒" if locked else "🔓"
            row.append(InlineKeyboardButton(f"{status}{icon}", callback_data=f"tglock_{k}"))
        rows.append(row)
    rows.append([InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")])
    try:
        await query.edit_message_text(
            get_panel_header("🔒", "قفل‌های گروه", "روی هرکدوم بزن تا تغییر کنه"),
            parse_mode=ParseMode.HTML,
            reply_markup=InlineKeyboardMarkup(rows),
        )
    except (BadRequest, Forbidden):
        pass


async def _toggle_lock(query, context, chat_id: int, lock_name: str) -> None:
    locks = set(await db.get_locks(chat_id))
    if lock_name in locks:
        await db.remove_lock(chat_id, lock_name)
    else:
        await db.add_lock(chat_id, lock_name)
    locks = set(await db.get_locks(chat_id))
    rows: list[list[InlineKeyboardButton]] = []
    items = list(LOCK_TYPES.items())
    for i in range(0, len(items), 2):
        row: list[InlineKeyboardButton] = []
        for j in range(2):
            if i + j >= len(items):
                break
            k, (label, icon) = items[i + j]
            locked = k in locks
            status = "🔒" if locked else "🔓"
            row.append(InlineKeyboardButton(f"{status}{icon}", callback_data=f"tglock_{k}"))
        rows.append(row)
    rows.append([InlineKeyboardButton("🔙 بازگشت", callback_data="st_main")])
    try:
        await query.edit_message_reply_markup(InlineKeyboardMarkup(rows))
    except (BadRequest, Forbidden):
        pass


async def _toggle_setting(query, context, chat_id: int, key: str) -> None:
    mapping = {
        "welcome": ("welcome_enabled", True),
        "goodbye": ("goodbye_enabled", False),
        "rulesaccept": ("rules_accept_enabled", False),
        "clean": ("auto_clean_enabled", False),
        "captcha": ("captcha_enabled", False),
        "antiflood": ("antiflood", False),
        "antiraid": ("antiraid", False),
        "antispam": ("antispam_enabled", False),
    }
    if key not in mapping:
        return
    db_key, default = mapping[key]
    cur = await db.get_setting(chat_id, db_key, default)
    await db.set_setting(chat_id, db_key, not cur)
    await query.answer("✅ تغییر کرد")
    sub_handlers = {
        "welcome": _show_welcome,
        "goodbye": _show_goodbye,
        "rulesaccept": _show_rules_accept,
        "clean": _show_clean,
        "captcha": _show_captcha,
        "antiflood": _show_flood,
        "antiraid": _show_antiraid,
        "antispam": _show_antispam,
    }
    if key in sub_handlers:
        await sub_handlers[key](query, context, chat_id)


async def _adjust_flood(query, context, chat_id: int, action: str) -> None:
    limit = await db.get_setting(chat_id, "flood_limit", 10)
    if action == "+1":
        limit = min(limit + 1, 50)
    elif action == "-1":
        limit = max(limit - 1, 2)
    await db.set_setting(chat_id, "flood_limit", limit)
    await query.answer(f"✅ حد فلود: {limit}")
    await _show_flood(query, context, chat_id)


def register(app) -> None:
    register_mixed(
        app,
        {"settings": settings_cmd},
        {"تنظیمات": settings_cmd, "تنظیمات گروه": settings_cmd, "مدیریت": settings_cmd, "تنظیمات ربات": settings_cmd},
    )


def register_callbacks(app) -> None:
    app.add_handler(
        CallbackQueryHandler(settings_callback, pattern=r"^(st_|tglock_|toggle_|flood_|close)")
    )
