#!/usr/bin/env python3
"""
Generate images using MakeCoder AI API with Nano Banana models.

Supports models:
- Nano Banana (default, high quality image generation)
- Nano Banana Pro (advanced model with enhanced capabilities)
"""

import argparse
import json
import sys
from pathlib import Path
from typing import Optional

try:
    import httpx
except ImportError:
    print("Error: 'httpx' library not found. Install with: pip install httpx")
    sys.exit(1)


def check_config_file() -> Optional[str]:
    """Check if config.json file exists and contains ak/sk."""
    config_path = Path.home() / ".coder" / "config.json"

    if config_path.exists():
        try:
            with open(config_path, 'r') as f:
                config = json.load(f)
                auth = config.get('auth', {})
                ak = auth.get('ak')
                sk = auth.get('sk')

                if ak and sk:
                    return f"{ak}.{sk}"
        except (json.JSONDecodeError, KeyError):
            pass

    return None


def extract_image_url(markdown_text: str) -> Optional[str]:
    """Extract image URL from markdown format."""
    import re
    # Match markdown image format: ![alt](url)
    match = re.search(r'!\[.*?\]\((https?://[^\)]+)\)', markdown_text)
    if match:
        return match.group(1)
    return None


def download_image(url: str, output_path: str) -> None:
    """Download image from URL and save to file."""
    try:
        with httpx.Client(timeout=60.0) as client:
            response = client.get(url)
            response.raise_for_status()
            with open(output_path, 'wb') as f:
                f.write(response.content)
    except Exception as e:
        print(f"❌ Error downloading image: {e}")
        sys.exit(1)


def generate_image(
    prompt: str,
    model: str = "Nano Banana",
    output_path: str = "generated_image.png",
    api_key: Optional[str] = None
) -> dict:
    """
    Generate an image using MakeCoder AI API.

    Args:
        prompt: Text description of the image to generate
        model: Model name (default: Nano Banana)
               Options: "Nano Banana", "Nano Banana Pro"
        output_path: Path to save the generated image
        api_key: MakeCoder API key (will check config.json if not provided)

    Returns:
        dict: Response from MakeCoder API
    """
    # Check for API key
    if not api_key:
        api_key = check_config_file()

    if not api_key:
        print("❌ Error: API key not found!")
        print("\nPlease create a config file at ~/.coder/config.json with:")
        print(json.dumps({
            "agent": "claude",
            "auth": {
                "ak": "your-ak-here",
                "sk": "your-sk-here"
            }
        }, indent=2))
        print("\nGet your API key from: https://makecoder.com/my/apikeys")
        sys.exit(1)

    # Map model names to aimodel_id
    model_mapping = {
        "Nano Banana": "a4e37ec3-f725-4253-8e60-20c90b11a98f",
        "Nano Banana Pro": "65a8247d-78f4-4e36-be1d-0cda7b658fe2",
    }

    # Get aimodel_id from mapping, default to Nano Banana if not found
    aimodel_id = model_mapping.get(
        model,
        "a4e37ec3-f725-4253-8e60-20c90b11a98f"
    )

    print(f"🎨 Generating image with model: {model}")
    print(f"📝 Prompt: {prompt}")

    # Prepare request to local service
    url = "https://makecoder.com/bigapis/codev/v1/aiagent/chat/complete"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}",
    }

    payload = {
        "aimodel_id": aimodel_id,
        "query": prompt,
        "bot": None,
        "config": {
            "task_type": "codev",
            "use_system_prompt": False,
            "llm_params": {
                "aspect_ratio": "1:1",
                "image_size": "1K",
                "output_mime_type": "image/png"
            }
        },
    }

    # Store results
    conversation_id = None
    image_url = None

    # Send SSE streaming request
    try:
        with httpx.Client(timeout=300.0) as client:
            with client.stream("POST", url, json=payload, headers=headers) as response:
                response.raise_for_status()

                # Process SSE streaming response
                for line in response.iter_lines():
                    if line.startswith("data: "):
                        data = line[6:]  # Remove "data: " prefix

                        # Check if done
                        if data.strip() == "[DONE]":
                            print("\n✓ Generation complete")
                            break

                        try:
                            event_data = json.loads(data)

                            # Extract conversation_id
                            if (isinstance(event_data, dict) and
                                    "conversation_id" in event_data):
                                conversation_id = event_data["conversation_id"]

                            # Extract image URL from data field
                            if (isinstance(event_data, dict) and
                                    "data" in event_data and
                                    event_data.get("type") == "text"):
                                markdown_data = event_data["data"]
                                extracted_url = extract_image_url(markdown_data)
                                if extracted_url:
                                    image_url = extracted_url

                            # Print progress
                            print(".", end="", flush=True)

                        except json.JSONDecodeError:
                            print(f"\n⚠️ Failed to parse: {data}")

        # Download and save image
        if image_url:
            print(f"\n📥 Downloading image from: {image_url}")
            download_image(image_url, output_path)
            print(f"✅ Image saved to: {output_path}")
        else:
            print("⚠️ No image URL found in response")

        result = {
            "conversation_id": conversation_id,
            "image_url": image_url
        }

    except httpx.HTTPError as e:
        print(f"❌ HTTP Error: {e}")
        sys.exit(1)
    except Exception as e:
        print(f"❌ Error: {e}")
        sys.exit(1)

    return result


def main():
    parser = argparse.ArgumentParser(
        description="Generate images using MakeCoder AI API",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  # Generate with default model (Nano Banana)
  python generate_image.py "A beautiful sunset over mountains"

  # Use Nano Banana Pro model
  python generate_image.py "A cat in space" --model "Nano Banana Pro"

  # Specify output path
  python generate_image.py "Abstract art" --output my_image.png

Available models:
  - Nano Banana (default, high quality image generation)
  - Nano Banana Pro (advanced model with enhanced capabilities)
        """
    )

    parser.add_argument(
        "prompt",
        type=str,
        help="Text description of the image to generate"
    )

    parser.add_argument(
        "--model", "-m",
        type=str,
        default="Nano Banana",
        help="Model name (default: Nano Banana). Options: Nano Banana, Nano Banana Pro"
    )

    parser.add_argument(
        "--output", "-o",
        type=str,
        default="generated_image.png",
        help="Output file path (default: generated_image.png)"
    )

    parser.add_argument(
        "--api-key",
        type=str,
        help="MakeCoder API key (will check config.json if not provided)"
    )

    args = parser.parse_args()

    generate_image(
        prompt=args.prompt,
        model=args.model,
        output_path=args.output,
        api_key=args.api_key
    )


if __name__ == "__main__":
    main()
