"""Configuration settings for Stability AI integration."""

import os
from typing import Dict, Any, List, Optional
from dataclasses import dataclass
from enum import Enum


class StabilityEndpoint(Enum):
    """Stability AI API endpoints."""
    # Generate endpoints
    GENERATE_ULTRA = "/v2beta/stable-image/generate/ultra"
    GENERATE_CORE = "/v2beta/stable-image/generate/core"
    GENERATE_SD3 = "/v2beta/stable-image/generate/sd3"
    
    # Edit endpoints
    EDIT_ERASE = "/v2beta/stable-image/edit/erase"
    EDIT_INPAINT = "/v2beta/stable-image/edit/inpaint"
    EDIT_OUTPAINT = "/v2beta/stable-image/edit/outpaint"
    EDIT_SEARCH_REPLACE = "/v2beta/stable-image/edit/search-and-replace"
    EDIT_SEARCH_RECOLOR = "/v2beta/stable-image/edit/search-and-recolor"
    EDIT_REMOVE_BACKGROUND = "/v2beta/stable-image/edit/remove-background"
    EDIT_REPLACE_BACKGROUND = "/v2beta/stable-image/edit/replace-background-and-relight"
    
    # Upscale endpoints
    UPSCALE_FAST = "/v2beta/stable-image/upscale/fast"
    UPSCALE_CONSERVATIVE = "/v2beta/stable-image/upscale/conservative"
    UPSCALE_CREATIVE = "/v2beta/stable-image/upscale/creative"
    
    # Control endpoints
    CONTROL_SKETCH = "/v2beta/stable-image/control/sketch"
    CONTROL_STRUCTURE = "/v2beta/stable-image/control/structure"
    CONTROL_STYLE = "/v2beta/stable-image/control/style"
    CONTROL_STYLE_TRANSFER = "/v2beta/stable-image/control/style-transfer"
    
    # 3D endpoints
    STABLE_FAST_3D = "/v2beta/3d/stable-fast-3d"
    STABLE_POINT_AWARE_3D = "/v2beta/3d/stable-point-aware-3d"
    
    # Audio endpoints
    AUDIO_TEXT_TO_AUDIO = "/v2beta/audio/stable-audio-2/text-to-audio"
    AUDIO_AUDIO_TO_AUDIO = "/v2beta/audio/stable-audio-2/audio-to-audio"
    AUDIO_INPAINT = "/v2beta/audio/stable-audio-2/inpaint"
    
    # Results endpoint
    RESULTS = "/v2beta/results/{id}"
    
    # Legacy V1 endpoints
    V1_TEXT_TO_IMAGE = "/v1/generation/{engine_id}/text-to-image"
    V1_IMAGE_TO_IMAGE = "/v1/generation/{engine_id}/image-to-image"
    V1_MASKING = "/v1/generation/{engine_id}/image-to-image/masking"
    
    # User endpoints
    USER_ACCOUNT = "/v1/user/account"
    USER_BALANCE = "/v1/user/balance"
    ENGINES_LIST = "/v1/engines/list"


@dataclass
class StabilityConfig:
    """Configuration for Stability AI service."""
    api_key: str
    base_url: str = "https://api.stability.ai"
    timeout: int = 300
    max_retries: int = 3
    rate_limit_requests: int = 150
    rate_limit_window: int = 10  # seconds
    max_file_size: int = 10 * 1024 * 1024  # 10MB
    supported_image_formats: List[str] = None
    supported_audio_formats: List[str] = None
    
    def __post_init__(self):
        if self.supported_image_formats is None:
            self.supported_image_formats = ["jpeg", "jpg", "png", "webp"]
        if self.supported_audio_formats is None:
            self.supported_audio_formats = ["mp3", "wav"]


