import logging
import os
import json
import httpx
from typing import Optional
from src.services.provider.base import BaseImageService, ServiceResponse, TaskStatus, GenerationResult
from src.utils.image_processing import resolve_image_param

logger = logging.getLogger(__name__)

class VolcengineImageService(BaseImageService):
    BASE_URL = "https://ark.cn-beijing.volces.com/api/v3/images/generations"

    def __init__(self, model_name: str, api_key: Optional[str] = None, **kwargs):
        super().__init__(model_name, api_key=api_key, **kwargs)
        
        if not self.api_key:
             logger.warning("API Key is not set. API calls will fail.")

    async def generate(self, prompt: str, **kwargs) -> ServiceResponse:
        # Get effective API key (user key takes priority)
        user_id = kwargs.get('user_id')
        api_key = self.get_effective_api_key(user_id)
        if not api_key:
            logger.error(f"No API key available for {self._provider_id}")
            return ServiceResponse(
                status=TaskStatus.FAILED,
                error="API key not configured"
            )

        try:
            return await self._generate_async(prompt, api_key, **kwargs)
        except Exception as e:
            logger.error(f"Volcengine Image generation failed: {e}")
            return ServiceResponse(
                status=TaskStatus.FAILED,
                error=str(e)
            )
            
    async def _generate_async(self, prompt: str, api_key: str = None, **kwargs) -> ServiceResponse:
        # Use provided api_key or fall back to instance api_key
        effective_key = api_key or self.api_key

        headers = {
            "Authorization": f"Bearer {effective_key}",
            "Content-Type": "application/json"
        }
        
        # --- Unified Service Logic ---
        kwargs = self.normalize_image_kwargs(**kwargs)
        actual_model = self.model_name
        variants = getattr(self, "config", {}).get("variants")
        
        # 调试 logging for model and config
        logger.info(f"[Volcengine] ===== Image Generation Start =====")
        logger.info(f"[Volcengine] Initial model: {self.model_name}")
        logger.info(f"[Volcengine] Has config: {hasattr(self, 'config')}")
        if hasattr(self, 'config'):
            logger.info(f"[Volcengine] Config variants: {self.config.get('variants')}")
        logger.info(f"[Volcengine] Variants: {variants}")
        
        # Collect normalized image inputs
        image_urls = []
        if "image_inputs" in kwargs and isinstance(kwargs["image_inputs"], list):
            image_urls.extend(kwargs["image_inputs"])
        
        # Ensure all images are resolved (handles local paths -> base64, OSS signing)
        # This supports direct service calls where images might be local paths
        image_urls = [resolve_image_param(url) for url in image_urls]
        
        # 调试 logging
        if image_urls:
            logger.info(f"[Volcengine] Collected {len(image_urls)} reference images:")
            for i, url in enumerate(image_urls):
                logger.info(f"  [{i}] {url[:150] if len(url) > 150 else url}")

        if variants:
            if image_urls:
                actual_model = variants.get("i2i", variants.get("image", actual_model))
            else:
                actual_model = variants.get("t2i", actual_model)
        
        # 日志 final model after variant switch
        logger.info(f"[Volcengine] Final model (after variant switch): {actual_model}")

        payload = {
            "model": actual_model,
            "prompt": prompt,
        }
        
        # Add optional parameters based on API docs
        # 导入ANT: Volcengine requires minimum 3686400 pixels (e.g., 1920x1920)
        if "size" in kwargs:
             # Volcengine expects "WIDTHxHEIGHT" (e.g. "1280x720"), but API might send "1280*720"
             size_str = kwargs["size"].replace("*", "x")
             
             # 验证 minimum size requirement
             try:
                 width, height = map(int, size_str.split("x"))
                 total_pixels = width * height
                 if total_pixels < 3686400:
                     logger.warning(f"Size {size_str} ({total_pixels} pixels) is below minimum 3686400 pixels. Using default 2048x2048.")
                     size_str = "2048x2048"  # 默认 that meets minimum
             except (ValueError, TypeError):
                 logger.warning(f"Invalid size format: {size_str}. Using default 2048x2048.")
                 size_str = "2048x2048"
             
             payload["size"] = size_str
        
        # 'n' parameter mapping - API uses sequential_image_generation_options for multiple images
        if "n" in kwargs and isinstance(kwargs["n"], int) and kwargs["n"] > 1:
             payload["sequential_image_generation"] = "auto"
             payload["sequential_image_generation_options"] = {
                 "max_images": min(kwargs["n"], 15) # Max is 15
             }
        
        # 映射 common params to Volcengine specific params
        if "width" in kwargs and "height" in kwargs:
            # Volcengine expects "WIDTHxHEIGHT" (e.g. "1280x720"), but API might send "1280*720"
            # 验证 minimum size requirement
            width = int(kwargs['width'])
            height = int(kwargs['height'])
            total_pixels = width * height
            
            if total_pixels < 3686400:
                 logger.warning(f"Size {width}x{height} ({total_pixels} pixels) is below minimum 3686400 pixels. Using default 2048x2048.")
                 payload["size"] = "2048x2048"
            else:
                 payload["size"] = f"{width}x{height}"
        
        if "seed" in kwargs:
            payload["seed"] = kwargs["seed"]
            
        if "negative_prompt" in kwargs and kwargs["negative_prompt"]:
            # 注意: Verify if API supports negative_prompt directly or if it needs to be in style/parameters
            # Doubao, it's often supported at top level or not at all depending on version.
            # For now, suming standard field name for now.
            payload["negative_prompt"] = kwargs["negative_prompt"]

        if "watermark" in kwargs:
            payload["watermark"] = kwargs["watermark"]
        else:
            payload["watermark"] = False # 默认 to false per our preference? Doc says default true.

        # Handle reference images
        # API parameter is 'image' which can be string or array
            
        if image_urls:
            if len(image_urls) == 1:
                payload["image"] = image_urls[0]
            else:
                payload["image"] = image_urls # 列表 of URLs
                # 注意: doubao-seedream-4.5 supports single or multiple images.
                # For now, we're using multiple images for multi-reference generation.
            
            logger.info(f"[Volcengine] Added 'image' field to payload: {payload['image'][:150] if isinstance(payload['image'], str) and len(payload['image']) > 150 else payload['image']}")
        else:
            logger.info(f"[Volcengine] No reference images provided")
        
        try:
            logger.info(f"Submitting Volcengine Image task for model {actual_model}...")
            logger.info(f"Volcengine Payload: {json.dumps(payload, ensure_ascii=False)}")
            async with httpx.AsyncClient(timeout=120) as client:
                response = await client.post(
                    self.BASE_URL,
                    headers=headers,
                    data=json.dumps(payload),
                )
            
            if response.status_code != 200:
                logger.error(f"Volcengine API Error: {response.text}")
                
            response.raise_for_status()
            data = response.json()
            
            results = []
            for item in data.get("data", []):
                results.append(GenerationResult(url=item.get("url")))
                
            return ServiceResponse(
                status=TaskStatus.SUCCEEDED,
                results=results
            )
            
        except Exception as e:
            raise e

    async def check_status(self, task_id: str, user_id: Optional[str] = None) -> ServiceResponse:
        # Get effective API key (user key takes priority)
        api_key = self.get_effective_api_key(user_id)
        if not api_key:
            logger.error(f"No API key available for {self._provider_id}")
            return ServiceResponse(
                status=TaskStatus.FAILED,
                error="API key not configured"
            )

        # OpenAI compatible image generation is usually synchronous.
        # So we might not need this, but we implement it for interface compliance.
        return ServiceResponse(status=TaskStatus.UNKNOWN, error="Not supported for synchronous API")
