#!/usr/bin/env python3
import json
import subprocess
from pathlib import Path

WORKSPACE = Path("/Users/tonyclaw/.openclaw/workspace")
ETSY_DIR = WORKSPACE / "Etsy"
STATE_PATH = ETSY_DIR / "pipeline-state.json"
PIPELINE_TOOL = ETSY_DIR / "tools" / "pipeline_state.py"

DESIGNS_ROOT = Path("/Users/tonyclaw/Documents/Etsy Designs")
PRINT_REVIEW = DESIGNS_ROOT / "02-Review-Print"
UPLOAD_READY = DESIGNS_ROOT / "03-Upload-Ready"

BUNDLER_CMD = ["openclaw", "agent", "run", "Etsy-Bundler-Print"]

def run(cmd, check=True):
    return subprocess.run(cmd, check=check, text=True, capture_output=True)

def load_state():
    with open(STATE_PATH, "r", encoding="utf-8") as f:
        return json.load(f)

def pick_next_item(state):
    candidates = []
    for it in state.get("items", []):
        if it.get("status") != "ready_for_bundler":
            continue
        review = (it.get("paths") or {}).get("review_folder", "")
        if review and str(PRINT_REVIEW) in review:
            candidates.append(it)
    if not candidates:
        return None
    candidates.sort(key=lambda x: (-int(x.get("priority", 0)), x.get("created_at", "")))
    return candidates[0]

def ps_set(item_id, stage, status, message, paths=None):
    cmd = [
        "python3", str(PIPELINE_TOOL), "set",
        "--path", str(STATE_PATH),
        "--id", item_id,
        "--stage", stage,
        "--status", status,
        "--by", "Etsy-Bundler-Print",
        "--message", message
    ]
    if paths:
        for k, v in paths.items():
            cmd += ["--path_kv", f"{k}={v}"]
    r = run(cmd, check=False)
    if r.returncode != 0:
        raise RuntimeError(r.stderr.strip() or "pipeline_state set failed")

def ps_error(item_id, message):
    cmd = [
        "python3", str(PIPELINE_TOOL), "error",
        "--path", str(STATE_PATH),
        "--id", item_id,
        "--by", "Etsy-Bundler-Print",
        "--message", message
    ]
    run(cmd, check=False)

def validate_upload_ready(folder: Path, design_name: str):
    # Minimal required artifacts for Print bundles (adjust to your rules)
    required = [
        folder / "listing.txt",
        folder / "design-info.json",
        folder / f"{design_name}-sublimation.zip",
        folder / f"{design_name}.png",
        folder / f"{design_name}-white-bg.png",
    ]
    missing = [str(p) for p in required if not p.exists()]
    return missing

def main():
    state = load_state()
    item = pick_next_item(state)
    if not item:
        print("Bundler-Print: no items ready_for_bundler in Print review")
        return

    item_id = item["id"]
    design_name = item.get("design_name")
    review_folder = (item.get("paths") or {}).get("review_folder")

    ps_set(item_id, stage="bundler_in_progress", status="blocked", message="Claimed for bundling (lock held)")

    try:
        if not design_name:
            ps_error(item_id, "Missing design_name")
            return
        if not review_folder or not Path(review_folder).exists():
            ps_error(item_id, f"Missing review_folder: {review_folder}")
            return

        r = run(BUNDLER_CMD, check=False)
        if r.returncode != 0:
            ps_error(item_id, f"Bundler command failed: {r.stderr.strip()}")
            return

        out_folder = UPLOAD_READY / design_name
        if not out_folder.exists():
            ps_error(item_id, f"Expected upload-ready folder missing: {out_folder}")
            return

        missing = validate_upload_ready(out_folder, design_name)
        if missing:
            ps_error(item_id, "Validation failed (missing): " + ", ".join(missing))
            return

        ps_set(
            item_id,
            stage="bundled",
            status="complete",
            message="Bundled successfully.",
            paths={
                "upload_ready_folder": str(out_folder),
                "bundle_zip": str(out_folder / f"{design_name}-sublimation.zip"),
                "listing_txt": str(out_folder / "listing.txt"),
            }
        )
        print(f"Bundler-Print complete: {item_id} -> complete")

    except Exception as e:
        ps_error(item_id, f"Unhandled exception: {e}")

if __name__ == "__main__":
    main()