# Model pricing information
MODEL_PRICING = {
    "generate": {
        "ultra": 8,
        "core": 3,
        "sd3.5-large": 6.5,
        "sd3.5-large-turbo": 4,
        "sd3.5-medium": 3.5,
        "sd3.5-flash": 2.5
    },
    "edit": {
        "erase": 5,
        "inpaint": 5,
        "outpaint": 4,
        "search_and_replace": 5,
        "search_and_recolor": 5,
        "remove_background": 5,
        "replace_background_and_relight": 8
    },
    "upscale": {
        "fast": 2,
        "conservative": 40,
        "creative": 60
    },
    "control": {
        "sketch": 5,
        "structure": 5,
        "style": 5,
        "style_transfer": 8
    },
    "3d": {
        "stable_fast_3d": 10,
        "stable_point_aware_3d": 4
    },
    "audio": {
        "text_to_audio": 20,
        "audio_to_audio": 20,
        "inpaint": 20
    }
}

# Image dimension limits
IMAGE_LIMITS = {
    "generate": {
        "min_pixels": 4096,
        "max_pixels": 16777216,  # 16MP
        "min_dimension": 64,
        "max_dimension": 16384
    },
    "edit": {
        "min_pixels": 4096,
        "max_pixels": 9437184,  # ~9.4MP
        "min_dimension": 64,
        "aspect_ratio_min": 0.4,  # 1:2.5
        "aspect_ratio_max": 2.5   # 2.5:1
    },
    "upscale": {
        "fast": {
            "min_width": 32,
            "max_width": 1536,
            "min_height": 32,
            "max_height": 1536,
            "min_pixels": 1024,
            "max_pixels": 1048576
        },
        "conservative": {
            "min_pixels": 4096,
            "max_pixels": 9437184,
            "min_dimension": 64
        },
        "creative": {
            "min_pixels": 4096,
            "max_pixels": 1048576,
            "min_dimension": 64
        }
    },
    "control": {
        "min_pixels": 4096,
        "max_pixels": 9437184,
        "min_dimension": 64,
        "aspect_ratio_min": 0.4,
        "aspect_ratio_max": 2.5
    },
    "3d": {
        "min_pixels": 4096,
        "max_pixels": 4194304,  # 4MP
        "min_dimension": 64
    }
}

# Audio limits
AUDIO_LIMITS = {
    "min_duration": 6,
    "max_duration": 190,
    "max_file_size": 50 * 1024 * 1024,  # 50MB
    "supported_formats": ["mp3", "wav"]
}

# Style preset descriptions
STYLE_PRESET_DESCRIPTIONS = {
    "enhance": "Enhance the natural qualities of the image",
    "anime": "Japanese animation style",
    "photographic": "Realistic photographic style",
    "digital-art": "Digital artwork style",
    "comic-book": "Comic book illustration style",
    "fantasy-art": "Fantasy and magical themes",
    "line-art": "Clean line art style",
    "analog-film": "Vintage film photography style",
    "neon-punk": "Cyberpunk with neon lighting",
    "isometric": "Isometric 3D perspective",
    "low-poly": "Low polygon 3D style",
    "origami": "Paper folding art style",
    "modeling-compound": "Clay or modeling compound style",
    "cinematic": "Movie-like cinematic style",
    "3d-model": "3D rendered model style",
    "pixel-art": "Retro pixel art style",
    "tile-texture": "Seamless tile texture style"
}

