from __future__ import annotations

from quart import (
    request, make_response, Blueprint, g, jsonify
)

from shared.browser.app.authz import require_admin
from shared.browser.app.redis_cacher import clear_cache

from .services.ticket import (
    get_ticket_type as svc_get_ticket_type,
    update_ticket_type as svc_update_ticket_type,
    soft_delete_ticket_type as svc_delete_ticket_type,
)

from ..ticket_types.services.tickets import (
    list_ticket_types as svc_list_ticket_types,
)
from shared.sx.helpers import sx_response


def register():
    bp = Blueprint("ticket_type", __name__, url_prefix='/<int:ticket_type_id>')

    @bp.get("/edit/")
    @require_admin
    async def get_edit(ticket_type_id: int, **kwargs):
        """Show the edit form for a ticket type."""
        ticket_type = await svc_get_ticket_type(g.s, ticket_type_id)
        if not ticket_type:
            return await make_response("Not found", 404)

        from sxc.pages.tickets import render_ticket_type_edit_form
        va = request.view_args or {}
        return sx_response(render_ticket_type_edit_form(
            ticket_type, g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
        ))

    @bp.get("/view/")
    @require_admin
    async def get_view(ticket_type_id: int, **kwargs):
        """Show the view for a ticket type."""
        ticket_type = await svc_get_ticket_type(g.s, ticket_type_id)
        if not ticket_type:
            return await make_response("Not found", 404)

        from sxc.pages.tickets import render_ticket_type_main_panel
        va = request.view_args or {}
        return sx_response(render_ticket_type_main_panel(
            ticket_type, g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
        ))

    @bp.put("/")
    @require_admin
    @clear_cache(tag="calendars", tag_scope="all")
    async def put(ticket_type_id: int, **kwargs):
        """Update a ticket type."""
        form = await request.form

        name = (form.get("name") or "").strip()
        cost_str = (form.get("cost") or "").strip()
        count_str = (form.get("count") or "").strip()

        field_errors: dict[str, list[str]] = {}

        # Validate name
        if not name:
            field_errors.setdefault("name", []).append("Please enter a ticket type name.")

        # Validate cost
        cost = None
        if not cost_str:
            field_errors.setdefault("cost", []).append("Please enter a cost.")
        else:
            try:
                cost = float(cost_str)
                if cost < 0:
                    field_errors.setdefault("cost", []).append("Cost must be positive.")
            except ValueError:
                field_errors.setdefault("cost", []).append("Please enter a valid number.")

        # Validate count
        count = None
        if not count_str:
            field_errors.setdefault("count", []).append("Please enter a ticket count.")
        else:
            try:
                count = int(count_str)
                if count < 0:
                    field_errors.setdefault("count", []).append("Count must be positive.")
            except ValueError:
                field_errors.setdefault("count", []).append("Please enter a valid whole number.")

        if field_errors:
            return jsonify({
                "message": "Please fix the highlighted fields.",
                "errors": field_errors,
            }), 422

        # Update ticket type
        ticket_type = await svc_update_ticket_type(
            g.s,
            ticket_type_id,
            name=name,
            cost=cost,
            count=count,
        )

        if not ticket_type:
            return await make_response("Not found", 404)

        # Return updated view with OOB flag
        from sxc.pages.tickets import render_ticket_type_main_panel
        va = request.view_args or {}
        return sx_response(render_ticket_type_main_panel(
            ticket_type, g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
            oob=True,
        ))

    @bp.delete("/")
    @require_admin
    @clear_cache(tag="calendars", tag_scope="all")
    async def delete(ticket_type_id: int, **kwargs):
        """Soft-delete a ticket type."""
        success = await svc_delete_ticket_type(g.s, ticket_type_id)
        if not success:
            return await make_response("Not found", 404)

        # Re-render the ticket types list
        ticket_types = await svc_list_ticket_types(g.s, g.entry.id)
        from sxc.pages.tickets import render_ticket_types_table
        va = request.view_args or {}
        return sx_response(render_ticket_types_table(
            ticket_types, g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
        ))

    return bp
