"""Prompt Studio Service - AI-Powered Prompt Enhancement

Uses Google Gemini or OpenAI GPT-4 to transform basic prompts into
professional, detailed prompts optimized for AI image/video generation.

Features:
- Multiple style presets (cinematic, photographic, artistic, etc.)
- Provider support for various image generators (DALL-E, Stable Diffusion, Midjourney, Flux)
- Negative prompt generation
- Technical parameter suggestions
- Multi-language support

Styles Available:
- cinematic: Movie-like scenes with dramatic lighting
- photographic: Professional photography with camera settings
- artistic: Painterly descriptions with artistic techniques
- product: Commercial product photography
- fantasy: Magical, otherworldly scenes
- minimal: Clean, simple compositions
- vintage: Retro, nostalgic aesthetics
- futuristic: Sci-fi, high-tech visuals
- anime: Japanese animation style
- portrait: Professional portrait photography
- landscape: Nature and scenic photography
- abstract: Non-representational art
- fashion: High-end fashion photography
- architecture: Building and interior design
- food: Culinary and food photography
"""
import httpx
from typing import Optional, Dict, Any, List
from app.config import settings


# Style configurations with detailed instructions
STYLE_CONFIGS = {
    "cinematic": {
        "name": "Cinematic",
        "instruction": """Transform this into a cinematic, movie-like scene description with:
- Dramatic lighting (golden hour, chiaroscuro, rim lighting, volumetric rays)
- Film-quality composition (rule of thirds, leading lines, depth of field)
- Atmospheric elements (fog, dust particles, lens flares)
- Color grading suggestions (teal and orange, desaturated, high contrast)
- Camera movement or angle (dolly shot, crane shot, dutch angle)
- Aspect ratio: 21:9 or 2.39:1 for widescreen cinematic feel""",
        "negative_base": "amateur, low budget, poorly lit, flat lighting, snapshot quality",
        "technical": {"aspect_ratio": "21:9", "style": "cinematic"}
    },
    "photographic": {
        "name": "Professional Photography",
        "instruction": """Transform this into a professional photography prompt with:
- Specific camera and lens (e.g., Canon EOS R5, Sony A7IV, 85mm f/1.4)
- Exact lighting setup (softbox, ring light, natural window light, golden hour)
- Technical settings (ISO, aperture, shutter speed)
- Composition technique (rule of thirds, symmetry, leading lines)
- Post-processing style (high contrast, film emulation, clean edit)""",
        "negative_base": "blurry, out of focus, overexposed, underexposed, amateur",
        "technical": {"quality": "high", "style": "photorealistic"}
    },
    "artistic": {
        "name": "Fine Art",
        "instruction": """Transform this into an artistic, painterly description with:
- Art movement reference (Impressionism, Surrealism, Art Nouveau, Baroque)
- Specific artist style influence (Monet, Van Gogh, Klimt, Dali)
- Medium specification (oil on canvas, watercolor, digital painting)
- Brushwork and texture details (impasto, glazing, wet-on-wet)
- Color palette (complementary, analogous, monochromatic)
- Emotional mood and atmosphere""",
        "negative_base": "photorealistic, photograph, digital render, 3D, CGI",
        "technical": {"style": "artistic"}
    },
    "product": {
        "name": "Product Photography",
        "instruction": """Transform this into professional product photography with:
- Clean, commercial backdrop (white seamless, gradient, lifestyle setting)
- Studio lighting setup (three-point lighting, beauty dish, softbox)
- Hero shot composition (angle, distance, focal point)
- Reflection and shadow control
- Brand-appropriate styling
- E-commerce or advertising context""",
        "negative_base": "cluttered background, amateur lighting, dirty, damaged",
        "technical": {"background": "transparent", "quality": "high"}
    },
    "fantasy": {
        "name": "Fantasy Art",
        "instruction": """Transform this into a fantastical, imaginative scene with:
- Magical elements (glowing particles, ethereal light, mystical symbols)
- Otherworldly setting details (floating islands, crystal formations, ancient ruins)
- Fantasy creature or character design elements
- Epic scale and grandeur
- Rich color palette (jewel tones, iridescent, bioluminescent)
- Atmospheric effects (mist, aurora, magical energy)""",
        "negative_base": "mundane, realistic, boring, plain, everyday",
        "technical": {"style": "fantasy-art"}
    },
    "minimal": {
        "name": "Minimalist",
        "instruction": """Transform this into a minimalist, clean description with:
- Negative space utilization (vast empty areas, breathing room)
- Limited color palette (monochrome, two-tone, muted)
- Simple geometric forms
- Clean lines and shapes
- Subtle textures
- Zen-like calm and balance""",
        "negative_base": "cluttered, busy, complex, detailed, ornate, decorated",
        "technical": {"style": "minimal"}
    },
    "vintage": {
        "name": "Vintage/Retro",
        "instruction": """Transform this into a vintage, retro-styled description with:
- Era-specific details (1920s Art Deco, 1950s Americana, 1970s psychedelic, 1980s neon)
- Film stock characteristics (Kodachrome, Polaroid, black and white)
- Grain and texture (film grain, light leaks, vignette)
- Period-appropriate color palette (sepia, faded, cross-processed)
- Nostalgic elements and props
- Authentic vintage aesthetic""",
        "negative_base": "modern, digital, contemporary, clean, sharp",
        "technical": {"style": "analog-film"}
    },
    "futuristic": {
        "name": "Sci-Fi/Futuristic",
        "instruction": """Transform this into a futuristic, sci-fi description with:
- Advanced technology elements (holograms, neon lights, cybernetic)
- Futuristic architecture (sleek, geometric, towering)
- Sci-fi lighting (neon, bioluminescent, holographic)
- Cyberpunk or utopian aesthetic
- High-tech materials (chrome, glass, LED)
- Atmospheric sci-fi elements (rain, smog, data streams)""",
        "negative_base": "primitive, ancient, rustic, natural, organic",
        "technical": {"style": "neon-punk"}
    },
    "anime": {
        "name": "Anime/Manga",
        "instruction": """Transform this into anime/manga style with:
- Character design elements (large expressive eyes, dynamic poses)
- Japanese animation aesthetic (cel shading, speed lines)
- Studio style reference (Studio Ghibli, Makoto Shinkai, MAPPA)
- Dramatic lighting and composition
- Vibrant color palette
- Emotional expression and atmosphere""",
        "negative_base": "realistic, photograph, western cartoon, 3D render",
        "technical": {"style": "anime"}
    },
    "portrait": {
        "name": "Portrait Photography",
        "instruction": """Transform this into professional portrait photography with:
- Flattering lighting setup (Rembrandt, butterfly, split lighting)
- Lens choice for portraits (85mm, 105mm, shallow depth of field)
- Background treatment (bokeh, studio backdrop, environmental)
- Skin tone and texture (natural, retouched, editorial)
- Expression and emotion capture
- Composition (headshot, half-body, full-body)""",
        "negative_base": "unflattering angle, harsh shadows, distorted features",
        "technical": {"style": "photographic"}
    },
    "landscape": {
        "name": "Landscape Photography",
        "instruction": """Transform this into epic landscape photography with:
- Golden hour or blue hour lighting
- Weather and atmospheric conditions (dramatic clouds, fog, storm)
- Geographic specificity (mountains, ocean, forest, desert)
- Foreground interest and depth
- Wide-angle perspective
- Long exposure effects (smooth water, star trails)""",
        "negative_base": "flat, boring, midday harsh light, no depth",
        "technical": {"aspect_ratio": "16:9", "style": "photorealistic"}
    },
    "abstract": {
        "name": "Abstract Art",
        "instruction": """Transform this into abstract art with:
- Non-representational forms and shapes
- Color theory application (complementary, triadic, split-complementary)
- Texture and pattern exploration
- Movement and flow
- Emotional expression through color and form
- Artistic technique (drip, splatter, geometric)""",
        "negative_base": "representational, realistic, figurative, recognizable objects",
        "technical": {"style": "digital-art"}
    },
    "fashion": {
        "name": "Fashion Photography",
        "instruction": """Transform this into high-end fashion photography with:
- Editorial or commercial context
- Designer styling and wardrobe
- High-fashion lighting (dramatic, clean, artistic)
- Model pose and expression
- Location or studio setting
- Magazine-worthy composition""",
        "negative_base": "casual, everyday, amateur, unflattering",
        "technical": {"style": "photographic", "quality": "high"}
    },
    "architecture": {
        "name": "Architectural Photography",
        "instruction": """Transform this into architectural photography with:
- Building style and era (modern, classical, brutalist, Art Deco)
- Perspective and angles (worm's eye, bird's eye, straight-on)
- Interior or exterior focus
- Lighting conditions (golden hour, twilight, dramatic shadows)
- Detail and texture emphasis
- Scale and grandeur""",
        "negative_base": "distorted, amateur angle, poor lighting, obstructed view",
        "technical": {"style": "photographic"}
    },
    "food": {
        "name": "Food Photography",
        "instruction": """Transform this into appetizing food photography with:
- Styling and plating details
- Lighting setup (backlit, side-lit, soft diffused)
- Props and context (table setting, ingredients, utensils)
- Texture and freshness emphasis
- Color harmony and contrast
- Angle (overhead, 45-degree, eye-level)""",
        "negative_base": "unappetizing, messy, cold, stale, poor presentation",
        "technical": {"style": "photographic", "quality": "high"}
    }
}

