"""Source chat registration and received-media browsing."""

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.database.models import MediaStatus
from app.handlers.common import show
from app.keyboards.inline import (
    back_cancel,
    media_item,
    media_list,
    media_menu,
    source_item,
    source_list,
)
from app.states import SourceChatState
from app.utils.validation import parse_chat_id

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

PAGE_SIZE = 6


@router.callback_query(F.data == "menu:media")
async def media_home(callback: CallbackQuery, ctx: AppContext) -> None:
    sources = await ctx.repos.media.list_sources()
    ready = await ctx.repos.media.count([MediaStatus.READY])
    total = await ctx.repos.media.count()
    await show(
        callback,
        "🎬 مدیریت فیلم‌ها\n\n"
        f"گروه‌های منبع: {len(sources)}\n"
        f"فایل‌های آماده: {ready}\n"
        f"کل فایل‌ها: {total}\n\n"
        "برای دریافت ویدیوهای جدید، ربات باید در گروه منبع باشد. "
        "فقط پیام‌های جدیدی که Bot API در اختیار ربات قرار می‌دهد پردازش می‌شوند؛ "
        "تاریخچه قدیمی به‌صورت خودکار قابل دریافت نیست.",
        media_menu(),
    )
    await callback.answer()


@router.callback_query(F.data == "source:add")
async def source_add(callback: CallbackQuery, state: FSMContext) -> None:
    await state.set_state(SourceChatState.waiting_id)
    await show(
        callback,
        "شناسه عددی گروه/کانال منبع را بفرستید (مثل `-1001234567890`)\n"
        "یا یک پیام از آن گروه را به اینجا فوروارد کنید.\n\n"
        "ربات باید عضو گروه باشد. برای دریافت همه پیام‌ها، Privacy Mode ربات را در BotFather غیرفعال کنید.",
        back_cancel("menu:media"),
    )
    await callback.answer()


@router.message(SourceChatState.waiting_id)
async def source_add_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
    title: str | None = None
    if message.forward_from_chat is not None:
        chat_id = message.forward_from_chat.id
        title = message.forward_from_chat.title
    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:
        source, created = await ctx.media.register_source(
            chat_id, added_by=message.from_user.id, title=title
        )
    except Exception as exc:
        await message.answer(f"⚠️ {exc}")
        return
    await state.clear()
    await message.answer(
        f"{'✅ گروه منبع اضافه شد.' if created else 'ℹ️ این گروه از قبل ثبت شده بود.'}\n"
        f"شناسه: `{chat_id}`\nعنوان: {getattr(source, 'title', None) or '—'}\n"
        "دریافت خودکار روشن است."
    )
    await ctx.repos.audit.log(
        message.from_user.id,
        "source_chat.add_from_panel",
        entity_type="source_chat",
        entity_id=chat_id,
    )


@router.callback_query(F.data == "source:list")
async def source_list_view(callback: CallbackQuery, ctx: AppContext) -> None:
    sources = await ctx.repos.media.list_sources()
    if not sources:
        await show(callback, "هیچ گروه منبعی ثبت نشده است.", back_cancel("menu:media"))
        await callback.answer()
        return
    lines = ["📋 گروه‌های منبع:"]
    for source in sources:
        lines.append(
            f"• {source.title or source.chat_id} | `{source.chat_id}` | "
            f"{'فعال' if source.is_active else 'غیرفعال'} | "
            f"دریافت {'روشن' if source.auto_ingest else 'خاموش'}"
        )
    await show(callback, "\n".join(lines), source_list(sources))
    await callback.answer()


@router.callback_query(F.data.startswith("source:view:"))
async def source_view(
    callback: CallbackQuery, ctx: AppContext, *, answer: bool = True
) -> None:
    source_id = int(callback.data.rsplit(":", 1)[1])
    source = await ctx.repos.media.get_source_by_id(source_id)
    if source is None:
        if answer:
            await callback.answer("گروه پیدا نشد.", show_alert=True)
        return
    await show(
        callback,
        f"📣 {source.title or source.chat_id}\n"
        f"شناسه: `{source.chat_id}`\n"
        f"وضعیت: {'فعال' if source.is_active else 'غیرفعال'}\n"
        f"دریافت خودکار: {'روشن' if source.auto_ingest else 'خاموش'}\n"
        f"آخرین خطا: {source.last_error or '—'}",
        source_item(source),
    )
    if answer:
        await callback.answer()


@router.callback_query(F.data.startswith("source:toggle:"))
async def source_toggle(callback: CallbackQuery, ctx: AppContext) -> None:
    source_id = int(callback.data.rsplit(":", 1)[1])
    source = await ctx.repos.media.get_source_by_id(source_id)
    if source is None:
        await callback.answer("گروه پیدا نشد.", show_alert=True)
        return
    await ctx.repos.media.update_source_by_id(source_id, is_active=not source.is_active)
    await callback.answer("وضعیت تغییر کرد.")
    await source_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("source:auto:"))
