"""Routes: admin tickets"""
from datetime import datetime
from flask import Response, flash, redirect, render_template, request, url_for

from nexora.config import logger
from nexora.core import app
from nexora.database.connection import db, execute, query
from nexora.services.qualifiers import qualifier_entry_list, qualifiers_enabled
from nexora.services.ticket_codes import build_qr_png
from nexora.services.registrations import registration_details
from nexora.services.tickets import participant_ticket_qr_payload, team_ticket_qr_items, ticket_qr_payload
from nexora.services.pdf_tickets import build_ticket_pdf
from nexora.security.permissions import admin_required, permission_required
from nexora.database.schema import _create_entry_tickets_for_reg


@app.route("/admin/registrations/<int:reg_id>/ticket.pdf", methods=["GET", "POST"])
@admin_required
@permission_required("download_pdf_tickets")
def registration_ticket_pdf(reg_id):
    details = registration_details(reg_id)
    settings = query("SELECT * FROM settings WHERE id = 1", one=True)
    if not details:
        flash("Registration not found.", "danger")
        return redirect(url_for("admin_registrations"))

    # If POST, save qualifier venue/date overrides and selected qualifiers from the modal
    if request.method == "POST":
        include_q = request.form.get("include_qualifiers", "1") == "1"
        if not include_q:
            # No qualifier passes — clear selected qualifiers
            execute("UPDATE registrations SET selected_qualifiers = '' WHERE id = ?", (reg_id,))
        else:
            # Handle no-qualifier mode: create qualifiers on-the-fly from nq_* fields
            nq_venue = (request.form.get("nq_venue") or "").strip()
            nq_date = (request.form.get("nq_date") or "").strip()
            nq_time = (request.form.get("nq_time") or "").strip()
            if nq_venue or nq_date:
                date_part = nq_date
                if nq_time:
                    date_part = f"{nq_date} {nq_time}" if nq_date else nq_time
                game_id = details.get("game_id") if details else None
                max_num = query("SELECT MAX(qualifier_number) AS mx FROM qualifiers WHERE game_id = ?", (game_id,), one=True)
                next_num = int((max_num["mx"] or 0) + 1) if max_num else 1
                qid_val = execute(
                    """INSERT INTO qualifiers (game_id, qualifier_name, qualifier_number, fee, location, qualifier_date, active, created_at)
                       VALUES (?, ?, ?, 0, ?, ?, 1, ?)""",
                    (game_id, f"Qualifier {next_num}", next_num, nq_venue or "TBD", date_part or "", datetime.now().isoformat(timespec="seconds")),
                )
                existing_sel = (details.get("selected_qualifiers") or "").strip()
                new_sel = f"{existing_sel},{qid_val}" if existing_sel else str(qid_val)
                execute("UPDATE registrations SET selected_qualifiers = ? WHERE id = ?", (new_sel, reg_id))

            # Save selected qualifiers from checkbox form
            selected_q = request.form.getlist("q_selected")
            # Preserve any previously selected qualifiers not in the form (hidden ones)
            existing_sel = (details.get("selected_qualifiers") or "").strip()
            existing_ids = [x.strip() for x in existing_sel.split(",") if x.strip()]
            form_ids = [x.strip() for x in selected_q if x.strip()]
            merged = list(dict.fromkeys(existing_ids + form_ids))
            execute(
                "UPDATE registrations SET selected_qualifiers = ? WHERE id = ?",
                (",".join(merged), reg_id),
            )

            # Save editable qualifier fields (name/venue/date/time)
            override_names = request.form.getlist("q_name")
            overrides = request.form.getlist("q_venue")
            override_dates = request.form.getlist("q_date")
            override_times = request.form.getlist("q_time")
            override_ids = request.form.getlist("q_id")
            for i, qid in enumerate(override_ids):
                if not qid:
                    continue
                name_val = (override_names[i] if i < len(override_names) else "").strip()
                venue_val = (overrides[i] if i < len(overrides) else "").strip()
                date_val = (override_dates[i] if i < len(override_dates) else "").strip()
                time_val = (override_times[i] if i < len(override_times) else "").strip()
                date_part = date_val
                if time_val:
                    date_part = f"{date_val} {time_val}" if date_val else time_val
                execute(
                    "UPDATE qualifiers SET qualifier_name = ?, location = ?, qualifier_date = ? WHERE id = ?",
                    (name_val or "Qualifier", venue_val or "TBD", date_part or "", int(qid)),
                )

            # Handle custom qualifiers (cq_name_*, cq_venue_*, etc.)
            import re as _re
            cq_keys = [k for k in request.form if _re.match(r"^cq_name_\d+$", k)]
            for k in cq_keys:
                idx = k.split("_")[-1]
                cq_name = (request.form.get(f"cq_name_{idx}") or "").strip()
                cq_venue = (request.form.get(f"cq_venue_{idx}") or "").strip()
                cq_date = (request.form.get(f"cq_date_{idx}") or "").strip()
                cq_time = (request.form.get(f"cq_time_{idx}") or "").strip()
                if not cq_name:
                    continue
                date_part = cq_date
                if cq_time:
                    date_part = f"{cq_date} {cq_time}" if cq_date else cq_time
                game_id = details.get("game_id") if details else None
                max_num = query("SELECT MAX(qualifier_number) AS mx FROM qualifiers WHERE game_id = ?", (game_id,), one=True)
                next_num = int((max_num["mx"] or 0) + 1) if max_num else 1
                qid_val = execute(
                    """INSERT INTO qualifiers (game_id, qualifier_name, qualifier_number, fee, location, qualifier_date, active, created_at)
                       VALUES (?, ?, ?, 0, ?, ?, 1, ?)""",
                    (game_id, cq_name, next_num, cq_venue or "TBD", date_part or "", datetime.now().isoformat(timespec="seconds")),
                )
                existing_sel = (details.get("selected_qualifiers") or "").strip()
                new_sel = f"{existing_sel},{qid_val}" if existing_sel else str(qid_val)
                execute("UPDATE registrations SET selected_qualifiers = ? WHERE id = ?", (new_sel, reg_id))
        # Ensure qualifier_entry_tickets exist for this registration
        try:
            with db() as conn:
                reg_row = conn.execute("SELECT * FROM registrations WHERE id = ?", (reg_id,)).fetchone()
                if reg_row:
                    _create_entry_tickets_for_reg(conn, reg_row)
                    conn.commit()
        except Exception as exc:
            logger.exception("Failed to create entry tickets for reg %s: %s", reg_id, exc)
        # Reload details after saving
        details = registration_details(reg_id)

    # Ensure qualifier_entry_tickets exist (for both GET and POST paths)
    if details and details.get("selected_qualifiers"):
        try:
            with db() as conn:
                reg_row = conn.execute("SELECT * FROM registrations WHERE id = ?", (reg_id,)).fetchone()
                if reg_row:
                    _create_entry_tickets_for_reg(conn, reg_row)
                    conn.commit()
                    details = registration_details(reg_id)
        except Exception as exc:
            logger.exception("Entry ticket creation failed for reg %s: %s", reg_id, exc)

    pdf = build_ticket_pdf(details, dict(settings) if settings else {})
    return Response(
        pdf,
        mimetype="application/pdf",
        headers={"Content-Disposition": f"attachment; filename={details['ticket_number']}.pdf"},
    )


