from __future__ import annotations

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

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

from .services.tickets import (
    list_ticket_types as svc_list_ticket_types,
    create_ticket_type as svc_create_ticket_type,
)

from ..ticket_type.routes import register as register_ticket_type

from shared.sx.helpers import sx_response


def register():
    bp = Blueprint("ticket_types", __name__, url_prefix='/ticket-types')

    # Register individual ticket routes
    bp.register_blueprint(
        register_ticket_type()
    )

    @bp.context_processor
    async def get_ticket_types():
        """Make ticket types available to all templates in this blueprint."""
        entry = getattr(g, "entry", None)
        if entry:
            return {
                "ticket_types": await svc_list_ticket_types(g.s, entry.id)
            }
        return {"ticket_types": []}

    @bp.post("/")
    @require_admin
    @clear_cache(tag="calendars", tag_scope="all")
    async def post(**kwargs):
        """Create a new 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

        # Create ticket type
        await svc_create_ticket_type(
            g.s,
            g.entry.id,
            name=name,
            cost=cost,
            count=count,
        )

        # Success → re-render the ticket types table
        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"),
        ))

    @bp.get("/add")
    @require_admin
    async def add_form(**kwargs):
        """Show the add ticket type form."""
        from sxc.pages.tickets import render_ticket_type_add_form
        va = request.view_args or {}
        return sx_response(render_ticket_type_add_form(
            g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
        ))

    @bp.get("/add-button")
    @require_admin
    async def add_button(**kwargs):
        """Show the add ticket type button."""
        from sxc.pages.tickets import render_ticket_type_add_button
        va = request.view_args or {}
        return sx_response(render_ticket_type_add_button(
            g.entry, g.calendar,
            va.get("day"), va.get("month"), va.get("year"),
        ))

    return bp
