"""Mandatory-membership channel management."""

from __future__ import annotations

import logging

from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery, Message

from app.context import AppContext
from app.handlers.common import show
from app.keyboards.inline import (
    back_cancel,
    confirm,
    membership_item,
    membership_menu,
    membership_text_menu,
)
from app.states import MembershipTextState, RequiredChannelState
from app.utils.validation import parse_chat_id, validate_http_url

logger = logging.getLogger(__name__)
router = Router(name="membership")


async def _overview(callback: CallbackQuery, ctx: AppContext) -> None:
    channels = await ctx.repos.membership.list_required()
    enabled = await ctx.app_settings.get_bool("membership_enabled", True)
    text = (
        "🔒 عضویت اجباری\n\n"
        f"وضعیت کلی: {'روشن' if enabled else 'خاموش'}\n"
        "کاربر فقط کانال‌های تأییدنشده را می‌بیند. خطای API هرگز به معنی عضویت یا عدم عضویت نیست.\n\n"
        "برای بررسی عضویت، ربات باید در هر کانال الزامی ادمین باشد."
    )
    await show(callback, text, membership_menu(channels))


@router.callback_query(F.data == "menu:membership")
async def membership_home(callback: CallbackQuery, ctx: AppContext) -> None:
    await _overview(callback, ctx)
    await callback.answer()


@router.callback_query(F.data == "member:toggle_global")
async def membership_toggle_global(callback: CallbackQuery, ctx: AppContext) -> None:
    current = await ctx.app_settings.get_bool("membership_enabled", True)
    await ctx.app_settings.set("membership_enabled", not current, actor_id=callback.from_user.id)
    await ctx.repos.audit.log(
        callback.from_user.id,
        "settings.membership_toggle",
        entity_type="app_setting",
        entity_id="membership_enabled",
        details={"enabled": not current},
    )
    await callback.answer("وضعیت عضویت اجباری تغییر کرد.")
    await _overview(callback, ctx)


@router.callback_query(F.data == "member:add")
async def member_add(callback: CallbackQuery, state: FSMContext) -> None:
    await state.set_state(RequiredChannelState.waiting_id)
    await show(
        callback,
        "شناسه عددی کانال الزامی را بفرستید یا یک پیام از آن کانال را فوروارد کنید.\n"
        "ربات باید در کانال ادمین باشد.",
        back_cancel("menu:membership"),
    )
    await callback.answer()


