import re
from typing import Dict, List, Callable
import ai_utils
import spider_api
import asr_utils
import tos_utlis
import json


class PlatformParser:
    @staticmethod
    def parse_douyin(link: str) -> Dict:
        if "douyin" in link:
            return {"is_dy": True, "type": "video", "url": link}

    @staticmethod
    def parse_xiaohongshu(link: str) -> Dict:
        if "xiaohongshu" in link:
            return {"is_xhs": True, "type": "video", "url": link}

    @staticmethod
    def parse_bzhan(link: str) -> Dict:
        if "bilibili" in link:
            return {"is_bili": True, "type": "video", "url": link}

    @staticmethod
    def parse_ks(link: str) -> Dict:
        if "kuaishou" in link:
            return {"is_ks": True, "type": "video", "url": link}


def parse_url(link: str) -> Dict:
    parsers = {
        "dy": PlatformParser.parse_douyin,
        "xhs": PlatformParser.parse_xiaohongshu,
        "bili": PlatformParser.parse_bzhan,
        "ks": PlatformParser.parse_ks
    }

    for platform, parser in parsers.items():
        result = parser(link)
        if not result:
            continue
        if result.get(f"is_{platform}"):
            return {
                "platform": platform,
                "type": result.get("type", "unknown"),
                "url": result.get("url", link)
            }

    return {
        "platform": "unknown",
        "type": "unknown",
        "url": link
    }


PROCESSOR_REGISTRY: Dict[str, Dict[str, Callable]] = {
    "dy": {
        "video": lambda url, data: print(f"处理dy视频: {url}")
    },
    "xhs": {
        "video": lambda url, data: print(f"处理xhs视频: {url}")
    },
    "bili": {
        "video": lambda url, data: print(f"处理bili视频: {url}")
    },
    "ks": {
        "video": lambda url, data: print(f"处理ks视频: {url}")
    }
}


def register_processor(platform: str, content_type: str):
    def decorator(func):
        if platform not in PROCESSOR_REGISTRY:
            PROCESSOR_REGISTRY[platform] = {}
        PROCESSOR_REGISTRY[platform][content_type] = func
        return func

    return decorator


############################################################
# 抖音
@register_processor("dy", "video")
def process_douyin_video(url: str, data: Dict):
    data = spider_api.get_dy_ocr_info(url)
    if not data:
        result = {
            "platform": "dy",
            "type": "xxx",
            "base_info": url,
            "text": {
                "content": "链接有误",
                "role": "assistant"
            }
        }
        return result
    if tos_utlis.check_file_in_tos(f"assets/{data.get('video_id')}/{data.get('video_id')}.json"):
        return tos_utlis.get_string_from_tos(f"assets/{data.get('video_id')}/{data.get('video_id')}.json")
    else:
        if data.get('aweme_type') == 68:
            url_list = []
            for i in range(data.get('image_length')):
                if tos_utlis.check_file_in_tos(f"assets/{data.get('video_id')}/{i}.jpg"):
                    url_list.append({
                        "type": "image_url",
                        "image_url": {
                            "url": f"https://douchacha-web.tos-cn-beijing.volces.com/assets/{data.get('video_id')}/{i}.jpg"}
                    })
                else:
                    result = {
                        "platform": "dy",
                        "type": "image",
                        "base_info": data,
                        "text": {
                            "content": "图文提取失败请稍后重试",
                            "role": "assistant"
                        }
                    }
                    return result

            url_list.append({"type": "text", "text": "提取图片中的文字仅返回图中文字不要返回"})
            ai_reply, total_tokens = ai_utils.get_image_to_text(url_list)
            result = {
                "platform": "dy",
                "type": "image",
                "base_info": data,
                "text": ai_reply
            }
            tos_utlis.put_string_to_tos(
                f"assets/{data.get('video_id')}/{data.get('video_id')}.json",
                result)
            return result
        else:
            if data.get("duration") / 1000 / 60 > 20:
                result = {
                    "platform": "dy",
                    "type": "other",
                    "base_info": data,
                    "text": {
                        "content": "该视频时长超出20min暂不支持提取",
                        "role": "assistant"
                    }
                }
                return result
            if tos_utlis.check_file_in_tos(f"assets/{data.get('video_id')}/{data.get('video_id')}.mp4"):
                recognizer = asr_utils.SpeechRecognizer()
                ai_reply = recognizer.recognize_audio(
                    f"https://douchacha-web.tos-cn-beijing.volces.com/assets/{data.get('video_id')}/{data.get('video_id')}.mp4")
                result = {
                    "platform": "dy",
                    "type": "video",
                    "base_info": data,
                    "text": {
                        "content": ai_reply,
                        "role": "assistant"
                    }
                }
                tos_utlis.put_string_to_tos(
                    f"assets/{data.get('video_id')}/{data.get('video_id')}.json",
                    result)
                return result
            else:
                result = {
                    "platform": "dy",
                    "type": "video",
                    "base_info": data,
                    "text": {
                        "content": "视频提取失败请稍后重试",
                        "role": "assistant"
                    }
                }
            return result


