"""
素材管理模块

实现微信公众号素材管理相关API
"""

from typing import Optional, Dict, Any, Union
from io import BytesIO
from ..core import Auth, Client


class Asset:
    """
    素材管理类
    
    用于管理微信公众号的永久素材和临时素材
    """
    
    def __init__(self, auth: Auth):
        """
        初始化素材管理
        
        :param auth: 认证管理实例
        """
        self.auth = auth
        self.client = Client(proxy=auth.proxy)
    
    def get_material(self, media_id: str) -> Union[Dict[str, Any], bytes]:
        """
        获取永久素材
        
        :param media_id: 素材的media_id
        :return: 图文消息返回字典，其他类型返回二进制数据
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={access_token}"
        
        data = {"media_id": media_id}
        response = self.client.post(url, data)
        
        # 如果是图文消息，返回字典
        if isinstance(response, dict) and 'news_item' in response:
            return response
        # 其他类型返回二进制数据
        else:
            # 重新请求获取二进制数据
            return self.client.download(url, data=data)
    
    def get_material_count(self) -> Dict[str, Any]:
        """
        获取永久素材总数
        
        :return: 各类素材的总数
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token={access_token}"
        
        return self.client.get(url)
    
    def batch_get_material(self, material_type: str, offset: int = 0, count: int = 20) -> Dict[str, Any]:
        """
        获取永久素材列表
        
        :param material_type: 素材类型，可选值：image, video, voice, news
        :param offset: 从全部素材的该偏移位置开始返回，0表示从第一个素材返回
        :param count: 返回素材的数量，取值在1到20之间
        :return: 素材列表
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token={access_token}"
        
        data = {
            "type": material_type,
            "offset": offset,
            "count": count
        }
        
        return self.client.post(url, data)
    
    def upload_image(self, image_path: Optional[str] = None, image_content: Optional[bytes] = None, image_url: Optional[str] = None) -> Dict[str, Any]:
        """
        上传图文消息图片

        :param image_path: 图片文件路径
        :param image_content: 图片二进制内容
        :param image_url: 网络图片URL
        :return: 图片URL
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={access_token}"

        files = {}
        file_to_close = None

        if image_url:
            import requests
            response = requests.get(image_url)
            response.raise_for_status()
            image_content = response.content

        if image_path:
            files["media"] = open(image_path, "rb")
            file_to_close = files["media"]
        elif image_content:
            files["media"] = ("image.jpg", BytesIO(image_content), "image/jpeg")
        else:
            raise ValueError("❌ 请提供图片文件路径、图片二进制内容或图片URL")

        try:
            return self.client.upload(url, files)
        finally:
            if file_to_close:
                file_to_close.close()
    
    def add_material(self, media_type: str, media_path: Optional[str] = None, 
                    media_content: Optional[bytes] = None, description: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
        """
        上传永久素材
        
        :param media_type: 素材类型，可选值：image, video, voice, news
        :param media_path: 文件路径
        :param media_content: 文件二进制内容
        :param description: 视频素材的描述信息，格式为 {"title": "标题", "introduction": "描述"}
        :return: 素材的media_id等信息
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={access_token}&type={media_type}"
        
        # 准备文件数据
        files = {}
        if media_path:
            files["media"] = open(media_path, "rb")
        elif media_content:
            files["media"] = ("file", BytesIO(media_content))
        else:
            raise ValueError("❌ 请提供文件路径或文件二进制内容")
        
        try:
            return self.client.upload(url, files, data=description)
        finally:
            # 关闭文件
            if media_path and "media" in files:
                files["media"].close()
    
    def del_material(self, media_id: str) -> Dict[str, Any]:
        """
        删除永久素材
        
        :param media_id: 素材的media_id
        :return: 删除结果
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/material/del_material?access_token={access_token}"
        
        data = {"media_id": media_id}
        return self.client.post(url, data)
    
    def get_media(self, media_id: str) -> bytes:
        """
        获取临时素材
        
        :param media_id: 素材的media_id
        :return: 素材二进制内容
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/media/get?access_token={access_token}&media_id={media_id}"
        
        return self.client.download(url)
    
    def upload_temp_media(self, media_type: str, media_path: Optional[str] = None, 
                         media_content: Optional[bytes] = None) -> Dict[str, Any]:
        """
        新增临时素材
        
        :param media_type: 素材类型，可选值：image, video, voice, thumb
        :param media_path: 文件路径
        :param media_content: 文件二进制内容
        :return: 素材的media_id等信息
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/media/upload?access_token={access_token}&type={media_type}"
        
        # 准备文件数据
        files = {}
        if media_path:
            files["media"] = open(media_path, "rb")
        elif media_content:
            files["media"] = ("file", BytesIO(media_content))
        else:
            raise ValueError("❌ 请提供文件路径或文件二进制内容")
        
        try:
            return self.client.upload(url, files)
        finally:
            # 关闭文件
            if media_path and "media" in files:
                files["media"].close()
    
    def get_hd_voice(self, media_id: str) -> bytes:
        """
        获取高清语音素材
        
        :param media_id: 素材的media_id
        :return: 语音素材二进制内容
        """
        access_token = self.auth.get_access_token()
        url = f"https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token={access_token}&media_id={media_id}"
        
        return self.client.download(url)
