"""
图片下载器

负责下载和保存网络图片到本地文件系统。
"""

import os
import tempfile
from datetime import datetime
from pathlib import Path
from typing import Optional
from urllib.parse import urlparse

try:
    import requests
except ImportError:
    raise ImportError("requests is required for image download. Install with: pip install requests")


class ImageDownloader:
    """图片下载器，负责下载网络图片并保存到本地"""

    def __init__(self, default_save_dir: Optional[str] = None):
        """
        初始化图片下载器

        Args:
            default_save_dir: 默认保存目录，如果为 None 则使用系统临时目录
        """
        if default_save_dir:
            self.default_save_dir = Path(default_save_dir)
            self.default_save_dir.mkdir(parents=True, exist_ok=True)
        else:
            self.default_save_dir = None

    def download_image(
        self,
        url: str,
        save_path: Optional[str] = None,
        filename: Optional[str] = None
    ) -> str:
        """
        下载图片到本地

        Args:
            url: 图片 URL
            save_path: 保存路径（完整文件路径），如果提供则忽略 filename 和 default_save_dir
            filename: 保存的文件名，如果不提供则使用 URL 的文件名或自动生成

        Returns:
            str: 保存的本地文件路径

        Raises:
            ValueError: URL 无效
            Exception: 下载失败或保存失败
        """
        try:
            # 验证 URL
            if not url or not isinstance(url, str):
                raise ValueError("URL 无效")

            if not url.startswith(('http://', 'https://')):
                raise ValueError(f"URL 必须以 http:// 或 https:// 开头: {url}")

            # 下载图片
            headers = {
                'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36'
            }

            response = requests.get(url, headers=headers, timeout=30)
            response.raise_for_status()

            # 确定保存路径
            if save_path:
                # 使用完整路径
                file_path = Path(save_path)
                file_path.parent.mkdir(parents=True, exist_ok=True)
            else:
                # 确定保存目录
                save_dir = self.default_save_dir or Path(tempfile.gettempdir())

                # 确定文件名
                if not filename:
                    # 尝试从 URL 获取文件名
                    parsed_url = urlparse(url)
                    url_filename = os.path.basename(parsed_url.path)

                    if url_filename and url_filename.strip():
                        filename = url_filename
                    else:
                        # 自动生成文件名：generate_image_YYYYMMDD_HHMMSS.png
                        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                        filename = f"generate_image_{timestamp}.png"

                file_path = save_dir / filename

            # 保存图片
            with open(file_path, 'wb') as f:
                f.write(response.content)

            return str(file_path.resolve())

        except requests.RequestException as e:
            raise Exception(f"下载图片失败 (网络错误): {str(e)}")
        except IOError as e:
            raise Exception(f"保存图片失败 (文件错误): {str(e)}")
        except Exception as e:
            raise Exception(f"处理图片失败: {str(e)}")

    def download_image_to_temp(self, url: str) -> str:
        """
        下载图片到系统临时目录

        Args:
            url: 图片 URL

        Returns:
            str: 保存的本地文件路径
        """
        return self.download_image(url, save_path=None)


# 创建全局实例
_downloader: Optional[ImageDownloader] = None


def get_downloader(default_save_dir: Optional[str] = None) -> ImageDownloader:
    """获取全局下载器实例"""
    global _downloader
    if _downloader is None:
        _downloader = ImageDownloader(default_save_dir)
    return _downloader