# Provider-specific optimizations
PROVIDER_OPTIMIZATIONS = {
    "openai": {
        "max_length": 4000,
        "style_suffix": "highly detailed, professional quality",
        "avoid": "text, watermarks, logos"
    },
    "gpt-image-1": {
        "max_length": 32000,
        "style_suffix": "highly detailed, professional quality, masterpiece",
        "avoid": "text, watermarks, logos, blurry"
    },
    "stable-diffusion": {
        "max_length": 500,
        "style_suffix": "(masterpiece, best quality, highly detailed)",
        "avoid": "(worst quality, low quality, blurry, distorted)"
    },
    "midjourney": {
        "max_length": 600,
        "style_suffix": "--v 6 --q 2 --s 750",
        "avoid": "--no text, watermarks, blurry"
    },
    "flux": {
        "max_length": 2000,
        "style_suffix": "ultra high quality, professional, detailed",
        "avoid": "low quality, amateur, blurry"
    },
    "leonardo": {
        "max_length": 1000,
        "style_suffix": "highly detailed, professional, stunning",
        "avoid": "low quality, blurry, distorted"
    }
}


async def enhance(
    prompt: str,
    style: str = "cinematic",
    provider: str = "openai",
    include_negative: bool = True,
    include_technical: bool = True,
    language: str = "en"
) -> dict:
    """Enhance a prompt using AI

    Args:
        prompt: The original prompt to enhance
        style: Style preset to apply (see STYLE_CONFIGS)
        provider: Target image generation provider for optimization
        include_negative: Whether to generate negative prompts
        include_technical: Whether to include technical parameters
        language: Output language code

    Returns:
        Dictionary with enhanced prompt, negative prompt, and metadata
    """

    # Get style configuration
    style_config = STYLE_CONFIGS.get(style, STYLE_CONFIGS["cinematic"])
    provider_config = PROVIDER_OPTIMIZATIONS.get(provider, PROVIDER_OPTIMIZATIONS["openai"])

    # Try Google Gemini first, then OpenAI, then fallback
    enhanced_result = None

    if settings.google_api_key:
        enhanced_result = await _enhance_with_gemini(prompt, style_config, provider_config, language)
    elif settings.openai_api_key:
        enhanced_result = await _enhance_with_openai(prompt, style_config, provider_config, language)

    if not enhanced_result:
        # Fallback to rule-based enhancement
        enhanced_result = _enhance_fallback(prompt, style_config, provider_config)

    # Build response
    response = {
        "original_prompt": prompt,
        "enhanced_prompt": enhanced_result.get("enhanced_prompt", prompt),
        "style": style,
        "style_name": style_config["name"],
        "provider": provider
    }

    if include_negative:
        response["negative_prompt"] = enhanced_result.get(
            "negative_prompt",
            style_config.get("negative_base", "blurry, low quality, distorted")
        )

    if include_technical:
        response["technical_params"] = {
            **style_config.get("technical", {}),
            "max_prompt_length": provider_config["max_length"]
        }

    if enhanced_result.get("suggestions"):
        response["suggestions"] = enhanced_result["suggestions"]

    if enhanced_result.get("note"):
        response["note"] = enhanced_result["note"]

    return response


