"""
DashScope Parameter Adapter

Transforms standard parameters into DashScope (Alibaba Cloud) API format.
"""

from typing import Dict, Any, Optional
from src.services.provider.adapters import ParameterAdapter, register_adapter
from src.services.provider.base import ServiceResponse, TaskStatus, GenerationResult


class DashScopeVideoAdapter(ParameterAdapter):
    """ Adapter for DashScope (Alibaba Cloud) video generation API. """
    
    provider_name = "dashscope"
    
    def adapt_generate_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """ Transform standard params to DashScope format.
        
        DashScope expects:
        - input.prompt: Text prompt
        - input.img_url: Single image URL for I2V
        - input.first_frame_url: First frame for KF2V
        - input.last_frame_url: Last frame for KF2V
        - parameters.duration: Video duration
        - parameters.size: Resolution string
        """
        result = {
            "input": {},
            "parameters": {}
        }
        
        # Prompt
        if params.get("prompt"):
            result["input"]["prompt"] = params["prompt"]
        
        # Handle image inputs
        image_inputs = params.get("image_inputs") or []
        
        if image_inputs:
            result["input"]["img_url"] = image_inputs[0]
            if len(image_inputs) > 1:
                result["input"]["last_frame_url"] = image_inputs[1]
        
        # Reference videos
        video_inputs = params.get("video_inputs")
        if video_inputs:
            result["input"]["ref_video_url"] = video_inputs[0]
        
        # 持续时间
        if params.get("duration"):
            result["parameters"]["duration"] = params["duration"]
        
        # Resolution/Size
        size = params.get("size")
        if size:
            result["parameters"]["size"] = size
        
        # Seed
        if params.get("seed") is not None:
            result["parameters"]["seed"] = params["seed"]
        
        # 清理 up empty dicts
        if not result["input"]:
            del result["input"]
        if not result["parameters"]:
            del result["parameters"]
        
        return result
    
    def adapt_response(self, raw_response: Dict[str, Any]) -> ServiceResponse:
        """ 转换 DashScope response to standard format."""
        output = raw_response.get("output", {})
        
        # 获取 task ID
        task_id = output.get("task_id")
        
        # 映射 status
        status_str = output.get("task_status", "UNKNOWN")
        status_map = {
            "PENDING": TaskStatus.PENDING,
            "RUNNING": TaskStatus.PROCESSING,
            "SUCCEEDED": TaskStatus.SUCCEEDED,
            "FAILED": TaskStatus.FAILED,
        }
        status = status_map.get(status_str, TaskStatus.UNKNOWN)
        
        # 提取 results
        results = []
        if status == TaskStatus.SUCCEEDED:
            video_url = output.get("video_url")
            if video_url:
                results.append(GenerationResult(url=video_url))
        
        # 错误 message
        error = output.get("message") if status == TaskStatus.FAILED else None
        
        return ServiceResponse(
            status=status,
            task_id=task_id,
            results=results if results else None,
            error=error
        )
    
    def get_actual_model(self, base_model: str, params: Dict[str, Any], variants: Optional[Dict[str, str]] = None) -> str:
        """Determine DashScope model variant based on inputs."""
        if not variants:
            return base_model
        
        # Unified input names
        image_inputs = params.get("image_inputs") or []
        video_inputs = params.get("video_inputs") or []
        
        has_last_frame = len(image_inputs) > 1
        has_image = len(image_inputs) > 0
        
        if video_inputs and "r2v" in variants:
            return variants["r2v"]
        elif has_last_frame and "kf2v" in variants:
            return variants["kf2v"]
        elif has_image and "i2v" in variants:
            return variants["i2v"]
        else:
            return variants.get("t2v", base_model)


class DashScopeImageAdapter(ParameterAdapter):
    """ Adapter for DashScope image generation API. """
    
    provider_name = "dashscope"
    
    def adapt_generate_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
        """ Transform standard params to DashScope image format. """
        result = {
            "input": {},
            "parameters": {}
        }
        
        if params.get("prompt"):
            result["input"]["prompt"] = params["prompt"]
        
        if params.get("negative_prompt"):
            result["input"]["negative_prompt"] = params["negative_prompt"]
        
        # Reference images for I2I (Unified name)
        ref_images = params.get("image_inputs")
        if ref_images:
            result["input"]["ref_img"] = ref_images[0]
        
        # 大小
        if params.get("size"):
            result["parameters"]["size"] = params["size"]
        
        # 数字 of images
        if params.get("n"):
            result["parameters"]["n"] = params["n"]
        
        # Seed
        if params.get("seed") is not None:
            result["parameters"]["seed"] = params["seed"]
        
        # 清理 up empty dicts
        if not result["input"]:
            del result["input"]
        if not result["parameters"]:
            del result["parameters"]
        
        return result
    
    def adapt_response(self, raw_response: Dict[str, Any]) -> ServiceResponse:
        """ 转换 DashScope image response to standard format."""
        output = raw_response.get("output", {})
        
        task_id = output.get("task_id")
        status_str = output.get("task_status", "UNKNOWN")
        
        status_map = {
            "PENDING": TaskStatus.PENDING,
            "RUNNING": TaskStatus.PROCESSING,
            "SUCCEEDED": TaskStatus.SUCCEEDED,
            "FAILED": TaskStatus.FAILED,
        }
        status = status_map.get(status_str, TaskStatus.UNKNOWN)
        
        results = []
        if status == TaskStatus.SUCCEEDED:
            # DashScope returns results in output.results array
            for item in output.get("results", []):
                if item.get("url"):
                    results.append(GenerationResult(url=item["url"]))
        
        error = output.get("message") if status == TaskStatus.FAILED else None
        
        return ServiceResponse(
            status=status,
            task_id=task_id,
            results=results if results else None,
            error=error
        )
