#!/usr/bin/env python3
"""
scan_manual_uploads.py — Scan 01-Source-PNG for loose PNG files and register them as manual items.

This runs FIRST in the pipeline before Maker.
Loose PNGs (not in subfolders) are added to pipeline-state.json as manual items.
They skip Maker and go straight to Critic for routing.
They do NOT count toward daily API budget.

Excludes subfolders (those are generated items or already-processed).
"""

import json
import os
import re
from datetime import datetime
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")
SOURCE_PNG_DIR = DESIGNS_ROOT / "01-Source-PNG"

DEBUG = True


def run_pipeline_tool(args: list) -> tuple[int, str, str]:
    import subprocess
    r = subprocess.run(
        ["python3", str(PIPELINE_TOOL)] + args,
        check=False, text=True, capture_output=True
    )
    return r.returncode, r.stdout.strip(), r.stderr.strip()


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


def slugify(s: str) -> str:
    s = s.lower().replace(".png", "").replace(".jpg", "")
    s = re.sub(r"[^a-z0-9\s-]", "", s)
    s = re.sub(r"\s+", "-", s).strip("-")
    s = re.sub(r"-+", "-", s)
    return s[:50]


def ps_set(item_id, stage, status, message, design_name=None, source=None, paths=None):
    """Register an item in pipeline state."""
    args = [
        "set", "--path", str(STATE_PATH),
        "--id", item_id,
        "--stage", stage,
        "--status", status,
        "--by", "scan-manual",
        "--message", message
    ]
    if design_name:
        args += ["--design_name", design_name]
    if source:
        args += ["--source", source]
    if paths:
        for k, v in paths.items():
            args += ["--path_kv", f"{k}={v}"]
    rc, out, err = run_pipeline_tool(args)
    if rc != 0:
        raise RuntimeError(err or "pipeline_state set failed")


def main():
    if not SOURCE_PNG_DIR.exists():
        print(f"Scanner: {SOURCE_PNG_DIR} not found")
        return

    state = load_state()
    existing_ids = {it["id"] for it in state.get("items", [])}

    # Find loose PNG files (direct children, not in subfolders)
    loose_pngs = [
        f for f in SOURCE_PNG_DIR.iterdir()
        if f.is_file() and f.suffix.lower() in (".png", ".jpg", ".jpeg")
    ]

    if not loose_pngs:
        print("Scanner: no loose PNGs found")
        return

    print(f"Scanner: found {len(loose_pngs)} loose PNG(s)")

    for png_path in loose_pngs:
        design_name = slugify(png_path.stem)
        item_id = f"manual-{design_name}-{datetime.now().isoformat()[:10]}"

        if item_id in existing_ids:
            print(f"Scanner: {item_id} already registered, skipping")
            continue

        print(f"Scanner: registering manual upload '{design_name}'")

        try:
            ps_set(
                item_id,
                stage="critic_ready",
                status="ready_for_critic",
                message=f"Manual upload: {png_path.name}",
                design_name=design_name,
                source="manual",
                paths={
                    "source_file": str(png_path),
                    "source_type": "manual"
                }
            )
            print(f"Scanner: {item_id} registered -> ready_for_critic")
        except Exception as e:
            print(f"Scanner: ERROR registering {design_name}: {e}")


if __name__ == "__main__":
    main()
