"""Durable publication scheduling UI and scheduled-job inspection."""

from __future__ import annotations

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 JobType
from app.handlers.common import show
from app.keyboards.inline import back_menu, schedule_item, schedule_menu
from app.states import ScheduleState
from app.utils.validation import format_local, parse_local_datetime

router = Router(name="scheduling")


@router.callback_query(F.data == "menu:schedule")
async def schedule_home(
    callback: CallbackQuery, ctx: AppContext, *, answer: bool = True
) -> None:
    jobs = await ctx.repos.jobs.list_pending(20)
    text = (
        "📅 زمان‌بندی انتشار\n\n"
        "کارها در دیتابیس به‌صورت پایدار ذخیره می‌شوند و پس از راه‌اندازی مجدد از دست نمی‌روند. "
        "زمان‌ها به UTC ذخیره و به وقت محلی نمایش داده می‌شوند."
    )
    if not jobs:
        text += "\n\nهیچ کار زمان‌بندی‌شده‌ای در انتظار نیست."
    await show(callback, text, schedule_menu(jobs))
    if answer:
        await callback.answer()


@router.callback_query(F.data.startswith("schedule:view:"))
async def schedule_view(callback: CallbackQuery, ctx: AppContext) -> None:
    job_id = int(callback.data.rsplit(":", 1)[1])
    job = await ctx.repos.jobs.get(job_id)
    if job is None:
        await callback.answer("کار پیدا نشد.", show_alert=True)
        return
    text = (
        f"⏰ کار #{job.id}\n"
        f"نوع: {job.job_type.value}\n"
        f"وضعیت: {job.status.value}\n"
        f"زمان اجرا: {format_local(job.run_at, ctx.settings.tzinfo)}\n"
        f"پست: {job.post_id or '—'}\n"
        f"تلاش‌ها: {job.attempts} از {job.max_attempts}\n"
        f"آخرین خطا: {job.last_error or '—'}\n"
        f"Payload: {job.payload}"
    )
    await show(callback, text, schedule_item(job.id))
    await callback.answer()


@router.callback_query(F.data.startswith("schedule:cancel:"))
async def schedule_cancel(callback: CallbackQuery, ctx: AppContext) -> None:
    job_id = int(callback.data.rsplit(":", 1)[1])
    job = await ctx.repos.jobs.get(job_id)
    if job is None:
        await callback.answer("کار پیدا نشد.", show_alert=True)
        return
    if job.job_type == JobType.PUBLISH_POST and job.post_id:
        await ctx.posts.cancel_schedule(job.post_id, callback.from_user.id)
    else:
        await ctx.repos.jobs.cancel(job_id)
        await ctx.repos.audit.log(
            callback.from_user.id,
            "job.cancel",
            entity_type="scheduled_job",
            entity_id=job_id,
        )
    await callback.answer("زمان‌بندی لغو شد.")
    await schedule_home(callback, ctx, answer=False)


@router.message(ScheduleState.waiting_datetime)
async def schedule_receive(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if not message.text:
        await message.answer("زمان را به شکل 2026-12-31 21:30 بفرستید.")
        return
    text = message.text.strip()
    if text in {"/cancel", "❌ لغو"}:
        await state.clear()
        await message.answer("لغو شد.")
        return
    data = await state.get_data()
    post_id = int(data.get("schedule_post_id", 0))
    return_to = data.get("schedule_return", "post")
    if not post_id:
        await state.clear()
        await message.answer("جلسه منقضی شده است.")
        return
    try:
        run_at = parse_local_datetime(text, ctx.settings.tzinfo)
        job_id = await ctx.posts.schedule(post_id, run_at, message.from_user.id)
    except Exception as exc:
        await message.answer(f"⚠️ {exc}")
        return
    await state.clear()
    await message.answer(
        f"✅ انتشار برای {format_local(run_at, ctx.settings.tzinfo)} زمان‌بندی شد.\n"
        f"شناسه کار: {job_id}",
        reply_markup=back_menu(f"post:view:{post_id}" if return_to == "post" else "menu:schedule"),
    )
