#!/usr/bin/env python3
"""
Image Processor for Notion Inspiration DB - Phase 2
Processes local images: vision analysis, upload, Notion update.
Images must already be pulled to /tmp/inspo_images/
"""

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

import requests

# Configuration
NOTION_API_KEY_PATH = "/home/clawd/secrets/notion/api_key"
IMAGES_DIR = "/tmp/inspo_images"
NOTION_DELAY = 0.35

# Gemini for vision
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 analyze_image_with_vision(image_path):
    """Use Gemini vision to analyze image and generate tags."""
    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 this list (pick most relevant):
   - 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()
        data = resp.json()
        
        text = data["candidates"][0]["content"]["parts"][0]["text"]
        text = 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 for free hosting."""
    with open(image_path, "rb") as f:
        files = {"fileToUpload": f}
        data = {"reqtype": "fileupload"}
        
        try:
            resp = requests.post(
                "https://catbox.moe/user/api.php",
                files=files,
                data=data,
                timeout=60,
            )
            if resp.status_code == 200 and resp.text.startswith("https://"):
                return resp.text.strip()
        except Exception as e:
            print(f"    Upload error: {e}")
    
    return None


def update_notion_page(api_key, page_id, title=None, tags=None, cover_url=None, description=None):
    """Update Notion page with new info."""
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Notion-Version": "2022-06-28",
        "Content-Type": "application/json",
    }
    
    url = f"https://api.notion.com/v1/pages/{page_id}"
    
    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(url, headers=headers, json=payload, timeout=30)
        return resp.status_code == 200
    except Exception as e:
        print(f"    Notion error: {e}")
        return False


def process_image(api_key, page_id, image_path):
    """Process a single image: analyze, upload, update."""
    filename = os.path.basename(image_path)
    print(f"\n  [{filename[:40]}]")
    
    # 1. Analyze with vision
    print("    Vision analysis...", end=" ", flush=True)
    analysis = analyze_image_with_vision(image_path)
    if "error" in analysis:
        print(f"✗ ({analysis['error'][:50]})")
        new_title = None
        tags = None
        description = None
    else:
        print("✓")
        new_title = analysis.get("title")
        tags = analysis.get("tags", [])
        description = analysis.get("description")
        print(f"      Title: {new_title}")
        print(f"      Tags: {', '.join(tags[:5])}")
    
    # 2. Upload for cover
    print("    Uploading...", end=" ", flush=True)
    cover_url = upload_to_catbox(image_path)
    if cover_url:
        print("✓")
    else:
        print("✗")
    
    # 3. Update Notion
    print("    Notion update...", end=" ", flush=True)
    success = update_notion_page(api_key, page_id, new_title, tags, cover_url, description)
    if success:
        print("✓")
    else:
        print("✗")
    
    return success


def main():
    parser = argparse.ArgumentParser(description="Process pulled images")
    parser.add_argument("--manifest", required=True, help="JSON manifest file with page_id -> filename mapping")
    args = parser.parse_args()
    
    # Load manifest
    with open(args.manifest) as f:
        manifest = json.load(f)
    
    print(f"Processing {len(manifest)} images from {IMAGES_DIR}")
    
    api_key = load_notion_key()
    
    success = 0
    failed = 0
    
    for page_id, filename in manifest.items():
        image_path = os.path.join(IMAGES_DIR, filename)
        if not os.path.exists(image_path):
            print(f"\n  ✗ Missing: {filename}")
            failed += 1
            continue
        
        if process_image(api_key, page_id, image_path):
            success += 1
        else:
            failed += 1
        
        time.sleep(NOTION_DELAY)
    
    print(f"\n=== RESULTS ===")
    print(f"Success: {success}")
    print(f"Failed: {failed}")


if __name__ == "__main__":
    main()
