#!/usr/bin/env python3
"""Generate the dashboard block/feedback QR set using the public CIBA URL.

The Flask process may listen on 5899 internally, but that address is never
embedded in a QR code. Feedback QR codes use the same batch ID and stage that
the dashboard's clickable feedback link uses.
"""

from pathlib import Path
from urllib.parse import urlencode

import qrcode

from config import PUBLIC_BASE_URL, public_url
from blockchain_logic import (
    Blockchain,
    get_batch_id_from_block,
    LINEAGE_P_VANNAMEI,
    LINEAGE_P_MONODON,
    LINEAGE_P_INDICUS,
    LINEAGE_XLSX_2025,
)

QR_DIR = Path("static/qr")

SPECIES_CONFIG = {
    "vannamei": ("blockchain_p_vannamei.db", LINEAGE_P_VANNAMEI),
    "monodon": ("blockchain_p_monodon.db", LINEAGE_P_MONODON),
    "indicus": ("blockchain_p_indicus.db", LINEAGE_P_INDICUS),
    "vannamei_2025": ("blockchain_p_vannamei_2025.db", LINEAGE_XLSX_2025),
}


def create_qr(filename: str, url: str):
    QR_DIR.mkdir(parents=True, exist_ok=True)
    qr = qrcode.QRCode(
        version=None,
        error_correction=qrcode.constants.ERROR_CORRECT_H,
        box_size=10,
        border=5,
    )
    qr.add_data(url)
    qr.make(fit=True)
    qr.make_image(fill_color="black", back_color="white").save(QR_DIR / filename)


def displayed_blocks(blockchain):
    """Match the dashboard's visible block list (exclude plate/customer-view)."""
    blocks = [b.to_dict(include_hash=True) for b in blockchain.chain[1:]]
    result = []
    for block in blocks:
        stage = str(block.get("stage", "")).lower()
        if ("shrimp on a plate" in stage or "customer view" in stage) and any(
            x in stage for x in ("-1", "-2", "-3")
        ):
            continue
        result.append(block)
    return result


def feedback_url(species, block):
    batch_id = get_batch_id_from_block(block) or ""
    stage = block.get("stage") or "Unknown Stage"
    query = urlencode({
        "product_id": species,
        "batch_id": batch_id,
        "stage": stage,
    })
    return public_url(f"/localhost_feedback?{query}")


def generate_all_qrs():
    """Regenerate static dashboard QR files from the exact Flask click URLs."""
    # Import the running application's already-loaded blockchain instances so
    # the QR data is derived from the same blocks used to render clickable links.
    from app import BLOCKCHAINS, format_blocks_for_template

    print(f"Public QR base URL: {PUBLIC_BASE_URL}")
    for species in ("vannamei", "monodon", "indicus", "vannamei_2025"):
        chain = BLOCKCHAINS[species]["instance"].chain
        blocks = [b.to_dict(include_hash=True) for b in chain[1:]]
        # Use the exact same filtering as the dashboard.
        visible = []
        for block in blocks:
            stage = str(block.get("stage", "")).lower()
            if ("shrimp on a plate" in stage or "customer view" in stage) and any(
                x in stage for x in ("-1", "-2", "-3")
            ):
                continue
            visible.append(block)

        # format_blocks_for_template creates the exact public click URLs and
        # synchronizes static/qr PNGs from those same URLs.
        format_blocks_for_template(visible, species)
        print(f"{species}: synchronized {len(visible)} block/feedback QR pairs")

    for lid in ("a", "b", "c", "d", "e"):
        create_qr(
            f"lineage_vannamei_2025_{lid}.png",
            public_url(f"/lineage_trace/vannamei_2025/{lid}"),
        )

    print("All static dashboard QR files now match the Flask clickable URLs exactly.")


if __name__ == "__main__":
    generate_all_qrs()
