"""Global caption, signature, buttons and cover settings."""

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, caption_menu, cover_menu
from app.services.templates import SUPPORTED_VARIABLES
from app.states import CaptionState, CoverState
from app.utils.validation import validate_buttons_json

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

_SETTING_BY_KIND = {
    "template": "caption_template",
    "prefix": "caption_prefix",
    "suffix": "caption_suffix",
    "signature": "brand_signature",
    "buttons": "buttons",
}

_TITLE_BY_KIND = {
    "template": "قالب کپشن",
    "prefix": "متن ابتدای کپشن",
    "suffix": "متن انتهای کپشن",
    "signature": "امضای برند",
    "buttons": "دکمه‌های زیر پست",
}


async def _caption_overview(callback: CallbackQuery, ctx: AppContext) -> None:
    template = await ctx.app_settings.get("caption_template")
    prefix = await ctx.app_settings.get("caption_prefix")
    suffix = await ctx.app_settings.get("caption_suffix")
    signature = await ctx.app_settings.get("brand_signature")
    buttons = await ctx.app_settings.get("buttons")
    variables = "، ".join(f"{{{name}}}" for name in SUPPORTED_VARIABLES)
    text = (
        "📝 تنظیمات کپشن عمومی\n\n"
        f"قالب:\n{template}\n\n"
        f"ابتدای کپشن: {prefix or '—'}\n"
        f"انتهای کپشن: {suffix or '—'}\n"
        f"امضای برند: {signature or '—'}\n"
        f"دکمه‌ها: {buttons or '[]'}\n\n"
        f"متغیرهای پشتیبانی‌شده:\n{variables}\n\n"
        "اولویت: کپشن اختصاصی پست > قالب اختصاصی پست > قالب عمومی > پیش‌فرض. "
        "متن‌ها به‌صورت plain text ارسال می‌شوند تا از تزریق HTML جلوگیری شود."
    )
    await show(callback, text, caption_menu())
    await callback.answer()


@router.callback_query(F.data == "menu:caption")
async def caption_home(callback: CallbackQuery, ctx: AppContext) -> None:
    await _caption_overview(callback, ctx)


@router.callback_query(F.data.startswith("caption:edit:"))
async def caption_edit(callback: CallbackQuery, state: FSMContext, ctx: AppContext) -> None:
    kind = callback.data.rsplit(":", 1)[1]
    key = _SETTING_BY_KIND.get(kind)
    if key is None:
        await callback.answer("گزینه نامعتبر است.", show_alert=True)
        return
    await state.set_state(CaptionState.waiting_template)
    await state.update_data(caption_kind=kind, setting_key=key)
    if kind == "buttons":
        hint = (
            "دکمه‌ها را به شکل JSON بفرستید. هر دکمه شامل text و url است:\n"
            '[{"text":"کانال ما","url":"https://t.me/example"}]\n'
            "برای حذف همه دکمه‌ها [] بفرستید."
        )
    elif kind == "template":
        hint = (
            "قالب جدید را بفرستید. از متغیرهای {title}، {description}، {video_link}، "
            "{post_id}، {publish_date}، {channel_name} و سایر متغیرهای فهرست استفاده کنید."
        )
    else:
        hint = f"{_TITLE_BY_KIND[kind]} جدید را بفرستید. برای خالی کردن /clear را بفرستید."
    await show(callback, hint, back_cancel("menu:caption"))
    await callback.answer()


@router.message(CaptionState.waiting_template)
async def caption_receive(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if not message.text:
        await message.answer("لطفاً متن بفرستید.")
        return
    data = await state.get_data()
    kind = data.get("caption_kind")
    key = data.get("setting_key")
    if not kind or not key:
        await state.clear()
        await message.answer("جلسه ویرایش منقضی شده است.")
        return
    text = message.text.strip()
    if text == "/cancel":
        await state.clear()
        await message.answer("لغو شد.")
        return
    if kind == "buttons":
        try:
            buttons = validate_buttons_json(text)
        except Exception as exc:
            await message.answer(f"⚠️ {exc}")
            return
        import json

        value = json.dumps(buttons, ensure_ascii=False)
    elif kind == "template":
        if len(text) > 4000:
            await message.answer("⚠️ قالب حداکثر ۴۰۰۰ کاراکتر است.")
            return
        value = text
    else:
        if text == "/clear":
            value = ""
        else:
            if len(text) > 1024:
                await message.answer("⚠️ این متن حداکثر ۱۰۲۴ کاراکتر است.")
                return
            value = text
    await ctx.app_settings.set(key, value, actor_id=message.from_user.id)
    await ctx.repos.audit.log(
        message.from_user.id,
        "settings.caption_update",
        entity_type="app_setting",
        entity_id=key,
    )
    await state.clear()
    await message.answer(
        f"✅ {_TITLE_BY_KIND[kind]} ذخیره شد.",
        reply_markup=back_cancel("menu:caption"),
    )


@router.callback_query(F.data == "menu:cover")
async def cover_home(
    callback: CallbackQuery, ctx: AppContext, *, answer: bool = True
) -> None:
    cover = await ctx.app_settings.get("default_cover_file_id")
    use_thumb = await ctx.app_settings.get_bool("use_media_thumbnail_as_cover", True)
    text = (
        "🖼 عکس کاور عمومی\n\n"
        f"کاور عمومی: {'ثبت شده' if cover else 'ثبت نشده'}\n"
        f"استفاده از تامبنیل ویدیو در نبود کاور: {'روشن' if use_thumb else 'خاموش'}\n\n"
        "کاور باید عکس JPEG یا PNG باشد. کاور پست بر کاور عمومی اولویت دارد. "
        "توجه: کاور جایگزین تامبنیل خود ویدیو در تلگرام می‌شود و در همه کلاینت‌ها یکسان نمایش داده نمی‌شود."
    )
    await show(callback, text, cover_menu())
    if answer:
        await callback.answer()


@router.callback_query(F.data == "cover:set")
async def cover_set(callback: CallbackQuery, state: FSMContext) -> None:
    await state.set_state(CoverState.waiting_photo)
    await show(
        callback,
        "یک عکس به‌صورت Photo بفرستید (نه فایل). برای لغو /cancel.",
        back_cancel("menu:cover"),
    )
    await callback.answer()


@router.message(CoverState.waiting_photo)
async def cover_receive(message: Message, state: FSMContext, ctx: AppContext) -> None:
    if message.text == "/cancel":
        await state.clear()
        await message.answer("لغو شد.")
        return
    if not message.photo:
        await message.answer("لطفاً یک عکس به‌صورت Photo بفرستید.")
        return
    file_id = message.photo[-1].file_id
    await ctx.app_settings.set("default_cover_file_id", file_id, actor_id=message.from_user.id)
    await ctx.repos.audit.log(
        message.from_user.id,
        "settings.cover_update",
        entity_type="app_setting",
        entity_id="default_cover_file_id",
    )
    await state.clear()
    await message.answer("✅ کاور عمومی ذخیره شد.", reply_markup=back_cancel("menu:cover"))


@router.callback_query(F.data == "cover:remove")
async def cover_remove(callback: CallbackQuery, ctx: AppContext) -> None:
    await ctx.app_settings.set("default_cover_file_id", "", actor_id=callback.from_user.id)
    await ctx.repos.audit.log(
        callback.from_user.id,
        "settings.cover_remove",
        entity_type="app_setting",
        entity_id="default_cover_file_id",
    )
    await callback.answer("کاور عمومی حذف شد.")
    await cover_home(callback, ctx, answer=False)