# Default parameters for different operations
DEFAULT_PARAMETERS = {
    "generate": {
        "ultra": {
            "aspect_ratio": "1:1",
            "output_format": "png"
        },
        "core": {
            "aspect_ratio": "1:1",
            "output_format": "png"
        },
        "sd3": {
            "model": "sd3.5-large",
            "mode": "text-to-image",
            "aspect_ratio": "1:1",
            "output_format": "png"
        }
    },
    "edit": {
        "erase": {
            "grow_mask": 5,
            "output_format": "png"
        },
        "inpaint": {
            "grow_mask": 5,
            "output_format": "png"
        },
        "outpaint": {
            "creativity": 0.5,
            "output_format": "png"
        }
    },
    "upscale": {
        "fast": {
            "output_format": "png"
        },
        "conservative": {
            "creativity": 0.35,
            "output_format": "png"
        },
        "creative": {
            "creativity": 0.3,
            "output_format": "png"
        }
    },
    "control": {
        "sketch": {
            "control_strength": 0.7,
            "output_format": "png"
        },
        "structure": {
            "control_strength": 0.7,
            "output_format": "png"
        },
        "style": {
            "aspect_ratio": "1:1",
            "fidelity": 0.5,
            "output_format": "png"
        }
    },
    "3d": {
        "stable_fast_3d": {
            "texture_resolution": "1024",
            "foreground_ratio": 0.85,
            "remesh": "none",
            "vertex_count": -1
        },
        "stable_point_aware_3d": {
            "texture_resolution": "1024",
            "foreground_ratio": 1.3,
            "remesh": "none",
            "target_type": "none",
            "target_count": 1000,
            "guidance_scale": 3
        }
    },
    "audio": {
        "text_to_audio": {
            "duration": 190,
            "model": "stable-audio-2",
            "output_format": "mp3"
        },
        "audio_to_audio": {
            "duration": 190,
            "model": "stable-audio-2",
            "output_format": "mp3",
            "strength": 1
        },
        "inpaint": {
            "duration": 190,
            "steps": 8,
            "output_format": "mp3",
            "mask_start": 30,
            "mask_end": 190
        }
    }
}

# Rate limiting configuration
RATE_LIMIT_CONFIG = {
    "requests_per_window": 150,
    "window_seconds": 10,
    "timeout_seconds": 60,
    "burst_allowance": 10  # Allow brief bursts above limit
}

# Content moderation settings
CONTENT_MODERATION = {
    "enabled": True,
    "blocked_keywords": [
        # This would contain actual blocked keywords in production
    ],
    "warning_keywords": [
        # Keywords that trigger warnings but don't block
    ]
}

# Quality settings for different use cases
QUALITY_PRESETS = {
    "draft": {
        "model": "core",
        "steps": None,  # Use model defaults
        "cfg_scale": None,
        "description": "Fast generation for drafts and iterations"
    },
    "standard": {
        "model": "sd3.5-medium",
        "steps": None,
        "cfg_scale": 4,
        "description": "Balanced quality and speed"
    },
    "premium": {
        "model": "ultra",
        "steps": None,
        "cfg_scale": None,
        "description": "Highest quality for final outputs"
    },
    "professional": {
        "model": "sd3.5-large",
        "steps": None,
        "cfg_scale": 4,
        "style_preset": "photographic",
        "description": "Professional photography style"
    }
}

# Workflow templates
WORKFLOW_TEMPLATES = {
    "portrait_enhancement": {
        "description": "Enhance portrait photos with professional quality",
        "steps": [
            {"operation": "upscale_conservative", "params": {"creativity": 0.2}},
            {"operation": "inpaint", "params": {"prompt": "professional portrait, high quality"}}
        ]
    },
    "art_creation": {
        "description": "Create artistic images from sketches",
        "steps": [
            {"operation": "control_sketch", "params": {"control_strength": 0.8}},
            {"operation": "upscale_fast", "params": {}}
        ]
    },
    "product_photography": {
        "description": "Create professional product images",
        "steps": [
            {"operation": "remove_background", "params": {}},
            {"operation": "replace_background_and_relight", "params": {"background_prompt": "professional studio lighting, white background"}}
        ]
    },
    "creative_exploration": {
        "description": "Explore different creative interpretations",
        "steps": [
            {"operation": "generate_core", "params": {}},
            {"operation": "control_style", "params": {"fidelity": 0.7}},
            {"operation": "upscale_creative", "params": {"creativity": 0.4}}
        ]
    }
}


def get_stability_config() -> StabilityConfig:
    """Get Stability AI configuration from environment variables.
    
    Returns:
        StabilityConfig instance
    """
    api_key = os.getenv("STABILITY_API_KEY")
    if not api_key:
        raise ValueError("STABILITY_API_KEY environment variable is required")
    
    return StabilityConfig(
        api_key=api_key,
        base_url=os.getenv("STABILITY_BASE_URL", "https://api.stability.ai"),
        timeout=int(os.getenv("STABILITY_TIMEOUT", "300")),
        max_retries=int(os.getenv("STABILITY_MAX_RETRIES", "3")),
        max_file_size=int(os.getenv("STABILITY_MAX_FILE_SIZE", str(10 * 1024 * 1024)))
    )