############################################################
# 小红书
@register_processor("xhs", "video")
def process_xhs_video(url: str, data: Dict):
    data = spider_api.get_xhs_info(url)
    if not data:
        result = {
            "platform": "xhs",
            "type": "other",
            "base_info": url,
            "text": {
                "content": "链接有误",
                "role": "assistant"
            }
        }
        return result
    if tos_utlis.check_file_in_tos(
            f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.json"):
        return tos_utlis.get_string_from_tos(
            f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.json")
    else:
        if data.get('type') == 'video':
            if data.get("duration") / 1000 / 60 > 20:
                result = {
                    "platform": "xhs",
                    "type": "other",
                    "base_info": data,
                    "text": {
                        "content": "该视频时长超出20min暂不支持提取",
                        "role": "assistant"
                    }
                }
                return result
            if tos_utlis.check_file_in_tos(
                    f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.mp4"):
                recognizer = asr_utils.SpeechRecognizer()
                ai_reply = recognizer.recognize_audio(
                    f"https://douchacha-web.tos-cn-beijing.volces.com/xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.mp4")
                result = {
                    "platform": "xhs",
                    "type": "video",
                    "base_info": data,
                    "text": {
                        "content": ai_reply,
                        "role": "assistant"
                    }
                }
                tos_utlis.put_string_to_tos(
                    f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.json",
                    result)
                return result

            else:
                result = {
                    "platform": "xhs",
                    "type": "video",
                    "base_info": data,
                    "text": {
                        "content": "视频提取失败请稍后重试",
                        "role": "assistant"
                    }
                }
                return result
        else:
            url_list = []
            for i in range(data.get('image_length')):
                if tos_utlis.check_file_in_tos(f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{i}.jpg"):
                    url_list.append({
                        "type": "image_url",
                        "image_url": {
                            "url": f"https://douchacha-web.tos-cn-beijing.volces.com/xhs/{data.get('note_id')}_{data.get('xsec_token')}/{i}.jpg"}
                    })
                else:
                    result = {
                        "platform": "xhs",
                        "type": "image",
                        "base_info": data,
                        "text": {
                            "content": "图片提取失败请稍后重试",
                            "role": "assistant"
                        }
                    }

                    return result

            url_list.append({"type": "text", "text": "提取图片中的文字仅返回图中文字"})
            ai_reply, total_tokens = ai_utils.get_image_to_text(url_list)
            result = {
                "platform": "xhs",
                "type": "image",
                "base_info": data,
                "text": ai_reply
            }
            tos_utlis.put_string_to_tos(
                f"xhs/{data.get('note_id')}_{data.get('xsec_token')}/{data.get('note_id')}_{data.get('xsec_token')}.json",
                result)
            return result


############################################################
"""
快手
"""
@register_processor("ks", "video")
def process_ks_video(url: str, data: Dict):
    data = spider_api.get_ks_info(url)
    if not data:
        result = {
            "platform": "ks",
            "type": "other",
            "base_info": url,
            "text": {
                "content": "链接有误",
                "role": "assistant"
            }
        }
        return result

    if tos_utlis.check_file_in_tos(
            f"ks/{data.get('video_id')}/{data.get('video_id')}.json"):
        return tos_utlis.get_string_from_tos(
            f"ks/{data.get('video_id')}/{data.get('video_id')}.json")
    if data.get("duration") / 1000 / 60 > 20:
        result = {
            "platform": "ks",
            "type": "other",
            "base_info": data,
            "text": {
                "content": "该视频时长超出20min暂不支持提取",
                "role": "assistant"
            }
        }
        return result

    if tos_utlis.check_file_in_tos(f"ks/{data.get('video_id')}/{data.get('video_id')}.mp4"):
        recognizer = asr_utils.SpeechRecognizer()
        ai_reply = recognizer.recognize_audio(
            f"https://douchacha-web.tos-cn-beijing.volces.com/ks/{data.get('video_id')}/{data.get('video_id')}.mp4")
        result = {
            "platform": "ks",
            "type": "video",
            "base_info": data,
            "text": {
                "content": ai_reply,
                "role": "assistant"
            }
        }
        tos_utlis.put_string_to_tos(
            f"ks/{data.get('video_id')}/{data.get('video_id')}.json",
            result)
        return result

    else:
        result = {
            "platform": "ks",
            "type": "video",
            "base_info": data,
            "text": {
                "content": "视频下载失败请稍后重试",
                "role": "assistant"
            }
        }
        return result


############################################################
# b站
@register_processor("bili", "video")
def process_bzhan_video(url: str, data: Dict):
    data = spider_api.get_bilibili_info(url)
    if not data:
        result = {
            "platform": "bili",
            "type": "other",
            "base_info": url,
            "text": {
                "content": "链接有误",
                "role": "assistant"
            }
        }
        return result

    if tos_utlis.check_file_in_tos(
            f"bilibili/{data.get('bvid')}/{data.get('bvid')}.json"):
        return tos_utlis.get_string_from_tos(
            f"bilibili/{data.get('bvid')}/{data.get('bvid')}.json")
    if data.get("duration") / 60 > 50:
        result = {
            "platform": "bili",
            "type": "other",
            "base_info": data,
            "text": {
                "content": "该视频时长超出20min暂不支持提取",
                "role": "assistant"
            }
        }
        return result

    if tos_utlis.check_file_in_tos(f"bilibili/{data.get('bvid')}/{data.get('bvid')}.mp3"):
        recognizer = asr_utils.SpeechRecognizer()
        ai_reply = recognizer.recognize_audio(
            f"https://douchacha-web.tos-cn-beijing.volces.com/bilibili/{data.get('bvid')}/{data.get('bvid')}.mp3")
        result = {
            "platform": "bili",
            "type": "video",
            "base_info": data,
            "text": {
                "content": ai_reply,
                "role": "assistant"
            }
        }
        tos_utlis.put_string_to_tos(
            f"bilibili/{data.get('bvid')}/{data.get('bvid')}.json",
            result)
        return result
    else:
        result = {
            "platform": "bili",
            "type": "video",
            "base_info": data,
            "text": {
                "content": "视频下载失败请稍后重试",
                "role": "assistant"
            }
        }
    return result


############################################################


def process_urls(urls: List[str]):
    results = []
    for url in urls:
        parsed_data = parse_url(url)
        platform = parsed_data["platform"]
        content_type = parsed_data["type"]

        platform_processors = PROCESSOR_REGISTRY.get(platform, {})
        processor = platform_processors.get(content_type)

        if processor:
            result = processor(url, parsed_data)
            results.append(result)
        else:
            results.append(f"无法处理的链接: {url}")
    return results


def extract_mp4_to_text(text: str):
    # url提取
    url_pattern = re.compile(r'https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]')
    urls = url_pattern.findall(text)
    # 汉字提取
    chinese_pattern = re.compile(r'[\u4e00-\u9fa5]+')
    chinese_chars = chinese_pattern.findall(text)
    data = process_urls(urls)

    return data
    # return urls


def convert_dialog_format(original_dialog: list) -> list:
    converted = []
    for item in original_dialog:

        if 'user' in item:
            converted.append({
                'role': 'user',
                'content': item['user']
            })
        elif 'assistant' in item:
            converted.append({
                'role': 'assistant',
                'content': item['assistant']
            })
        else:
            continue
    return converted


# 获取最新用户
def get_last_user_value(dialogs: list) -> str or None:
    last_user_content = None
    for item in dialogs:
        if 'user' in item:
            last_user_content = item['user']

    if last_user_content is not None:
        return [{'role': 'user', 'content': last_user_content}]
    return None


def transform_image_urls(url_list: List[str]) -> List[Dict]:
    return [
        {
            "type": "image_url",
            "image_url": {"url": url}
        }
        for url in url_list
    ]
