#!/usr/bin/env python3
"""Verify that dashboard QR targets exactly match their clickable public URLs.

This checks the URL contract used by the Flask templates and QR generator.
It does not require the public server to be reachable; it validates that the
QR images and generated links use the same CIBA public URL.
"""
from pathlib import Path
from urllib.parse import urlencode
from config import public_url
from blockchain_logic import (
    Blockchain, LINEAGE_P_VANNAMEI, LINEAGE_P_MONODON,
    LINEAGE_P_INDICUS, LINEAGE_XLSX_2025,
)
try:
    from pyzbar.pyzbar import decode
    from PIL import Image
except ImportError:
    raise SystemExit("Install QR verification dependencies: pip install pyzbar pillow")

ROOT = Path(__file__).resolve().parent
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 displayed_blocks(blockchain):
    result = []
    for b in blockchain.chain[1:]:
        d = b.to_dict(include_hash=True)
        stage = str(d.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(d)
    return result

def qr_value(path):
    decoded = decode(Image.open(path))
    if not decoded:
        return None
    return decoded[0].data.decode("utf-8")

def main():
    mismatches = []
    checked = 0
    for species, (db, lineage) in CONFIG.items():
        blocks = displayed_blocks(Blockchain(db_name=db, sample_lineage=lineage))
        for idx, block in enumerate(blocks, 1):
            expected_block = public_url(f"/lineage_block/{species}/{idx}")
            expected_feedback = public_url(
                "/localhost_feedback?" + urlencode({
                    "product_id": species,
                    "batch_id": block.get("data_id") or "",
                    "stage": block.get("stage") or "Unknown Stage",
                })
            )
            pairs = [
                (ROOT / "static/qr" / f"blockdata_{species}_{idx}.png", expected_block),
                (ROOT / "static/qr" / f"feedback_{species}_{idx}.png", expected_feedback),
            ]
            for path, expected in pairs:
                actual = qr_value(path)
                checked += 1
                if actual != expected:
                    mismatches.append((str(path.relative_to(ROOT)), actual, expected))

    for lid in "abcde":
        path = ROOT / "static/qr" / f"lineage_vannamei_2025_{lid}.png"
        expected = public_url(f"/lineage_trace/vannamei_2025/{lid}")
        checked += 1
        if qr_value(path) != expected:
            mismatches.append((str(path.relative_to(ROOT)), qr_value(path), expected))

    print(f"Public base: {public_url('/')}")
    print(f"QR targets checked: {checked}")
    if mismatches:
        print(f"FAIL: {len(mismatches)} QR/click mismatches")
        for item in mismatches[:20]:
            print(" ", item)
        raise SystemExit(1)
    print("PASS: every dashboard QR encodes exactly the same public URL used by its clickable link.")
    print("PASS: no internal IP/port is used by dashboard QR targets.")

if __name__ == "__main__":
    main()