@app.route("/admin/registrations/<int:reg_id>/ticket")
@admin_required
@permission_required("download_pdf_tickets")
def registration_ticket_html(reg_id):
    details = registration_details(reg_id)
    if not details:
        flash("Registration not found.", "danger")
        return redirect(url_for("admin_registrations"))
    if details.get("selected_qualifiers"):
        try:
            with db() as conn:
                reg_row = conn.execute("SELECT * FROM registrations WHERE id = ?", (reg_id,)).fetchone()
                if reg_row:
                    _create_entry_tickets_for_reg(conn, reg_row)
                    conn.commit()
                    details = registration_details(reg_id)
        except Exception as exc:
            logger.exception("Entry ticket creation failed for ticket HTML reg %s: %s", reg_id, exc)
    member_qrs = team_ticket_qr_items(details)
    qualifier_sections = qualifier_entry_list(details)
    qualifier_list = []
    if details.get("selected_qualifiers"):
        q_ids = [x.strip() for x in details["selected_qualifiers"].split(",") if x.strip()]
        if q_ids:
            placeholders = ",".join("?" * len(q_ids))
            qualifier_list = query(
                f"SELECT * FROM qualifiers WHERE id IN ({placeholders}) ORDER BY qualifier_number",
                [int(x) for x in q_ids],
            )
            qualifier_list = [dict(q) for q in qualifier_list]
    game_id = details.get("game_id")
    game = query("SELECT * FROM games WHERE id = ?", (game_id,), one=True) if game_id else None
    game_has_qualifiers = qualifiers_enabled(game) if game else False
    game_qualifier_list = []
    if game_has_qualifiers and game_id:
        game_qualifier_list = [dict(q) for q in query(
            "SELECT id, qualifier_name, qualifier_number, fee, location, qualifier_date FROM qualifiers WHERE game_id = ? AND active = 1 ORDER BY qualifier_number",
            (game_id,),
        )]
    return render_template(
        "ticket_print.html",
        details=details,
        reg_id=reg_id,
        member_qrs=member_qrs,
        qualifier_list=qualifier_list,
        qualifier_sections=qualifier_sections,
        game_has_qualifiers=game_has_qualifiers,
        game_qualifier_list=game_qualifier_list,
    )