def validate_image_requirements(
    width: int, 
    height: int, 
    operation: str
) -> Dict[str, Any]:
    """Validate image requirements for specific operations.
    
    Args:
        width: Image width
        height: Image height
        operation: Operation type (generate, edit, upscale, etc.)
        
    Returns:
        Validation result with success status and any issues
    """
    issues = []
    
    limits = IMAGE_LIMITS.get(operation, IMAGE_LIMITS["generate"])
    total_pixels = width * height
    
    # Check minimum requirements
    if "min_pixels" in limits and total_pixels < limits["min_pixels"]:
        issues.append(f"Image must have at least {limits['min_pixels']} pixels")
    
    if "max_pixels" in limits and total_pixels > limits["max_pixels"]:
        issues.append(f"Image must have at most {limits['max_pixels']} pixels")
    
    if "min_dimension" in limits:
        if width < limits["min_dimension"] or height < limits["min_dimension"]:
            issues.append(f"Both dimensions must be at least {limits['min_dimension']} pixels")
    
    # Check aspect ratio for operations that require it
    if "aspect_ratio_min" in limits and "aspect_ratio_max" in limits:
        aspect_ratio = width / height
        if aspect_ratio < limits["aspect_ratio_min"] or aspect_ratio > limits["aspect_ratio_max"]:
            issues.append(f"Aspect ratio must be between {limits['aspect_ratio_min']}:1 and {limits['aspect_ratio_max']}:1")
    
    return {
        "is_valid": len(issues) == 0,
        "issues": issues,
        "total_pixels": total_pixels,
        "aspect_ratio": round(width / height, 3)
    }


def get_model_recommendations(
    use_case: str,
    quality_preference: str = "standard",
    speed_preference: str = "balanced"
) -> Dict[str, Any]:
    """Get model recommendations based on use case and preferences.
    
    Args:
        use_case: Type of use case (portrait, landscape, art, product, etc.)
        quality_preference: Quality preference (draft, standard, premium)
        speed_preference: Speed preference (fast, balanced, quality)
        
    Returns:
        Model recommendations with explanations
    """
    recommendations = {}
    
    # Base recommendations by use case
    if use_case == "portrait":
        recommendations["primary"] = "ultra"
        recommendations["alternative"] = "sd3.5-large"
        recommendations["style_preset"] = "photographic"
    elif use_case == "art":
        recommendations["primary"] = "sd3.5-large"
        recommendations["alternative"] = "ultra"
        recommendations["style_preset"] = "digital-art"
    elif use_case == "product":
        recommendations["primary"] = "ultra"
        recommendations["alternative"] = "sd3.5-large"
        recommendations["style_preset"] = "photographic"
    elif use_case == "concept":
        recommendations["primary"] = "core"
        recommendations["alternative"] = "sd3.5-medium"
        recommendations["style_preset"] = "enhance"
    else:
        recommendations["primary"] = "core"
        recommendations["alternative"] = "sd3.5-medium"
    
    # Adjust based on preferences
    if speed_preference == "fast":
        if recommendations["primary"] == "ultra":
            recommendations["primary"] = "core"
        elif recommendations["primary"] == "sd3.5-large":
            recommendations["primary"] = "sd3.5-medium"
    elif speed_preference == "quality":
        if recommendations["primary"] == "core":
            recommendations["primary"] = "ultra"
        elif recommendations["primary"] == "sd3.5-medium":
            recommendations["primary"] = "sd3.5-large"
    
    # Add quality preset
    if quality_preference in QUALITY_PRESETS:
        recommendations.update(QUALITY_PRESETS[quality_preference])
    
    return recommendations


