"""Destination channel management and permission checks."""

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, channel_item, channels_menu, confirm
from app.states import ChannelState
from app.utils.validation import parse_chat_id

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


async def _overview(callback: CallbackQuery, ctx: AppContext) -> None:
    channels = await ctx.repos.channels.list()
    if not channels:
        text = (
            "📢 کانال‌های انتشار\n\n"
            "هنوز کانالی ثبت نشده است. ربات را در کانال ادمین کنید و سپس کانال را اضافه کنید."
        )
    else:
        text = (
            "📢 کانال‌های انتشار\n\n"
            "برای ارسال پست، ربات باید در کانال ادمین باشد. "
            "علامت ✅ یعنی دسترسی ارسال تأیید شده است."
        )
    await show(callback, text, channels_menu(channels))


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


@router.callback_query(F.data == "channel:add")
async def channel_add(callback: CallbackQuery, state: FSMContext) -> None:
    await state.set_state(ChannelState.waiting_id)
    await show(
        callback,
        "شناسه عددی کانال را بفرستید (مثل -1001234567890) یا یک پیام از کانال را فوروارد کنید.\n\n"
        "ربات باید عضو کانال باشد و برای بررسی/ارسال، ادمین کانال باشد.",
        back_cancel("menu:channels"),
    )
    await callback.answer()


@router.message(ChannelState.waiting_id)
async def channel_receive(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:
        channel, created = await ctx.channels.add(chat_id, message.from_user.id)
    except Exception as exc:
        await message.answer(f"⚠️ {exc}")
        return
    await state.clear()
    status = "✅ دسترسی تأیید شد" if channel.can_post else "⚠️ دسترسی ارسال تأیید نشد"
    await message.answer(
        f"{'✅ کانال اضافه شد.' if created else 'ℹ️ کانال از قبل ثبت شده بود.'}\n"
        f"عنوان: {channel.title or '—'}\nشناسه: {channel.chat_id}\n{status}\n"
        f"جزئیات: {channel.last_error or '—'}",
        reply_markup=back_cancel("menu:channels"),
    )


@router.callback_query(F.data.startswith("channel:view:"))
async def channel_view(
    callback: CallbackQuery, ctx: AppContext, *, answer: bool = True
) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.channels.get(channel_id)
    if channel is None:
        if answer:
            await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    status = (
        "✅ ادمین/دسترسی ارسال"
        if channel.can_post
        else ("⚠️ بدون دسترسی تأییدشده" if channel.can_post is False else "❔ بررسی نشده")
    )
    text = (
        f"📢 {channel.title or channel.chat_id}\n"
        f"شناسه: {channel.chat_id}\n"
        f"نام کاربری: @{channel.username}\n" if channel.username else
        f"📢 {channel.title or channel.chat_id}\nشناسه: {channel.chat_id}\nنام کاربری: —\n"
    )
    text += (
        f"وضعیت: {'فعال' if channel.is_active else 'غیرفعال'}\n"
        f"پیش‌فرض: {'بله' if channel.is_default else 'خیر'}\n"
        f"دسترسی: {status}\n"
        f"آخرین بررسی: {channel.last_checked_at or '—'}\n"
        f"آخرین خطا: {channel.last_error or '—'}"
    )
    await show(callback, text, channel_item(channel))
    if answer:
        await callback.answer()


@router.callback_query(F.data.startswith("channel:check:"))
async def channel_check(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    ok = await ctx.channels.check(channel_id)
    await callback.answer("✅ دسترسی تأیید شد." if ok else "⚠️ دسترسی تأیید نشد.", show_alert=True)
    await channel_view(callback, ctx, answer=False)


@router.callback_query(F.data == "channel:check_all")
async def channel_check_all(callback: CallbackQuery, ctx: AppContext) -> None:
    result = await ctx.channels.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("channel:default:"))
async def channel_default(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    if not await ctx.repos.channels.set_default(channel_id):
        await callback.answer("کانال فعال پیدا نشد.", show_alert=True)
        return
    await callback.answer("کانال پیش‌فرض تغییر کرد.")
    await channel_view(callback, ctx, answer=False)


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


@router.callback_query(F.data.startswith("channel:delete:"))
async def channel_delete_ask(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    channel = await ctx.repos.channels.get(channel_id)
    if channel is None:
        await callback.answer("کانال پیدا نشد.", show_alert=True)
        return
    if await ctx.repos.channels.has_destinations(channel_id):
        await callback.answer(
            "این کانال در تاریخچه پست‌ها استفاده شده و حذف آن مجاز نیست؛ آن را غیرفعال کنید.",
            show_alert=True,
        )
        return
    await show(
        callback,
        f"آیا کانال «{channel.title or channel.chat_id}» حذف شود؟\n"
        "این عملیات فقط رکورد کانال را حذف می‌کند.",
        confirm("channel_delete", channel_id, back=f"channel:view:{channel_id}"),
    )
    await callback.answer()


@router.callback_query(F.data.startswith("confirm:channel_delete:"))
async def channel_delete_confirm(callback: CallbackQuery, ctx: AppContext) -> None:
    channel_id = int(callback.data.rsplit(":", 1)[1])
    if await ctx.repos.channels.has_destinations(channel_id):
        await callback.answer("حذف مجاز نیست؛ کانال در پست‌ها استفاده شده است.", show_alert=True)
        return
    ok = await ctx.repos.channels.remove(channel_id)
    await ctx.repos.audit.log(
        callback.from_user.id,
        "channel.delete",
        entity_type="publish_channel",
        entity_id=channel_id,
    )
    await callback.answer("حذف شد." if ok else "کانال پیدا نشد.", show_alert=True)
    await _overview(callback, ctx)
