#!/usr/bin/env python3
"""
Build script for Avery's Art Journey PWA (Phase 6).

Reads all data sources and produces a single self-contained avery_pwa.html
with data inlined as JSON. Also produces avery_manifest.json.

Data sources:
  - map_data.json        (galleries, advisory, approachable, routes, field_capture)
  - deck_data.json       (65 drill cards)
  - avery_pipeline.db    (MissionPacket-backed Kanban)

Output:
  - avery_pwa.html   — complete PWA, all data inlined, service worker registered
  - avery_manifest.json — Web App Manifest

Usage:
  python3 build_pwa.py
"""

import json
import sqlite3
import sys
from pathlib import Path

HERE = Path("/Users/brians/Documents/AveryArt")
MAP_JSON = HERE / "map_data.json"
DECK_JSON = HERE / "deck_data.json"
PIPE_DB = HERE / "avery_pipeline.db"
PWA_TEMPLATE = HERE / "avery_pwa.html"
SW_FILE = HERE / "avery_sw.js"
MANIFEST = HERE / "avery_manifest.json"

OUT_HTML = HERE / "avery_pwa.html"


def load_map_data() -> dict:
    with open(MAP_JSON, "r", encoding="utf-8") as f:
        return json.loads(f.read())


def load_deck_data() -> list:
    with open(DECK_JSON, "r", encoding="utf-8") as f:
        return json.loads(f.read())


def load_pipeline_data() -> dict:
    """Extract packets from the pipeline DB for inlining."""
    if not PIPE_DB.exists():
        return {"packets": []}
    conn = sqlite3.connect(PIPE_DB)
    conn.row_factory = sqlite3.Row
    rows = conn.execute(
        """SELECT
           packet_id, gallery_id, gallery_name, scope, budget, expiry,
           denied_actions, approval_required, content_hash,
           created_at, status, claimed_by, column, wip_slot,
           reason_closed, updated_at
         FROM packets"""
    ).fetchall()
    conn.close()

    packets = []
    for row in rows:
        denied = row["denied_actions"]
        try:
            denied = json.loads(denied) if denied else []
        except (json.JSONDecodeError, TypeError):
            denied = []

        packets.append({
            "id": row["packet_id"],
            "gallery_id": row["gallery_id"],
            "gallery_name": row["gallery_name"],
            "column": row["column"],
            "priority": 0,
            "status": row["status"],
            "wip_slot": row["wip_slot"],
            "reason_closed": row["reason_closed"] or "",
            "comp_model": "",
            "degree_bar": "",
            "certifiable_comp": False,
            "drill_score": 0,
            "named_human": "",
            "current_show_hook": "",
            "artist_brief": "",
            "opener": "",
        })

    # Enrich with card_faces data
    conn = sqlite3.connect(PIPE_DB)
    conn.row_factory = sqlite3.Row
    faces = conn.execute(
        """SELECT packet_id, priority, drill_score, opener,
           current_show_hook, artist_brief, visit_obs,
           named_human, comp_model, degree_bar, certifiable_comp
         FROM card_faces"""
    ).fetchall()
    conn.close()

    face_map = {}
    for f in faces:
        denied = f["visit_obs"]
        try:
            denied = json.loads(denied) if denied else []
        except (json.JSONDecodeError, TypeError):
            denied = []
        face_map[f["packet_id"]] = {
            "priority": f["priority"],
            "drill_score": f["drill_score"],
            "opener": f["opener"] or "",
            "current_show_hook": f["current_show_hook"] or "",
            "artist_brief": f["artist_brief"] or "",
            "visit_observations": denied,
            "named_human": f["named_human"] or "",
            "comp_model": f["comp_model"] or "",
            "degree_bar": f["degree_bar"] or "",
            "certifiable_comp": bool(f["certifiable_comp"]),
        }

    for p in packets:
        if p["id"] in face_map:
            f = face_map[p["id"]]
            p["priority"] = f["priority"]
            p["drill_score"] = f["drill_score"]
            p["opener"] = f["opener"]
            p["current_show_hook"] = f["current_show_hook"]
            p["artist_brief"] = f["artist_brief"]
            p["named_human"] = f["named_human"]
            p["comp_model"] = f["comp_model"]
            p["degree_bar"] = f["degree_bar"]
            p["certifiable_comp"] = f["certifiable_comp"]

    return {"packets": packets}