@app.route("/admin/registrations/<int:reg_id>/qr.png")
@admin_required
@permission_required("download_pdf_tickets")
def registration_qr_png(reg_id):
    details = registration_details(reg_id)
    if not details:
        return Response(status=404)
    return Response(build_qr_png(ticket_qr_payload(details)), mimetype="image/png")


@app.route("/admin/registrations/<int:reg_id>/participant-qr.png")
@admin_required
@permission_required("download_pdf_tickets")
def registration_participant_qr_png(reg_id):
    details = registration_details(reg_id)
    if not details:
        return Response(status=404)
    return Response(build_qr_png(participant_ticket_qr_payload(details, 1)), mimetype="image/png")


@app.route("/admin/member-tickets/<int:ticket_id>/qr.png")
@admin_required
@permission_required("download_pdf_tickets")
def member_ticket_qr_png(ticket_id):
    ticket = query("SELECT ticket_token FROM member_tickets WHERE id = ?", (ticket_id,), one=True)
    if not ticket or not ticket["ticket_token"]:
        return Response(status=404)
    return Response(build_qr_png(f"NXT:{ticket['ticket_token']}"), mimetype="image/png")


@app.route("/qualifier-entry-qr/<int:entry_id>.png")
@admin_required
@permission_required("download_pdf_tickets")
def qualifier_entry_qr_png(entry_id):
    """QR for a single (qualifier x participant) entry ticket.

    Encodes NQ:{opaque token} which the scanner resolves to that exact
    qualifier entry record — independent check-in per qualifier/member.
    """
    entry = query(
        "SELECT * FROM qualifier_entry_tickets WHERE id = ? AND COALESCE(ticket_token, '') != ''",
        (entry_id,),
        one=True,
    )
    if not entry:
        return Response(status=404)
    return Response(build_qr_png(f"NQ:{entry['ticket_token']}"), mimetype="image/png")


@app.route("/qualifier-qr/<int:reg_id>/<int:qualifier_id>.png")
@admin_required
@permission_required("download_pdf_tickets")
def qualifier_qr_png(reg_id, qualifier_id):
    """Backwards-compatible leader qualifier QR (member_number 1)."""
    entry = query(
        """SELECT * FROM qualifier_entry_tickets
           WHERE registration_id = ? AND qualifier_id = ? AND member_number = 1
           AND COALESCE(ticket_token, '') != ''""",
        (reg_id, qualifier_id),
        one=True,
    )
    if not entry:
        return Response(status=404)
    return Response(build_qr_png(f"NQ:{entry['ticket_token']}"), mimetype="image/png")