async def _enhance_with_gemini(
    prompt: str,
    style_config: dict,
    provider_config: dict,
    language: str
) -> Optional[Dict[str, Any]]:
    """Enhance prompt using Google Gemini"""
    try:
        import google.generativeai as genai
        genai.configure(api_key=settings.google_api_key)
        model = genai.GenerativeModel("gemini-2.0-flash-exp")

        system_prompt = f"""You are an expert AI image prompt engineer. Your task is to transform basic prompts into detailed, professional prompts optimized for AI image generation.

STYLE: {style_config['name']}
{style_config['instruction']}

OPTIMIZATION TARGET: {provider_config.get('max_length', 1000)} characters maximum

Guidelines:
1. Add specific visual details (lighting, colors, textures, materials)
2. Include composition and framing suggestions
3. Add atmosphere, mood, and emotional tone
4. Be specific about quality indicators
5. Keep under {provider_config.get('max_length', 1000)} characters
6. Make it suitable for AI image generators
7. {"Output in " + language if language != "en" else ""}

ORIGINAL PROMPT: {prompt}

Respond in this exact format:
ENHANCED: [your enhanced prompt here]
NEGATIVE: [negative prompt - things to avoid]
SUGGESTIONS: [1-2 additional tips for better results]"""

        response = model.generate_content(system_prompt)
        text = response.text.strip()

        # Parse response
        enhanced_prompt = prompt
        negative_prompt = style_config.get("negative_base", "")
        suggestions = []

        if "ENHANCED:" in text:
            parts = text.split("ENHANCED:")[1]
            if "NEGATIVE:" in parts:
                enhanced_prompt = parts.split("NEGATIVE:")[0].strip()
                parts = parts.split("NEGATIVE:")[1]
                if "SUGGESTIONS:" in parts:
                    negative_prompt = parts.split("SUGGESTIONS:")[0].strip()
                    suggestions = parts.split("SUGGESTIONS:")[1].strip().split("\n")
                else:
                    negative_prompt = parts.strip()
            else:
                enhanced_prompt = parts.strip()
        else:
            # If format not followed, use full response as enhanced prompt
            enhanced_prompt = text

        # Apply provider optimization suffix
        if provider_config.get("style_suffix"):
            enhanced_prompt = f"{enhanced_prompt}, {provider_config['style_suffix']}"

        # Truncate if needed
        max_len = provider_config.get("max_length", 1000)
        if len(enhanced_prompt) > max_len:
            enhanced_prompt = enhanced_prompt[:max_len-3] + "..."

        return {
            "enhanced_prompt": enhanced_prompt,
            "negative_prompt": negative_prompt,
            "suggestions": [s.strip() for s in suggestions if s.strip()]
        }

    except Exception as e:
        return {"note": f"Gemini enhancement failed: {str(e)}"}


