#!/usr/bin/env python3
"""
Pull images from Mac Studio and process them.
Usage: python3 pull_and_process.py --limit 10
"""

import argparse
import base64
import json
import os
import subprocess
import sys
import time
from pathlib import Path

import requests

# Configuration
NOTION_API_KEY_PATH = "/home/clawd/secrets/notion/api_key"
NOTION_DB_ID = "2ff330c2-8646-81f0-bbd9-ec474393d7a5"
MAC_NODE = "Mac Studio"
DESKTOP_INSPO = "/Users/assafdagan/Desktop/inspo"
DATA_FILE = "/home/clawd/workspace/data/local_images.json"
IMAGES_DIR = "/tmp/inspo_images"
NOTION_DELAY = 0.35
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "AIzaSyDXqYZInk83iVV4mD29pSuHQKbgkiI1x9Q")


def load_notion_key():
    with open(NOTION_API_KEY_PATH) as f:
        return f.read().strip()


def load_images():
    with open(DATA_FILE) as f:
        return json.load(f)


def get_image_path(title, source):
    """Reconstruct the file path on Mac Studio."""
    subfolder = source.replace("Desktop/inspo", "").lstrip("/")
    if subfolder:
        return f"{DESKTOP_INSPO}/{subfolder}/{title}"
    return f"{DESKTOP_INSPO}/{title}"


def pull_image(title, source, local_path):
    """Pull image from Mac Studio via openclaw nodes run."""
    filepath = get_image_path(title, source)
    cmd = ["openclaw", "nodes", "run", "--node", MAC_NODE, "--timeout", "60000", "--", 
           "bash", "-c", f'base64 -i "{filepath}"']
    
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
        if result.returncode != 0:
            return False, result.stderr[:100]
        
        # Parse JSON output
        data = json.loads(result.stdout)
        if not data.get("success"):
            return False, data.get("error", "Unknown error")
        
        img_data = base64.b64decode(data["stdout"])
        with open(local_path, "wb") as f:
            f.write(img_data)
        return True, local_path
    except Exception as e:
        return False, str(e)[:100]


def analyze_image(image_path):
    """Use Gemini vision to analyze image."""
    with open(image_path, "rb") as f:
        img_data = base64.b64encode(f.read()).decode()
    
    ext = Path(image_path).suffix.lower()
    mime_map = {".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png",
                ".gif": "image/gif", ".webp": "image/webp"}
    mime_type = mime_map.get(ext, "image/jpeg")
    
    url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={GEMINI_API_KEY}"
    
    payload = {
        "contents": [{
            "parts": [
                {"inlineData": {"mimeType": mime_type, "data": img_data}},
                {"text": """Analyze this image for a design inspiration library.

Return a JSON object with:
1. "title": A short descriptive title (max 60 chars)
2. "description": One sentence describing what this is
3. "tags": Array of 3-8 relevant tags from:
   - Style: Minimalist, Bold, Playful, Elegant, Retro, Modern, Organic, Geometric
   - Type: Branding, Packaging, Typography, Illustration, Photography, UI/UX, 3D, Motion, Logo, Poster, Editorial
   - Subject: Food, Fashion, Architecture, Product, Portrait, Landscape, Abstract, Pattern
   - Color: Colorful, Monochrome, Pastel, Vibrant, Muted, Earth Tones
   - Industry: Tech, Food & Drink, Beauty, Lifestyle, Corporate, Entertainment, Art

Return ONLY valid JSON, no markdown."""}
            ]
        }],
        "generationConfig": {"temperature": 0.3, "maxOutputTokens": 500}
    }
    
    try:
        resp = requests.post(url, json=payload, timeout=30)
        resp.raise_for_status()
        text = resp.json()["candidates"][0]["content"]["parts"][0]["text"].strip()
        if text.startswith("```"):
            text = text.split("\n", 1)[1]
            if text.endswith("```"):
                text = text[:-3]
        return json.loads(text)
    except Exception as e:
        return {"error": str(e)}