async def source_auto(callback: CallbackQuery, ctx: AppContext) -> None:
    source_id = int(callback.data.rsplit(":", 1)[1])
    source = await ctx.repos.media.get_source_by_id(source_id)
    if source is None:
        await callback.answer("گروه پیدا نشد.", show_alert=True)
        return
    await ctx.repos.media.update_source_by_id(
        source_id, auto_ingest=not source.auto_ingest
    )
    await ctx.repos.audit.log(
        callback.from_user.id,
        "source_chat.auto_ingest",
        entity_type="source_chat",
        entity_id=source_id,
        details={"enabled": not source.auto_ingest},
    )
    await callback.answer("دریافت خودکار تغییر کرد.")
    await source_view(callback, ctx, answer=False)


@router.callback_query(F.data.startswith("media:list:"))
async def media_list_view(callback: CallbackQuery, ctx: AppContext) -> None:
    _, _, filter_name, page_raw = callback.data.split(":", 3)
    try:
        page = max(0, int(page_raw))
    except ValueError:
        page = 0
    statuses: list[MediaStatus] | None
    if filter_name == "ready":
        statuses = [MediaStatus.READY]
    elif filter_name == "error":
        statuses = [MediaStatus.INVALID, MediaStatus.ERROR]
    else:
        statuses = None
    items = await ctx.repos.media.list(
        statuses=statuses, limit=PAGE_SIZE + 1, offset=page * PAGE_SIZE
    )
    has_next = len(items) > PAGE_SIZE
    items = items[:PAGE_SIZE]
    total = await ctx.repos.media.count(statuses)
    if not items:
        await show(
            callback,
            "در این دسته فایلی وجود ندارد.",
            back_cancel("menu:media"),
        )
        await callback.answer()
        return
    lines = [f"🎬 فایل‌ها (صفحه {page + 1}، مجموع {total}):"]
    for media in items:
        status = {
            "READY": "آماده",
            "IN_USE": "در استفاده",
            "INVALID": "نامعتبر",
            "ERROR": "خطا",
            "RECEIVED": "دریافت‌شده",
            "IGNORED": "نادیده",
        }.get(media.status.value, media.status.value)
        size = f"{media.file_size / 1024 / 1024:.1f}MB" if media.file_size else "—"
        lines.append(
            f"• #{media.id} | {media.file_name or 'ویدیو'} | {status} | {size}"
        )
    await show(callback, "\n".join(lines), media_list(
        items, page=page, filter_name=filter_name, has_next=has_next
    ))
    await callback.answer()


@router.callback_query(F.data.startswith("media:view:"))
async def media_view(callback: CallbackQuery, ctx: AppContext) -> None:
    media_id = int(callback.data.rsplit(":", 1)[1])
    media = await ctx.repos.media.get(media_id, with_source=True)
    if media is None:
        await callback.answer("فایل پیدا نشد.", show_alert=True)
        return
    source_title = media.source_chat.title if media.source_chat else "—"
    size = f"{media.file_size / 1024 / 1024:.1f} MB" if media.file_size else "—"
    duration = f"{media.duration_seconds:.0f} ثانیه" if media.duration_seconds else "—"
    text = (
        f"🎬 فایل #{media.id}\n"
        f"عنوان فایل: {media.file_name or '—'}\n"
        f"گروه منبع: {source_title}\n"
        f"نوع: {media.media_type} / {media.mime_type or '—'}\n"
        f"حجم: {size}\nمدت: {duration}\n"
        f"وضعیت: {media.status.value}\n"
        f"کپشن اصلی: {(media.original_caption or '—')[:300]}"
    )
    if media.error_message:
        text += f"\n⚠️ خطا: {media.error_message}"
    await show(
        callback,
        text,
        media_item(media.id, ready=media.status in {MediaStatus.READY, MediaStatus.IN_USE}),
    )
    await callback.answer()


@router.callback_query(F.data == "media:stats")
async def media_stats(callback: CallbackQuery, ctx: AppContext) -> None:
    counts = await ctx.repos.stats.media_status_counts()
    labels = {
        "READY": "آماده",
        "IN_USE": "در استفاده",
        "INVALID": "نامعتبر",
        "ERROR": "خطا",
        "RECEIVED": "دریافت‌شده",
        "IGNORED": "نادیده",
    }
    text = "📊 وضعیت فایل‌ها:\n" + "\n".join(
        f"• {labels.get(key, key)}: {value}" for key, value in counts.items()
    )
    if not counts:
        text += "\nهنوز فایلی ثبت نشده است."
    await show(callback, text, back_cancel("menu:media"))
    await callback.answer()
