#!/usr/bin/env python3
"""
process-wiki-system-changes
Pipeline for star systems data.

Modes:
  (default)     Import wiki frontmatter → systems.db, update star-map.json,
                then regenerate wiki pages from DB (infobox + topology).
  --generate    Generate wiki pages from existing DB (no import).
  --rebuild-db  Drop and recreate systems.db from wiki (fresh start).
  --stats       Show fill rates.
  --dry-run     Show what star-map.json changes would occur.

Database: server/data/systems.db
Schema:   server/data/systems-schema.sql
"""

import argparse
import json
import sys
from pathlib import Path

SCRIPT_DIR = Path(__file__).resolve().parent
WORKTREE_ROOT = (SCRIPT_DIR / "..").resolve()
STAR_MAP_PATH = WORKTREE_ROOT / "docs" / "design" / "star-map.json"
DB_PATH = WORKTREE_ROOT / "server" / "data" / "systems.db"

# Import wiki_sync
sys.path.insert(0, str(SCRIPT_DIR / "db"))
import wiki_sync


# ---------------------------------------------------------------------------
# Star-map.json update (topology fields only)
# ---------------------------------------------------------------------------

STAR_MAP_NODE_FIELDS = [
    "system_id",
    "gate_topology", "aperture_count", "gate_connections",
    "hop_distance_from_gateway",
]


def update_star_map_from_db():
    """Update star-map.json node fields from systems.db."""
    conn = wiki_sync.get_connection()

    with open(STAR_MAP_PATH, "r") as f:
        data = json.load(f)

    nodes = data["nodes"]
    updated = 0

    for node in nodes:
        sid = node["system_id"]
        row = conn.execute(
            "SELECT g.gate_topology, g.aperture_count, g.gate_connections "
            "FROM star_systems s LEFT JOIN system_gates g ON s.system_id = g.system_id "
            "WHERE s.system_id = ?", (sid,)
        ).fetchone()

        if not row:
            continue

        changed = False
        field_map = {
            "gate_topology": row["gate_topology"],
            "aperture_count": row["aperture_count"],
            "gate_connections": row["gate_connections"],
        }

        for field, val in field_map.items():
            if val is not None and node.get(field) != val:
                node[field] = val
                changed = True

        if changed:
            updated += 1

    conn.close()

    with open(STAR_MAP_PATH, "w") as f:
        json.dump(data, f, indent=2)
        f.write("\n")

    return {"nodes": len(nodes), "edges": len(data["edges"]), "updated": updated}


def dry_run_star_map():
    """Show what would change in star-map.json."""
    conn = wiki_sync.get_connection()

    with open(STAR_MAP_PATH, "r") as f:
        data = json.load(f)

    changes = []
    for node in data["nodes"]:
        sid = node["system_id"]
        row = conn.execute(
            "SELECT g.gate_topology, g.aperture_count, g.gate_connections "
            "FROM star_systems s LEFT JOIN system_gates g ON s.system_id = g.system_id "
            "WHERE s.system_id = ?", (sid,)
        ).fetchone()

        if not row:
            continue

        field_map = {
            "gate_topology": row["gate_topology"],
            "aperture_count": row["aperture_count"],
            "gate_connections": row["gate_connections"],
        }

        for field, val in field_map.items():
            if val is not None and node.get(field) != val:
                changes.append(f"  {sid}.{field}: {node.get(field)} -> {val}")

    conn.close()
    return changes


# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------


def main():
    parser = argparse.ArgumentParser(
        description="Star systems data pipeline: wiki ↔ systems.db ↔ star-map.json"
    )
    parser.add_argument("--generate", action="store_true", help="Generate wiki from DB only")
    parser.add_argument("--rebuild-db", action="store_true", help="Drop and recreate DB from wiki")
    parser.add_argument("--stats", action="store_true", help="Show fill rates")
    parser.add_argument("--dry-run", action="store_true", help="Show star-map changes without writing")
    args = parser.parse_args()

    if args.stats:
        wiki_sync.stats()
        return

    if args.generate:
        print("--- Generating wiki pages from DB ---")
        result = wiki_sync.generate_wiki()
        print(result["summary"])
        return

    if args.rebuild_db:
        print(f"--- Rebuilding {DB_PATH} from wiki ---")
        if DB_PATH.exists():
            DB_PATH.unlink()
            print("  Deleted existing DB")

    if args.dry_run:
        # Need DB populated first for dry-run to work
        if not DB_PATH.exists():
            print("No DB found. Run without --dry-run first.")
            sys.exit(1)
        changes = dry_run_star_map()
        if changes:
            print(f"star-map.json changes ({len(changes)}):")
            for c in changes:
                print(c)
        else:
            print("star-map.json: no changes")
        return

    # Full pipeline: wiki → DB → star-map.json → wiki pages
    print("=== Star Systems Pipeline ===\n")

    # Step 1: Import wiki frontmatter into DB
    print("--- Step 1: Wiki → DB ---")
    result = wiki_sync.import_from_wiki()
    if not result["ok"]:
        print(f"ERROR: {result.get('error')}")
        sys.exit(1)
    print(result["summary"])
    if result["warnings"]:
        for w in result["warnings"][:5]:
            print(f"  ⚠ {w}")
        if len(result["warnings"]) > 5:
            print(f"  ... and {len(result['warnings']) - 5} more")

    # Step 2: Update star-map.json from DB
    print("\n--- Step 2: DB → star-map.json ---")
    map_result = update_star_map_from_db()
    print(f"Nodes: {map_result['nodes']}, Edges: {map_result['edges']}, Updated: {map_result['updated']}")

    # Step 3: Generate wiki pages from DB
    print("\n--- Step 3: DB → Wiki pages ---")
    gen_result = wiki_sync.generate_wiki()
    print(gen_result["summary"])

    # Step 4: Stats
    print("\n--- Completion ---")
    wiki_sync.stats()


if __name__ == "__main__":
    main()