def upload_to_catbox(image_path):
    """Upload image to catbox.moe."""
    with open(image_path, "rb") as f:
        try:
            resp = requests.post(
                "https://catbox.moe/user/api.php",
                files={"fileToUpload": f},
                data={"reqtype": "fileupload"},
                timeout=60
            )
            if resp.status_code == 200 and resp.text.startswith("https://"):
                return resp.text.strip()
        except Exception:
            pass
    return None


def update_notion(api_key, page_id, title=None, tags=None, cover_url=None, description=None):
    """Update Notion page."""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Notion-Version": "2022-06-28",
        "Content-Type": "application/json",
    }
    
    payload = {}
    props = {}
    
    if title:
        props["Name"] = {"title": [{"text": {"content": title[:2000]}}]}
    if tags:
        props["Tags"] = {"multi_select": [{"name": tag} for tag in tags[:10]]}
    if description:
        props["Description"] = {"rich_text": [{"text": {"content": description[:2000]}}]}
    if props:
        payload["properties"] = props
    if cover_url:
        payload["cover"] = {"type": "external", "external": {"url": cover_url}}
    
    if not payload:
        return True
    
    try:
        resp = requests.patch(
            f"https://api.notion.com/v1/pages/{page_id}",
            headers=headers, json=payload, timeout=30
        )
        return resp.status_code == 200
    except Exception:
        return False


def process_one(api_key, item):
    """Process a single image."""
    title = item["title"]
    source = item["source"]
    page_id = item["id"]
    
    print(f"\n  [{title[:50]}]")
    
    # Create safe filename
    safe_name = "".join(c if c.isalnum() or c in ".-_" else "_" for c in title)
    local_path = os.path.join(IMAGES_DIR, safe_name)
    
    # 1. Pull from Mac
    print("    Pulling...", end=" ", flush=True)
    success, result = pull_image(title, source, local_path)
    if not success:
        print(f"✗ ({result[:40]})")
        return False
    print("✓")
    
    # 2. Vision analysis
    print("    Analyzing...", end=" ", flush=True)
    analysis = analyze_image(local_path)
    if "error" in analysis:
        print(f"✗ ({analysis['error'][:40]})")
        new_title, tags, description = None, None, None
    else:
        print("✓")
        new_title = analysis.get("title")
        tags = analysis.get("tags", [])
        description = analysis.get("description")
        print(f"      → {new_title}")
        print(f"      → {', '.join(tags[:4])}")
    
    # 3. Upload for cover
    print("    Uploading...", end=" ", flush=True)
    cover_url = upload_to_catbox(local_path)
    if cover_url:
        print("✓")
    else:
        print("✗")
    
    # 4. Update Notion
    print("    Notion...", end=" ", flush=True)
    success = update_notion(api_key, page_id, new_title, tags, cover_url, description)
    if success:
        print("✓")
    else:
        print("✗")
    
    # Cleanup
    try:
        os.remove(local_path)
    except:
        pass
    
    return success


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--limit", type=int, default=10)
    parser.add_argument("--offset", type=int, default=0)
    args = parser.parse_args()
    
    os.makedirs(IMAGES_DIR, exist_ok=True)
    
    images = load_images()
    needs_work = [i for i in images if not i.get("has_cover")]
    batch = needs_work[args.offset:args.offset + args.limit]
    
    print(f"Total: {len(images)}, Need work: {len(needs_work)}, Processing: {len(batch)}")
    
    api_key = load_notion_key()
    success = failed = 0
    
    for item in batch:
        if process_one(api_key, item):
            success += 1
        else:
            failed += 1
        time.sleep(NOTION_DELAY)
    
    print(f"\n=== RESULTS ===")
    print(f"Success: {success}")
    print(f"Failed: {failed}")
    print(f"Remaining: {len(needs_work) - args.offset - len(batch)}")


if __name__ == "__main__":
    main()
