from __future__ import annotations

from quart import (
    request, make_response, Blueprint, g
)
from sqlalchemy import select

from models.calendars import Calendar


from .services.calendars import (
    create_calendar as svc_create_calendar,
)

from shared.browser.app.redis_cacher import cache_page, clear_cache

from shared.browser.app.authz import require_admin
from shared.browser.app.utils.htmx import is_htmx_request
from shared.sx.helpers import sx_response


def register():
    bp = Blueprint("calendars", __name__, url_prefix='/admin')
    @bp.context_processor
    async def inject_root():
        # Must always return a dict
        return {}

    # ---------- Pages ----------

    @bp.get("/")
    @cache_page(tag="calendars")
    async def home(**kwargs):
        from shared.sx.page import get_template_context
        from sxc.pages.renders import render_calendars_page, render_calendars_oob

        ctx = await get_template_context()
        if not is_htmx_request():
            html = await render_calendars_page(ctx)
            return await make_response(html)
        else:
            sx_src = await render_calendars_oob(ctx)
            return sx_response(sx_src)


    @bp.post("/new/")
    @require_admin
    @clear_cache(tag="calendars", tag_scope="all")
    async def create_calendar(**kwargs):
        form = await request.form
        name = (form.get("name") or "").strip()

        # Get post_id from context if available (blog-embedded mode)
        post_data = getattr(g, "post_data", None)
        post_id = (post_data.get("post") or {}).get("id") if post_data else None

        if not post_id:
            # Standalone mode: post_id from form (or None — calendar without post)
            post_id = form.get("post_id")
            if post_id:
                post_id = int(post_id)

        try:
            await svc_create_calendar(g.s, post_id, name)
        except Exception as e:
            from shared.sx.jinja_bridge import render as render_comp
            return await make_response(render_comp("error-inline", message=str(e)), 422)

        from shared.sx.page import get_template_context
        from sxc.pages.renders import render_calendars_list_panel
        ctx = await get_template_context()
        html = render_calendars_list_panel(ctx)

        # Blog-embedded mode: also update post nav
        if post_data:
            from shared.services.entry_associations import get_associated_entries
            from sxc.pages.entries import render_post_nav_entries_oob

            cals = (
                await g.s.execute(
                    select(Calendar)
                    .where(Calendar.container_type == "page", Calendar.container_id == post_id, Calendar.deleted_at.is_(None))
                    .order_by(Calendar.name.asc())
                )
            ).scalars().all()

            associated_entries = await get_associated_entries(post_id)
            nav_oob = render_post_nav_entries_oob(associated_entries, cals, post_data["post"])
            html = html + nav_oob

        return sx_response(html)
    return bp
