import concurrent
import requests
import json
import concurrent.futures
from typing import List
from typing import List, Dict, Any, Optional
from chuangliangTool.db_base import Chuangliang_ad_magic_task_skit, Chuangliang_ad_magic_cut, Material1_db, \
    Material2_db, Material3_db, Material4_db


class MagicTaskQuery:
    def __init__(self, task_id: int):
        self.task_id = task_id
        self.base_url = "https://tos.mobgi.com/"
        self.sql = f"SELECT task_id, batch_id, status, task_param, result_data, main_user_id, create_user_id " \
                   f"FROM chuangliang_ad_task_skit.task_log_client_mix_shear " \
                   f"WHERE task_id = {self.task_id}"
        self.detail_sql = f"SELECT rule_id, fission_mode, video_duration, create_task_time, " \
                          f"procssing_task_time, finish_task_time, main_user_id " \
                          f"FROM chuangliang_ad_task_skit.task_log_detail " \
                          f"WHERE task_id = {self.task_id}"
        self.material_sql = f"SELECT new_material_id, material_id, material_id_start, material_id_start_end, " \
                            f"start_time, end_time, use_duration, is_effect " \
                            f"FROM chuangliang_ad_magic_cut.client_material_relation " \
                            f"WHERE task_id = {self.task_id}"

    def _fetch_url_content(self, path: str) -> Optional[Dict[str, Any]]:
        """获取指定URL的内容并转换为JSON格式"""
        try:
            full_url = self.base_url + path
            response = requests.get(full_url, timeout=10)
            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            print(f"HTTP请求失败: {str(e)}")
            return None
        except json.JSONDecodeError as e:
            print(f"JSON解析失败: {str(e)}")
            return None

    def _parse_json_string(self, json_str: str) -> Dict[str, Any]:
        """解析JSON字符串"""
        try:
            return json.loads(json_str)
        except json.JSONDecodeError:
            return {"error_data": json_str}

    def _get_material_uris(self, material_id: int) -> Optional[str]:
        """获取素材URI"""
        material_sql = f"SELECT file_uri FROM chuangliang_ad_material.material WHERE material_id = {material_id}"
        # 先查询第一个库表
        try:
            result = Material1_db.query_database_select_to_dataframe(material_sql)
            if result and len(result) > 0:
                file_uri = result[0].get('file_uri')
                if file_uri:
                    return f"{self.base_url}{file_uri}"
        except Exception as e:
            print(f"查询material_id {material_id} 时Material1_db出错: {e}")

        # 第一个库表无结果或出错时查询第二个库表
        try:
            result = Material2_db.query_database_select_to_dataframe(material_sql)
            if result and len(result) > 0:
                file_uri = result[0].get('file_uri')
                if file_uri:
                    return f"{self.base_url}{file_uri}"
        except Exception as e:
            print(f"查询material_id {material_id} 时Material2_db出错: {e}")

        # 第二个库表无结果或出错时查第三个库表
        try:
            result = Material3_db.query_database_select_to_dataframe(material_sql)
            if result and len(result) > 0:
                file_uri = result[0].get('file_uri')
                if file_uri:
                    return f"{self.base_url}{file_uri}"
        except Exception as e:
            print(f"查询material_id {material_id} 时Material3_db出错: {e}")

        # 第三个库表无结果或出错时查第四个库表
        try:
            result = Material4_db.query_database_select_to_dataframe(material_sql)
            if result and len(result) > 0:
                file_uri = result[0].get('file_uri')
                if file_uri:
                    return f"{self.base_url}{file_uri}"
        except Exception as e:
            print(f"查询material_id {material_id} 时Material4_db出错: {e}")
        return None

    def _get_material_uri(self, material_id: int) -> Optional[str]:
        """获取素材URI - 并行查询优化"""
        material_sql = f"SELECT file_uri FROM chuangliang_ad_material.material WHERE material_id = {material_id}"

        databases = [Material1_db, Material2_db, Material3_db, Material4_db]
        db_names = ["Material1_db", "Material2_db", "Material3_db", "Material4_db"]

        def query_single_db(db, db_name):
            try:
                result = db.query_database_select_to_dataframe(material_sql)
                if result and len(result) > 0:
                    file_uri = result[0].get('file_uri')
                    if file_uri:
                        return f"{self.base_url}{file_uri}"
            except Exception as e:
                print(f"查询material_id {material_id} 时{db_name}出错: {e}")
            return None

        # 使用线程池并行查询
        with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
            futures = {
                executor.submit(query_single_db, db, name): (db, name)
                for db, name in zip(databases, db_names)
            }
            for future in concurrent.futures.as_completed(futures):
                result = future.result()
                if result:
                    # 取消其他未完成的查询
                    for f in futures:
                        if not f.done():
                            f.cancel()
                    return result
        return None

    def _process_material_data(self, query_results: List[Dict[str, Any]]) -> Dict[str, Any]:
        """处理素材关联表查询结果，生成指定JSON结构"""
        if not query_results:
            return {"new_material_id": None, "sum_use_duration": 0, "material_info": []}

        new_material_id = query_results[0]["new_material_id"]
        sum_use_duration = sum(record.get("use_duration", 0) for record in query_results)

        material_info = []
        for record in query_results:
            material_id = record["material_id"]
            material_uri = self._get_material_uri(material_id)

            material_record = {
                "material_id": material_id,
                "material_id_start": record.get("material_id_start"),
                "material_id_start_end": record.get("material_id_start_end"),
                "start_time": record.get("start_time"),
                "end_time": record.get("end_time"),
                "use_duration": record.get("use_duration"),
                "is_effect": record.get("is_effect"),
                "material_uri": material_uri
            }
            material_info.append(material_record)

        return {
            "new_material_id": new_material_id,
            "sum_use_duration": sum_use_duration,
            "material_info": material_info
        }

    def _get_video_materials(self, task_param):
        """
        从task_param中提取视频素材列表
        Args:
            task_param: 包含视频配置数据的字典

        Returns:
            list: 包含素材ID和名称的字典列表
        """
        video_materials = []

        # 检查mixed_shear_config是否存在
        if not task_param.get('mixed_shear_config'):
            return video_materials

        # 获取video_config_list
        video_config_list = task_param['mixed_shear_config'].get('video_config_list', [])

        # 遍历每个视频配置
        for video_config in video_config_list:
            # 获取每个配置中的video_list
            video_list = video_config.get('video_list', [])

            # 遍历每个视频
            for video in video_list:
                material_info = {
                    'material_id': video.get('material_id'),
                    'name': video.get('name'),
                    'file_uri': self._get_material_uri(video.get('material_id'))
                    # 'video_id': video.get('video_id'),
                    # 'duration': video.get('video_duration'),
                    # 'start_time': video.get('start_time')
                }
                video_materials.append(material_info)

        return video_materials

    def _process_audio_config(self, task_param: Dict[str, Any]) -> Dict[str, Any]:
        """处理音频配置"""
        result = []
        try:
            mixed_shear_config = task_param.get("mixed_shear_config")
            if not mixed_shear_config:
                print("mixed_shear_config为空")
                return result
            audio_config = mixed_shear_config.get("audio_config")
            if not audio_config:
                print("audio_config为空")
                return result
            for audio_info in audio_config:
                if not audio_info:
                    continue
                for audio_item in audio_info:
                    if not isinstance(audio_item, dict):
                        continue
                    # 提取material_id和name
                    material_id = audio_item.get('material_id')
                    name = audio_item.get('name')
                    if material_id is None:
                        print(f"音频项缺少material_id: {audio_item}")
                        continue
                    uri_file = self._get_material_uri(material_id)
                    result_item = {
                        "material_id": material_id,
                        "name": name,
                        "uri_file": uri_file
                    }
                    result.append(result_item)
            return result
        except Exception as e:
            print(f"处理音频配置时出错: {e}")
            return result

    def get_task_info(self) -> Dict[str, Any]:
        """获取任务信息并组合成最终结果"""
        # 获取主任务数据
        task_data_list = Chuangliang_ad_magic_task_skit.query_database_select_to_dataframe(self.sql)
        if not task_data_list:
            return {"error": f"未找到task_id为{self.task_id}的任务"}

        task_data = task_data_list[0]

        # 获取任务详情
        task_detail_list = Chuangliang_ad_magic_task_skit.query_database_select_to_dataframe(self.detail_sql)
        if not task_detail_list:
            return {"error": f"未找到task_id为{self.task_id}的任务详情"}

        detail_data = task_detail_list[0]

        # 获取任务参数
        if task_data['status'] != 'success':
            task_param = self._parse_json_string(task_data['task_param'])
        else:
            task_param = self._fetch_url_content(task_data['task_param'])

        # 处理结果数据
        result_data = self._parse_json_string(task_data['result_data'])

        # 获取素材信息
        material_info = Chuangliang_ad_magic_cut.query_database_select_to_dataframe(self.material_sql)
        # material_detail = self._process_material_data(material_info)
        material_detail = self._get_video_materials(task_param)
        # 构建最终结果
        return {
            "task_info": {
                "task_id": task_data['task_id'],
                "batch_id": task_data['batch_id'],
                "status": task_data['status'],
                "main_user_id": task_data['main_user_id'],
                "create_user_id": task_data['create_user_id']
            },
            "task_param": task_param,
            "result_data": result_data,
            "task_detail": {
                "rule_id": detail_data['rule_id'],
                "fission_mode": detail_data['fission_mode'],
                "video_duration": detail_data['video_duration'],
                "create_task_time": str(detail_data.get('create_task_time', '')),
                "procssing_task_time": str(detail_data.get('procssing_task_time', '')),
                "finish_task_time": str(detail_data.get('finish_task_time', '')),
                "main_user_id": detail_data['main_user_id']
            },
            "material_detail": material_detail,
            "audio_config": self._process_audio_config(task_param)
        }


def main():
    """主函数示例"""
    task_id = 33580458
    task_query = MagicTaskQuery(task_id)
    result = task_query.get_task_info()
    # 格式化输出JSON
    formatted_result = json.dumps(result, ensure_ascii=False)
    print(formatted_result)


if __name__ == "__main__":
    main()