def build_pwa_html(map_data: dict, deck_data: list, pipeline_data: dict) -> str:
    """Produce the final PWA HTML with data inlined."""
    template = PWA_TEMPLATE.read_text(encoding="utf-8")

    # Serialize data as JSON literals
    map_json = json.dumps(map_data, ensure_ascii=False)
    deck_json = json.dumps(deck_data, ensure_ascii=False)
    pipe_json = json.dumps(pipeline_data, ensure_ascii=False)

    # The template uses __MAP_JSON__, __DRILL_JSON__, __PIPELINE_JSON__ placeholders
    html = template
    html = html.replace("const __MAP_JSON__ = MAP_DATA;", f"const MAP_DATA = {map_json};")
    html = html.replace("const __DRILL_JSON__ = DRILL_DATA;", f"const DRILL_DATA = {deck_json};")
    html = html.replace("const __PIPELINE_JSON__ = PIPELINE_DATA;", f"const PIPELINE_DATA = {pipe_json};")

    return html


def main():
    print("=== Building Avery's Art Journey PWA (Phase 6) ===\n")

    map_data = load_map_data()
    print(f"Loaded map_data.json: {len(map_data['galleries'])} galleries, "
          f"{len(map_data['routes'])} routes, "
          f"{len(map_data['advisory'])} advisory sections, "
          f"{len(map_data['approachable'])} approachable sections")

    deck_data = load_deck_data()
    print(f"Loaded deck_data.json: {len(deck_data)} drill cards")

    pipeline_data = load_pipeline_data()
    print(f"Loaded pipeline: {len(pipeline_data['packets'])} packets")

    html = build_pwa_html(map_data, deck_data, pipeline_data)
    OUT_HTML.write_text(html, encoding="utf-8")
    print(f"\nWrote {OUT_HTML} — {len(html):,} bytes")
    print(f"  Service worker: {SW_FILE}")
    print(f"  Manifest: {MANIFEST}")

    # Quick sanity check: look for key functions in the output
    checks = [
        ("Today tab render", "renderToday()" in html),
        ("Map tab render", "renderMap()" in html),
        ("Drill tab render", "renderDrill()" in html),
        ("Pipeline tab render", "renderPipeline()" in html),
        ("Tab switching", "showTab(" in html),
        ("Two-price rule banner", 'dual-price' in html and 'show' in html),
        ("Service worker register", "navigator.serviceWorker.register" in html),
        ("Offline banner", "offlineBanner" in html),
        ("Gallery card component", "galleryCard(" in html),
        ("Drill deck selector", "deck-chip" in html),
        ("Kanban board render", "pipe-board" in html),
        ("Map iframe embed", "mapFrame" in html),
        ("Map data injected", str(len(map_data["galleries"])) in html),
        ("Drill data injected", str(len(deck_data)) in html),
        ("Pipeline data injected", str(len(pipeline_data["packets"])) in html),
        ("No external data fetch (offline-first)", "fetch('map_data.json')" not in html),
        ("Two-price rule text", "Arlene Shechet" in html),
        ("En-route button", "enroute-btn" in html),
    ]

    print("\n=== PWA Sanity Checks ===")
    all_ok = True
    for name, ok in checks:
        status = "✓" if ok else "✗"
        print(f"  {status}  {name}")
        if not ok:
            all_ok = False

    print(f"\n{'All checks pass ✓' if all_ok else 'Some checks failed ✗'}")
    print(f"\nNext: serve with 'python3 -m http.server 8080' from {HERE}")
    print("Then open http://localhost:8080/avery_pwa.html")


if __name__ == "__main__":
    main()
