"""Inline keyboard callback handler."""
from __future__ import annotations

import uuid

import structlog
from telegram import Update
from telegram.ext import ContextTypes

from app.bot.messages import t
from app.bot.session import SessionManager
from app.db.models import JobType, LinkStatus, MediaStatus
from app.db.repositories.job import JobRepository
from app.db.repositories.media import MediaRepository
from app.db.repositories.user import UserRepository
from app.services.queue import QueueService
from app.utils.url import url_to_hash

log = structlog.get_logger(__name__)


async def handle_callback(
    update: Update,
    context: ContextTypes.DEFAULT_TYPE,
    session: SessionManager,
    user_repo: UserRepository,
    media_repo: MediaRepository,
    job_repo: JobRepository,
    queue: QueueService,
) -> None:
    query = update.callback_query
    if not query or not update.effective_user:
        return

    await query.answer()

    uid = update.effective_user.id
    lang = await session.get_field(uid, "lang", "ar")
    data = query.data or ""

    log.info("bot.callback", telegram_id=uid, data=data)

    if data.startswith("save:"):
        await _handle_save_mode(query, uid, lang, data, session, user_repo, media_repo, job_repo, queue)
    elif data == "dismiss":
        await query.edit_message_text(t("cancelled", lang))
        await session.update(uid, state="idle")
    elif data == "search:new":
        await session.update(uid, state="awaiting_search_query")
        await query.edit_message_text(t("search_prompt", lang))
    else:
        log.warning("bot.callback.unknown", data=data)


async def _handle_save_mode(
    query: object,
    uid: int,
    lang: str,
    data: str,
    session: SessionManager,
    user_repo: UserRepository,
    media_repo: MediaRepository,
    job_repo: JobRepository,
    queue: QueueService,
) -> None:
    from telegram import CallbackQuery
    assert isinstance(query, CallbackQuery)

    sess = await session.get(uid)
    if sess.get("state") != "awaiting_save_mode":
        await query.edit_message_text(t("error_generic", lang))
        return

    mode = data.split(":")[1]  # "link" | "media" | "cancel"

    if mode == "cancel":
        await session.update(uid, state="idle")
        await query.edit_message_text(t("cancelled", lang))
        return

    normalized_url = sess.get("pending_url", "")
    url_hash = sess.get("pending_hash", "")
    platform = sess.get("pending_platform", "web")
    db_user_id = uuid.UUID(sess["db_user_id"])

    if mode == "link":
        # Create link record
        link = await media_repo.create_link(
            user_id=db_user_id,
            url=normalized_url,
            canonical_url_hash=url_hash,
        )
        # Create job
        job = await job_repo.create(
            entity_id=link.id,
            entity_type="link",
            user_id=db_user_id,
            canonical_url_hash=url_hash,
            job_type=JobType.AI_ANALYZE,
            payload={"chat_id": uid, "lang": lang},
        )
        await queue.enqueue("ai:analyze", job_id=str(job.id))
        await query.edit_message_text(t("processing_link", lang))
        log.info("bot.save.link", telegram_id=uid, job_id=str(job.id))

    elif mode == "media":
        # Create media item record
        media = await media_repo.create_media_item(
            user_id=db_user_id,
            source_url=normalized_url,
            canonical_url_hash=url_hash,
            source_platform=platform,
        )
        # Create job
        job = await job_repo.create(
            entity_id=media.id,
            entity_type="media",
            user_id=db_user_id,
            canonical_url_hash=url_hash,
            job_type=JobType.DOWNLOAD,
            payload={"chat_id": uid, "lang": lang},
        )
        await queue.enqueue("media:download", job_id=str(job.id))
        await query.edit_message_text(t("processing", lang))
        log.info("bot.save.media", telegram_id=uid, job_id=str(job.id))

    await session.update(uid, state="idle", pending_url=None, pending_hash=None)