async def _enhance_with_openai(
    prompt: str,
    style_config: dict,
    provider_config: dict,
    language: str
) -> Optional[Dict[str, Any]]:
    """Enhance prompt using OpenAI GPT-4"""
    try:
        async with httpx.AsyncClient(timeout=60) as client:
            response = await client.post(
                "https://api.openai.com/v1/chat/completions",
                headers={
                    "Authorization": f"Bearer {settings.openai_api_key}",
                    "Content-Type": "application/json"
                },
                json={
                    "model": "gpt-4o-mini",
                    "messages": [
                        {
                            "role": "system",
                            "content": f"""You are an expert AI image prompt engineer. Transform basic prompts into detailed, professional prompts.

STYLE: {style_config['name']}
{style_config['instruction']}

Keep under {provider_config.get('max_length', 1000)} characters. Be specific about visual details, lighting, composition, and mood."""
                        },
                        {
                            "role": "user",
                            "content": f"Enhance this prompt for {style_config['name']} style:\n\n{prompt}\n\nRespond with only the enhanced prompt, nothing else."
                        }
                    ],
                    "temperature": 0.7,
                    "max_tokens": 500
                }
            )
            response.raise_for_status()
            data = response.json()

            enhanced_prompt = data["choices"][0]["message"]["content"].strip()

            # Apply provider optimization
            if provider_config.get("style_suffix"):
                enhanced_prompt = f"{enhanced_prompt}, {provider_config['style_suffix']}"

            return {
                "enhanced_prompt": enhanced_prompt,
                "negative_prompt": style_config.get("negative_base", "blurry, low quality")
            }

    except Exception as e:
        return {"note": f"OpenAI enhancement failed: {str(e)}"}


