"""
Seedream 4.0 MCP工具 - 参数验证模块

提供各种参数验证函数。
"""

from pathlib import Path
from typing import List, Union, Any
from urllib.parse import urlparse

from .errors import SeedreamValidationError


def validate_prompt(prompt: str, max_length: int = 600) -> str:
    """验证文本提示词
    
    Args:
        prompt: 文本提示词
        max_length: 最大长度（英文单词数或汉字数）
        
    Returns:
        验证后的提示词
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    if not prompt or not isinstance(prompt, str):
        raise SeedreamValidationError("提示词不能为空", field="prompt", value=prompt)
    
    prompt = prompt.strip()
    if not prompt:
        raise SeedreamValidationError("提示词不能为空", field="prompt", value=prompt)
    
    # 检查长度
    if len(prompt) > max_length:
        raise SeedreamValidationError(
            f"提示词过长，建议不超过{max_length}个字符（当前{len(prompt)}个字符）",
            field="prompt",
            value=prompt
        )
    
    return prompt


def validate_size(size: str) -> str:
    """验证图像尺寸参数
    
    Args:
        size: 图像尺寸
        
    Returns:
        验证后的尺寸
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    valid_sizes = ["1K", "2K", "4K"]
    
    if not size or not isinstance(size, str):
        raise SeedreamValidationError("图像尺寸不能为空", field="size", value=size)
    
    size = size.strip().upper()
    if size not in valid_sizes:
        raise SeedreamValidationError(
            f"图像尺寸必须是以下值之一: {valid_sizes}",
            field="size",
            value=size
        )
    
    return size


def validate_image_url(image: str) -> str:
    """验证图像URL或文件路径
    
    Args:
        image: 图像URL或文件路径
        
    Returns:
        验证后的图像路径
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    if not image or not isinstance(image, str):
        raise SeedreamValidationError("图像路径不能为空", field="image", value=image)
    
    image = image.strip()
    if not image:
        raise SeedreamValidationError("图像路径不能为空", field="image", value=image)
    
    # 检查是否为URL
    if image.startswith(("http://", "https://")):
        return _validate_url(image)
    else:
        return _validate_file_path(image)


def validate_image_list(images: List[str], min_count: int = 1, max_count: int = 5) -> List[str]:
    """验证图像列表
    
    Args:
        images: 图像URL或文件路径列表
        min_count: 最小数量
        max_count: 最大数量
        
    Returns:
        验证后的图像路径列表
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    if not images or not isinstance(images, list):
        raise SeedreamValidationError("图像列表不能为空", field="images", value=images)
    
    if len(images) < min_count:
        raise SeedreamValidationError(
            f"图像数量不能少于{min_count}张",
            field="images",
            value=images
        )
    
    if len(images) > max_count:
        raise SeedreamValidationError(
            f"图像数量不能超过{max_count}张",
            field="images",
            value=images
        )
    
    # 验证每个图像路径
    validated_images = []
    for i, image in enumerate(images):
        try:
            validated_image = validate_image_url(image)
            validated_images.append(validated_image)
        except SeedreamValidationError as e:
            raise SeedreamValidationError(
                f"第{i+1}张图像验证失败: {e.message}",
                field=f"images[{i}]",
                value=image
            )
    
    return validated_images


def validate_max_images(max_images: Any) -> int:
    """验证最大图像数量
    
    Args:
        max_images: 最大图像数量
        
    Returns:
        验证后的数量
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    if not isinstance(max_images, int):
        try:
            max_images = int(max_images)
        except (ValueError, TypeError):
            raise SeedreamValidationError(
                "最大图像数量必须是整数",
                field="max_images",
                value=max_images
            )
    
    if max_images < 1:
        raise SeedreamValidationError(
            "最大图像数量不能小于1",
            field="max_images",
            value=max_images
        )
    
    if max_images > 10:
        raise SeedreamValidationError(
            "最大图像数量不能超过10",
            field="max_images",
            value=max_images
        )
    
    return max_images


def validate_watermark(watermark: Any) -> bool:
    """验证水印参数
    
    Args:
        watermark: 水印设置
        
    Returns:
        验证后的布尔值
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    if isinstance(watermark, bool):
        return watermark
    
    if isinstance(watermark, str):
        watermark_lower = watermark.lower().strip()
        if watermark_lower in ("true", "1", "yes", "on"):
            return True
        elif watermark_lower in ("false", "0", "no", "off"):
            return False
        else:
            raise SeedreamValidationError(
                "水印参数必须是布尔值或有效的字符串（true/false）",
                field="watermark",
                value=watermark
            )
    
    raise SeedreamValidationError(
        "水印参数必须是布尔值",
        field="watermark",
        value=watermark
    )


def validate_response_format(response_format: str) -> str:
    """验证响应格式
    
    Args:
        response_format: 响应格式
        
    Returns:
        验证后的格式
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    valid_formats = ["url", "b64_json"]
    
    if not response_format or not isinstance(response_format, str):
        raise SeedreamValidationError(
            "响应格式不能为空",
            field="response_format",
            value=response_format
        )
    
    response_format = response_format.strip().lower()
    if response_format not in valid_formats:
        raise SeedreamValidationError(
            f"响应格式必须是以下值之一: {valid_formats}",
            field="response_format",
            value=response_format
        )
    
    return response_format


def _validate_url(url: str) -> str:
    """验证URL格式
    
    Args:
        url: URL字符串
        
    Returns:
        验证后的URL
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    try:
        parsed = urlparse(url)
        if not parsed.scheme or not parsed.netloc:
            raise SeedreamValidationError(
                "无效的URL格式",
                field="image",
                value=url
            )
        
        # 检查是否为图像URL（简单检查）
        if parsed.path:
            path_lower = parsed.path.lower()
            image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
            if not any(path_lower.endswith(ext) for ext in image_extensions):
                # 如果没有明显的图像扩展名，给出警告但不阻止
                pass
        
        return url
        
    except Exception as e:
        raise SeedreamValidationError(
            f"URL验证失败: {str(e)}",
            field="image",
            value=url
        )


def _validate_file_path(file_path: str) -> str:
    """验证文件路径
    
    Args:
        file_path: 文件路径
        
    Returns:
        验证后的文件路径
        
    Raises:
        SeedreamValidationError: 验证失败时抛出
    """
    try:
        path = Path(file_path)
        
        # 检查文件是否存在
        if not path.exists():
            raise SeedreamValidationError(
                f"文件不存在: {file_path}",
                field="image",
                value=file_path
            )
        
        # 检查是否为文件
        if not path.is_file():
            raise SeedreamValidationError(
                f"路径不是文件: {file_path}",
                field="image",
                value=file_path
            )
        
        # 检查文件扩展名
        image_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']
        if path.suffix.lower() not in image_extensions:
            raise SeedreamValidationError(
                f"不支持的图像格式: {path.suffix}，支持的格式: {image_extensions}",
                field="image",
                value=file_path
            )
        
        # 检查文件大小（限制为50MB）
        file_size = path.stat().st_size
        max_size = 50 * 1024 * 1024  # 50MB
        if file_size > max_size:
            raise SeedreamValidationError(
                f"文件过大: {file_size / 1024 / 1024:.1f}MB，最大支持50MB",
                field="image",
                value=file_path
            )
        
        return str(path.absolute())
        
    except SeedreamValidationError:
        raise
    except Exception as e:
        raise SeedreamValidationError(
            f"文件路径验证失败: {str(e)}",
            field="image",
            value=file_path
        )