def get_optimal_parameters(
    operation: str,
    image_info: Optional[Dict[str, Any]] = None,
    user_preferences: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """Get optimal parameters for a specific operation.
    
    Args:
        operation: Operation type
        image_info: Information about input image
        user_preferences: User preferences
        
    Returns:
        Optimal parameters for the operation
    """
    # Start with defaults
    params = DEFAULT_PARAMETERS.get(operation, {}).copy()
    
    # Adjust based on image characteristics
    if image_info:
        total_pixels = image_info.get("total_pixels", 0)
        
        # Adjust creativity based on image quality
        if "creativity" in params:
            if total_pixels < 100000:  # Very low res
                params["creativity"] = min(params["creativity"] + 0.1, 0.5)
            elif total_pixels > 2000000:  # High res
                params["creativity"] = max(params["creativity"] - 0.1, 0.1)
    
    # Apply user preferences
    if user_preferences:
        for key, value in user_preferences.items():
            if key in params:
                params[key] = value
    
    return params


def calculate_estimated_cost(
    operation: str,
    model: Optional[str] = None,
    steps: Optional[int] = None
) -> float:
    """Calculate estimated cost in credits for an operation.
    
    Args:
        operation: Operation type
        model: Model name (if applicable)
        steps: Number of steps (for step-based pricing)
        
    Returns:
        Estimated cost in credits
    """
    if operation in MODEL_PRICING:
        if isinstance(MODEL_PRICING[operation], dict):
            if model and model in MODEL_PRICING[operation]:
                base_cost = MODEL_PRICING[operation][model]
            else:
                # Use default model cost
                base_cost = list(MODEL_PRICING[operation].values())[0]
        else:
            base_cost = MODEL_PRICING[operation]
    else:
        base_cost = 5  # Default cost
    
    # Adjust for steps if applicable (mainly for audio)
    if steps and operation.startswith("audio") and model == "stable-audio-2":
        # Audio 2.0 uses formula: 17 + 0.06 * steps
        return 17 + 0.06 * steps
    
    return base_cost


def get_operation_limits(operation: str) -> Dict[str, Any]:
    """Get limits and constraints for a specific operation.
    
    Args:
        operation: Operation type
        
    Returns:
        Limits and constraints
    """
    limits = {
        "file_size_limit": 10 * 1024 * 1024,  # 10MB default
        "timeout": 300,
        "rate_limit": True
    }
    
    # Add operation-specific limits
    if operation in IMAGE_LIMITS:
        limits.update(IMAGE_LIMITS[operation])
    
    if operation.startswith("audio"):
        limits.update(AUDIO_LIMITS)
        limits["file_size_limit"] = 50 * 1024 * 1024  # 50MB for audio
    
    if operation.startswith("3d"):
        limits["file_size_limit"] = 10 * 1024 * 1024  # 10MB for 3D
    
    return limits


# Environment-specific configurations
def get_environment_config() -> Dict[str, Any]:
    """Get environment-specific configuration.
    
    Returns:
        Environment configuration
    """
    env = os.getenv("ENVIRONMENT", "development")
    
    configs = {
        "development": {
            "debug_mode": True,
            "log_level": "DEBUG",
            "cache_results": False,
            "mock_responses": False
        },
        "staging": {
            "debug_mode": True,
            "log_level": "INFO",
            "cache_results": True,
            "mock_responses": False
        },
        "production": {
            "debug_mode": False,
            "log_level": "WARNING",
            "cache_results": True,
            "mock_responses": False
        }
    }
    
    return configs.get(env, configs["development"])


# Feature flags
FEATURE_FLAGS = {
    "enable_batch_processing": True,
    "enable_webhooks": True,
    "enable_caching": True,
    "enable_analytics": True,
    "enable_experimental_endpoints": True,
    "enable_quality_analysis": True,
    "enable_prompt_optimization": True,
    "enable_workflow_templates": True
}


def is_feature_enabled(feature: str) -> bool:
    """Check if a feature is enabled.
    
    Args:
        feature: Feature name
        
    Returns:
        True if feature is enabled
    """
    return FEATURE_FLAGS.get(feature, False)