#!/usr/bin/env python3
"""
Pokemon Overlay Studio - Game Sync Companion
Watches party_data.json and pushes updates to the overlay API.

Usage:
    python sync.py --url https://yoursite.com --slug my-run --key YOUR_SYNC_KEY --file party_data.json
"""

import argparse
import json
import os
import sys
import time
import urllib.request
import urllib.error


def read_party_file(path):
    """Read and parse the party data JSON file."""
    try:
        with open(path, "r") as f:
            return json.load(f)
    except (json.JSONDecodeError, FileNotFoundError, IOError):
        return None


def push_to_api(base_url, slug, sync_key, data):
    """POST party data to the game-sync API endpoint."""
    url = f"{base_url.rstrip('/')}/api/game-sync/{slug}"
    body = json.dumps(data).encode("utf-8")

    req = urllib.request.Request(
        url,
        data=body,
        headers={
            "Content-Type": "application/json",
            "User-Agent": "PokeOverlayStudio-Sync/1.0",
            "Accept": "application/json",
            "x-sync-key": sync_key,
        },
        method="POST",
    )

    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            return resp.status, resp.read().decode("utf-8")
    except urllib.error.HTTPError as e:
        return e.code, e.read().decode("utf-8", errors="replace")
    except urllib.error.URLError as e:
        return None, str(e.reason)
    except Exception as e:
        return None, str(e)


def main():
    parser = argparse.ArgumentParser(description="Pokemon Overlay Studio - Game Sync")
    parser.add_argument("--url", required=True, help="Base URL of your overlay site")
    parser.add_argument("--slug", required=True, help="Project slug")
    parser.add_argument("--key", required=True, help="Sync key from the editor")
    parser.add_argument("--file", default="party_data.json", help="Path to party_data.json")
    parser.add_argument("--interval", type=float, default=1.0, help="Poll interval in seconds")
    args = parser.parse_args()

    print(f"Pokemon Overlay Studio - Game Sync")
    print(f"  URL:  {args.url}")
    print(f"  Slug: {args.slug}")
    print(f"  File: {args.file}")
    print(f"  Poll: every {args.interval}s")
    print()

    if not os.path.exists(args.file):
        print(f"Waiting for {args.file} to appear...")
        while not os.path.exists(args.file):
            time.sleep(1)
        print(f"Found {args.file}!")

    last_mtime = 0
    last_content = None
    sync_count = 0
    error_count = 0

    print("Watching for changes... (Ctrl+C to stop)")

    try:
        while True:
            try:
                mtime = os.path.getmtime(args.file)
            except OSError:
                time.sleep(args.interval)
                continue

            if mtime > last_mtime:
                last_mtime = mtime
                data = read_party_file(args.file)

                if data is None:
                    time.sleep(args.interval)
                    continue

                # Only push if content actually changed
                content_str = json.dumps(data)
                if content_str == last_content:
                    time.sleep(args.interval)
                    continue

                last_content = content_str
                status, resp = push_to_api(args.url, args.slug, args.key, data)

                if status == 200:
                    sync_count += 1
                    party_size = len(data.get("party", []))
                    lead = data["party"][0]["speciesName"] if party_size > 0 else "empty"
                    print(f"  Synced #{sync_count}: {party_size} Pokemon (lead: {lead})")
                    error_count = 0
                else:
                    error_count += 1
                    print(f"  Error (status {status}): {resp}")
                    if error_count >= 5:
                        print("  Too many errors. Check your URL, slug, and sync key.")
                        error_count = 0

            time.sleep(args.interval)

    except KeyboardInterrupt:
        print(f"\nStopped. Total syncs: {sync_count}")


if __name__ == "__main__":
    main()
