#!/usr/bin/env python3
"""
Krea Node App runner - pipeline completo:
  1. Upload de imagem
  2. Executar Node App com node_id + input
  3. Polling do job até concluir
  4. Download do MP4 final

Uso:
  export KREA_API_KEY=sk_...
  python3 krea-run-workflow.py \
    --node-app-id tim-koda-motion-v2 \
    --input hero-shot.png \
    --output hero-motion.mp4 \
    --prompt "slow cinematic push-in, 8s, 24fps"

Requer: requests, tqdm
"""
import argparse
import os
import sys
import time
import requests
from pathlib import Path

KREA_BASE = os.environ.get("KREA_BASE", "https://api.krea.ai/v1")
API_KEY = os.environ.get("KREA_API_KEY")
POLL_INTERVAL = 3
POLL_MAX = 300


def auth_headers():
    if not API_KEY:
        sys.exit("KREA_API_KEY não definida")
    return {"Authorization": f"Bearer {API_KEY}"}


def upload_asset(path: Path) -> str:
    """Upload de imagem -> retorna asset_id"""
    url = f"{KREA_BASE}/assets/upload"
    with path.open("rb") as f:
        r = requests.post(
            url,
            headers=auth_headers(),
            files={"file": (path.name, f, "image/png")},
            timeout=120,
        )
    r.raise_for_status()
    asset_id = r.json()["id"]
    print(f"[upload] asset_id={asset_id}")
    return asset_id


def execute_node_app(node_app_id: str, asset_id: str, prompt: str) -> str:
    """Executa Node App -> retorna job_id"""
    url = f"{KREA_BASE}/node-apps/{node_app_id}/execute"
    payload = {
        "inputs": {
            "image": asset_id,
            "prompt": prompt,
        },
    }
    r = requests.post(url, headers=auth_headers(), json=payload, timeout=30)
    r.raise_for_status()
    job_id = r.json()["job_id"]
    print(f"[execute] job_id={job_id}")
    return job_id


def poll_job(job_id: str) -> dict:
    """Polling ate terminar"""
    url = f"{KREA_BASE}/jobs/{job_id}"
    for i in range(POLL_MAX):
        r = requests.get(url, headers=auth_headers(), timeout=15)
        r.raise_for_status()
        data = r.json()
        status = data["status"]
        print(f"[poll {i+1}] status={status}")
        if status == "completed":
            return data
        if status in ("failed", "error"):
            sys.exit(f"Job falhou: {data.get('error')}")
        time.sleep(POLL_INTERVAL)
    sys.exit("Timeout")


def download_output(url: str, out_path: Path):
    r = requests.get(url, stream=True, timeout=300)
    r.raise_for_status()
    out_path.parent.mkdir(parents=True, exist_ok=True)
    with out_path.open("wb") as f:
        for chunk in r.iter_content(chunk_size=1 << 20):
            f.write(chunk)
    print(f"[download] saved -> {out_path}")


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--node-app-id", required=True)
    ap.add_argument("--input", required=True, type=Path)
    ap.add_argument("--output", required=True, type=Path)
    ap.add_argument("--prompt", default="")
    args = ap.parse_args()

    asset_id = upload_asset(args.input)
    job_id = execute_node_app(args.node_app_id, asset_id, args.prompt)
    result = poll_job(job_id)
    output_url = result["outputs"]["video"]
    download_output(output_url, args.output)
    print("[done]")


if __name__ == "__main__":
    main()