def _enhance_fallback(
    prompt: str,
    style_config: dict,
    provider_config: dict
) -> Dict[str, Any]:
    """Rule-based fallback enhancement when no API is available"""

    # Basic enhancement patterns
    enhancements = {
        "cinematic": "cinematic lighting, dramatic composition, film grain, shallow depth of field, atmospheric, 8K resolution",
        "photographic": "professional photography, sharp focus, natural lighting, high resolution, detailed",
        "artistic": "artistic style, painterly, rich colors, textured brushstrokes, masterpiece",
        "product": "studio lighting, clean white background, professional product photography, sharp details",
        "fantasy": "magical atmosphere, ethereal lighting, fantasy art style, highly detailed, epic scale",
        "minimal": "minimalist composition, clean lines, negative space, simple elegant",
        "vintage": "vintage aesthetic, film grain, warm tones, retro style, nostalgic",
        "futuristic": "futuristic, sci-fi, neon lights, cyberpunk aesthetic, high tech",
        "anime": "anime style, vibrant colors, expressive, Japanese animation aesthetic",
        "portrait": "portrait photography, professional lighting, shallow depth of field, sharp focus",
        "landscape": "epic landscape, golden hour lighting, dramatic sky, high resolution",
        "abstract": "abstract art, bold colors, dynamic composition, non-representational",
        "fashion": "high fashion photography, editorial style, professional lighting, elegant",
        "architecture": "architectural photography, dramatic angles, professional composition",
        "food": "food photography, appetizing presentation, professional lighting, fresh"
    }

    style_key = style_config.get("name", "cinematic").lower().replace(" ", "_").replace("/", "_")
    base_enhancement = enhancements.get(style_key, enhancements["cinematic"])

    enhanced_prompt = f"{prompt}, {base_enhancement}"

    if provider_config.get("style_suffix"):
        enhanced_prompt = f"{enhanced_prompt}, {provider_config['style_suffix']}"

    return {
        "enhanced_prompt": enhanced_prompt,
        "negative_prompt": style_config.get("negative_base", "blurry, low quality, distorted, poorly drawn"),
        "note": "Enhanced using rule-based system (API keys not configured)"
    }


def get_available_styles() -> List[Dict[str, str]]:
    """Get list of available style presets"""
    return [
        {"id": key, "name": config["name"]}
        for key, config in STYLE_CONFIGS.items()
    ]


def get_style_info(style: str) -> Optional[Dict[str, Any]]:
    """Get detailed information about a style"""
    config = STYLE_CONFIGS.get(style)
    if not config:
        return None

    return {
        "id": style,
        "name": config["name"],
        "description": config["instruction"].split("\n")[0],
        "technical": config.get("technical", {}),
        "negative_base": config.get("negative_base", "")
    }
