from __future__ import annotations

from quart import Blueprint, request, g, abort

from shared.browser.app.authz import require_login
from shared.sx.helpers import sx_response, sx_call
from models import Snippet


VALID_VISIBILITY = frozenset({"private", "shared", "admin"})


async def _render_snippets():
    """Render snippets list via service data + .sx defcomp."""
    from shared.services.registry import services
    data = await services.blog_page.snippets_data(g.s)
    return sx_call("blog-snippets-content", **data)


def register():
    bp = Blueprint("snippets", __name__, url_prefix="/settings/snippets")

    @bp.delete("/<int:snippet_id>/")
    @require_login
    async def delete_snippet(snippet_id: int):
        """Delete a snippet. Owners delete their own; admins can delete any."""
        snippet = await g.s.get(Snippet, snippet_id)
        if not snippet:
            abort(404)

        is_admin = g.rights.get("admin")
        if snippet.user_id != g.user.id and not is_admin:
            abort(403)

        await g.s.delete(snippet)
        await g.s.flush()

        return sx_response(await _render_snippets())

    @bp.patch("/<int:snippet_id>/visibility/")
    @require_login
    async def patch_visibility(snippet_id: int):
        """Change snippet visibility. Admin only."""
        if not g.rights.get("admin"):
            abort(403)

        snippet = await g.s.get(Snippet, snippet_id)
        if not snippet:
            abort(404)

        form = await request.form
        visibility = form.get("visibility", "").strip()

        if visibility not in VALID_VISIBILITY:
            abort(400)

        snippet.visibility = visibility
        await g.s.flush()

        return sx_response(await _render_snippets())

    return bp