@router.message(RequiredChannelState.waiting_id)
async def member_add_id(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if message.text in {"/cancel", "❌ لغو"}:
        await state.clear()
        await message.answer("لغو شد.")
        return
    chat_id: int | None = None
    if message.forward_from_chat is not None:
        chat_id = message.forward_from_chat.id
    elif message.text:
        try:
            chat_id = parse_chat_id(message.text)
        except Exception as exc:
            await message.answer(f"⚠️ {exc}")
            return
    if chat_id is None:
        await message.answer("شناسه یا فوروارد معتبر بفرستید.")
        return
    try:
        chat = await ctx.gateway.get_chat(chat_id)
    except Exception:
        await message.answer("⚠️ اطلاعات کانال خوانده نشد. ربات باید عضو/ادمین کانال باشد.")
        return
    if chat.username:
        try:
            channel = await ctx.membership.add_channel(
                chat_id,
                title=chat.title,
                invite_link=f"https://t.me/{chat.username}",
                actor_id=message.from_user.id,
            )
        except Exception as exc:
            await message.answer(f"⚠️ {exc}")
            return
        await state.clear()
        await message.answer(
            f"✅ کانال الزامی ثبت شد: {channel.title}",
            reply_markup=back_cancel("menu:membership"),
        )
        return
    await state.set_state(RequiredChannelState.waiting_link)
    await state.update_data(required_chat_id=chat_id, required_title=chat.title)
    await message.answer(
        "این کانال عمومی نیست. لینک عضویت/دعوت را بفرستید (مثلاً https://t.me/+...).\n"
        "ربات باید همچنان ادمین کانال باشد."
    )


@router.message(RequiredChannelState.waiting_link)
async def member_add_link(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if not message.text or message.text in {"/cancel", "❌ لغو"}:
        await state.clear()
        await message.answer("لغو شد.")
        return
    data = await state.get_data()
    chat_id = data.get("required_chat_id")
    title = data.get("required_title")
    if not chat_id:
        await state.clear()
        await message.answer("جلسه منقضی شده است.")
        return
    try:
        link = validate_http_url(message.text.strip())
        channel = await ctx.membership.add_channel(
            int(chat_id),
            title=title,
            invite_link=link,
            actor_id=message.from_user.id,
        )
    except Exception as exc:
        await message.answer(f"⚠️ {exc}")
        return
    await state.clear()
    await message.answer(
        f"✅ کانال الزامی ثبت شد: {channel.title}",
        reply_markup=back_cancel("menu:membership"),
    )


@router.callback_query(F.data.startswith("member:view:"))
async def member_view(
    callback: CallbackQuery, ctx: AppContext, *, answer: bool = True
) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.membership.get_required(channel_id)
    if channel is None:
        if answer:
            await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    text = (
        f"📣 {channel.title}\n"
        f"شناسه: {channel.chat_id}\n"
        f"لینک: {channel.invite_link}\n"
        f"وضعیت: {'فعال' if channel.is_active else 'غیرفعال'}\n"
        f"الزام عمومی: {'بله' if channel.is_required_globally else 'خیر'}\n"
        f"وضعیت ربات: {channel.bot_status or 'نامشخص'}\n"
        f"آخرین بررسی: {channel.last_checked_at or '—'}\n"
        f"آخرین خطا: {channel.last_error or '—'}"
    )
    await show(callback, text, membership_item(channel))
    if answer:
        await callback.answer()


@router.callback_query(F.data.startswith("member:check:"))
async def member_check(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.membership.get_required(channel_id)
    if channel is None:
        await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    ok = await ctx.membership.check_bot_access(channel)
    await callback.answer("✅ دسترسی تأیید شد." if ok else "⚠️ ربات ادمین کانال نیست یا بررسی ناموفق بود.", show_alert=True)
    await member_view(callback, ctx, answer=False)


@router.callback_query(F.data == "member:check_all")
async def member_check_all(callback: CallbackQuery, ctx: AppContext) -> None:
    result = await ctx.membership.refresh_all()
    ok = sum(1 for value in result.values() if value)
    await callback.answer(f"{ok} از {len(result)} کانال تأیید شد.", show_alert=True)
    await _overview(callback, ctx)


@router.callback_query(F.data.startswith("member:toggle:"))
async def member_toggle(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.membership.get_required(channel_id)
    if channel is None:
        await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    await ctx.repos.membership.update_required(channel_id, is_active=not channel.is_active)
    await callback.answer("وضعیت تغییر کرد.")
    await member_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("member:global:"))
async def member_global(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.membership.get_required(channel_id)
    if channel is None:
        await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    await ctx.repos.membership.update_required(
        channel_id, is_required_globally=not channel.is_required_globally
    )
    await callback.answer("الزام عمومی تغییر کرد.")
    await member_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("member:up:"))
async def member_up(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    await ctx.repos.membership.move_required(channel_id, -1)
    await callback.answer("جابه‌جا شد.")
    await member_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("member:down:"))
async def member_down(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    await ctx.repos.membership.move_required(channel_id, 1)
    await callback.answer("جابه‌جا شد.")
    await member_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("member:delete:"))
async def member_delete_ask(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.membership.get_required(channel_id)
    if channel is None:
        await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    await show(
        callback,
        f"کانال الزامی «{channel.title}» حذف شود؟\n"
        "این کار روی پست‌های قبلی اثر ندارد اما الزام عضویت آن حذف می‌شود.",
        confirm("member_delete", channel_id, back=f"member:view:{channel_id}"),
    )
    await callback.answer()


@router.callback_query(F.data.startswith("confirm:member_delete:"))
async def member_delete_confirm(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    ok = await ctx.repos.membership.remove_required(channel_id)
    await ctx.repos.audit.log(
        callback.from_user.id,
        "required_channel.delete",
        entity_type="required_channel",
        entity_id=channel_id,
    )
    await callback.answer("حذف شد." if ok else "کانال پیدا نشد.", show_alert=True)
    await _overview(callback, ctx)


@router.callback_query(F.data == "member:text")
async def member_text_home(callback: CallbackQuery, ctx: AppContext) -> None:
    text = await ctx.app_settings.get("membership_message")
    label = await ctx.app_settings.get("membership_check_button")
    await show(
        callback,
        f"📝 متن عضویت:\n{text}\n\nمتن دکمه بررسی: {label}",
        membership_text_menu(),
    )
    await callback.answer()


@router.callback_query(F.data.startswith("member:text:"))
async def member_text_edit(callback: CallbackQuery, state: FSMContext) -> None:
    kind = callback.data.rsplit(":", 1)[1]
    if kind == "message":
        await state.set_state(MembershipTextState.waiting_message)
        prompt = "متن جدید پیام عضویت را بفرستید."
    else:
        await state.set_state(MembershipTextState.waiting_button)
        prompt = "متن جدید دکمه بررسی را بفرستید (حداکثر ۶۴ کاراکتر)."
    await show(callback, prompt, back_cancel("menu:membership"))
    await callback.answer()


@router.message(MembershipTextState.waiting_message)
async def member_text_message(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if not message.text:
        await message.answer("متن بفرستید.")
        return
    text = message.text.strip()
    if len(text) > 3000:
        await message.answer("⚠️ متن حداکثر ۳۰۰۰ کاراکتر است.")
        return
    await ctx.app_settings.set("membership_message", text, actor_id=message.from_user.id)
    await state.clear()
    await message.answer("✅ متن عضویت ذخیره شد.", reply_markup=back_cancel("menu:membership"))


@router.message(MembershipTextState.waiting_button)
async def member_text_button(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if not message.text:
        await message.answer("متن دکمه را بفرستید.")
        return
    text = message.text.strip()
    if not text or len(text) > 64:
        await message.answer("⚠️ متن دکمه باید بین ۱ تا ۶۴ کاراکتر باشد.")
        return
    await ctx.app_settings.set("membership_check_button", text, actor_id=message.from_user.id)
    await state.clear()
    await message.answer("✅ متن دکمه ذخیره شد.", reply_markup=back_cancel("menu:membership"))
