"""Ticket tokens, serials and QR image generation."""
import io
import re
import secrets
from datetime import datetime
from urllib.parse import parse_qs, urlparse


def make_ticket_token():
    return "nxt_" + secrets.token_urlsafe(24)


def game_ticket_code(title):
    clean = re.sub(r"[^A-Za-z0-9]+", " ", str(title or "")).upper().strip()
    if "FIFA" in clean or clean.startswith("EA FC"):
        return "FIFA"
    if "PUBG" in clean:
        return "PUBG"
    if "TEKKEN" in clean:
        return "TEKKEN"
    return ("".join(clean.split())[:8] or "GAME")


def make_ticket_serial(registration_id, game_title="", event_date=""):
    year_match = re.search(r"\b(20\d{2})\b", str(event_date or ""))
    event_year = year_match.group(1) if year_match else str(datetime.now().year)
    return f"NX-{game_ticket_code(game_title)}-{event_year}-{int(registration_id):06d}"


def make_ticket_serial_number(event_date=""):
    year_match = re.search(r"\b(20\d{2})\b", str(event_date or ""))
    event_year = year_match.group(1) if year_match else str(datetime.now().year)
    return f"NX-{event_year}-{secrets.randbelow(900000) + 100000}"


def make_participant_ticket_serial(parent_serial, member_number):
    return make_ticket_serial_number()


def make_qualifier_ticket_serial(reg, qual, member_number):
    return make_ticket_serial_number()


def normalize_qr_token(raw):
    """Accept an opaque token, an old-style scanner URL, a ticket serial,
    or an NX-#### reference. Returns the raw text for the lookup layer."""
    value = (raw or "").strip()
    if not value:
        return ""
    if value.upper().startswith("NXT:"):
        return value[4:].strip()
    parsed = urlparse(value)
    if parsed.scheme and parsed.query:
        token = parse_qs(parsed.query).get("token", [""])[0].strip()
        if token:
            return token
    return value


def build_qr_png(value):
    try:
        import qrcode

        stream = io.BytesIO()
        image = qrcode.make(value)
        image.save(stream, format="PNG")
        return stream.getvalue()
    except ModuleNotFoundError:
        # The PDF stack already provides a QR implementation. Use it when the
        # optional Pillow/qrcode package is not installed on a deployment.
        from reportlab.graphics import renderPM
        from reportlab.graphics.barcode import qr
        from reportlab.graphics.shapes import Drawing

        code = qr.QrCodeWidget(value)
        bounds = code.getBounds()
        width, height = bounds[2] - bounds[0], bounds[3] - bounds[1]
        size = 180
        drawing = Drawing(size, size, transform=[size / width, 0, 0, size / height, 0, 0])
        drawing.add(code)
        return renderPM.drawToString(drawing, fmt="PNG")
