import re, sys, json, base64,requests
from Crypto.Cipher import AES
from urllib.parse import urljoin
from Crypto.Util.Padding import unpad
from base.spider import Spider
sys.path.append('..')

class Spider(Spider):
    headers = {'User-Agent': 'okhttp/4.12.0'}
    FIXED_CONFIG = {
        'host': 'https://appp.lyyytv.cn',
        'cmskey': '',
        'RawPlayUrl': 0
    }
    def init(self, extend=''):
        self.host = self.FIXED_CONFIG['host']
        self.cmskey = self.FIXED_CONFIG.get('cmskey', '')
        raw_play_url = self.FIXED_CONFIG.get('RawPlayUrl', 0)
        if raw_play_url == 1:
            self.raw_play_url = 1
        else:
            self.raw_play_url = 0

    def homeVideoContent(self):
        data = self.fetch(f"{self.host}/api.php/app/index_video?token=", headers=self.headers,verify=False).json()
        videos = []
        for item in data['list']:
            videos.extend(item['vlist'])
        return {'list': videos}

    def homeContent(self, filter):
        data = self.fetch(f"{self.host}/api.php/app/nav?token=", headers=self.headers,verify=False).json()
        keys = ["class", "area", "lang", "year", "letter", "by", "sort"]
        filters = {}
        classes = []
        for item in data['list']:
            has_non_empty_field = False
            jsontype_extend = item["type_extend"]
            classes.append({"type_name": item["type_name"], "type_id": item["type_id"]})
            for key in keys:
                if key in jsontype_extend and jsontype_extend[key].strip() != "":
                    has_non_empty_field = True
                    break
            if has_non_empty_field:
                filters[str(item["type_id"])] = []
            for dkey in jsontype_extend:
                if dkey in keys and jsontype_extend[dkey].strip() != "":
                    values = jsontype_extend[dkey].split(",")
                    value_array = []
                    for value in values:
                        if value.strip() != "":
                            value_array.append({"n": value.strip(), "v": value.strip()})
                    filters[str(item["type_id"])].append({"key": dkey, "name": dkey, "value": value_array})
        return {"class": classes, "filters": filters}

    def categoryContent(self, tid, pg, filter, extend):
        query_params = [
            f"tid={tid}",
            f"pg={pg}",
            f"limit=18"
        ]
        if extend.get('class'):
            query_params.append(f"class={extend.get('class')}")
        if extend.get('area'):
            query_params.append(f"area={extend.get('area')}")
        if extend.get('lang'):
            query_params.append(f"lang={extend.get('lang')}")
        if extend.get('year'):
            query_params.append(f"year={extend.get('year')}")
        url = f"{self.host}/api.php/app/video?" + "&".join(query_params)
        data = self.fetch(url, headers=self.headers,verify=False).json()
        return data

    def searchContent(self, key, quick, pg="1"):
        data = self.fetch(f"{self.host}/api.php/app/search?text={key}&pg={pg}", headers=self.headers,verify=False).json()
        videos = data['list']
        for item in data['list']:
            item.pop('type', None)
        return {'list': videos, 'page': pg}

    def detailContent(self, ids):
        data = self.fetch(f"{self.host}/api.php/app/video_detail?id={ids[0]}", headers=self.headers,verify=False).json()['data']
        show, paly_urls = [], []
        for i in data['vod_url_with_player']:
            urls = i['url'].split('#')
            urls2 = []
            for j in urls:
                if j:
                    url = j.split('$', 1)
                    urls2.append(f"{url[0]}${self.lvdou(url[1])}")
            paly_urls.append('#'.join(urls2))
            name_str = i['name'].strip()
            code_str = i.get('code', '').strip()
            if '(' in code_str:
                show.append(f"{name_str}{code_str}")
            else:
                show.append(f"{name_str}({code_str})")
        data.pop('vod_url_with_player')
        data['vod_play_from'] = '$$$'.join(show)
        data['vod_play_url'] = '$$$'.join(paly_urls)
        return {'list': [data]}

    def playerContent(self, flag, video_id, vipFlags):
        jx = 0
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}
        video_id = re.sub(r'%[0-9A-Fa-f]{2}', '', video_id)
        # 定义两个解析接口
        parse_api = f"http://61.184.23.217:6163/api/index?parsesId=4&appid=10002&videoUrl={video_id}"
        backup_api = f"https://mk1080p.top/zzbh.php?url={video_id}"
        real_play_url = ""
        play_headers = headers.copy()
        if "bilibili.com" in video_id:
            play_headers["Referer"] = "https://www.bilibili.com"
        if "mgtv.com" in video_id:
            play_headers["User-Agent"] = "ImgoMediaPlayerLib/com.hunantv.imgo.samsung.V7.0.1_121 mediacodecNative/0/5.1.2_2.22011902.20240927/imgofflib"
        # 1. 优先尝试使用backup_api接口
        try:
            backup_raw = self.fetch(backup_api, headers=self.headers, timeout=4).text
            json_blocks = re.findall(r'\{.*?\}', backup_raw, re.S)
            backup_data = None
            for block in json_blocks:
                try:
                    tmp = json.loads(block)
                    if tmp.get("type") == "轮询":
                        continue
                    if tmp.get("url"):
                        backup_data = tmp
                        break
                except json.JSONDecodeError:
                    continue
            real_play_url = backup_data.get("url", "") if backup_data else ""
        except Exception:
            pass
        # 2. 如果backup_api接口解析失败 (real_play_url 为空)，则回退到parse_api接口
        if not real_play_url:
            try:
                resp = self.fetch(parse_api, headers=self.headers, timeout=3).json()
                dat_vurl = resp.get("url", "")
                if dat_vurl:
                    step1 = base64.b64decode(dat_vurl).decode('utf-8')
                    step2 = step1.replace("https://ldmax.cooom/", "")
                    key_iv = step2[:16][::-1].encode('utf-8')
                    cipher = AES.new(key_iv, AES.MODE_CBC, key_iv)
                    dec_data = base64.b64decode(step2[16:])
                    dec_bytes = cipher.decrypt(dec_data)
                    real_play_url = unpad(dec_bytes, AES.block_size).decode('utf-8')
            except Exception:
                # 两个接口都失败，则直接返回原始 video_id并调用外置解析
                jx = 1
                real_play_url = video_id
        return {
            'jx': jx,
            'parse': 0,
            'url': real_play_url,
            'header': play_headers
        }
    def lvdou(self, text):
        key = self.cmskey[:16].encode("utf-8")
        iv = self.cmskey[-16:].encode("utf-8")
        original_text = text
        url_prefix = "lvdou+"
        if original_text.startswith(url_prefix):
            ciphertext_b64 = original_text[len(url_prefix):]
            try:
                cipher = AES.new(key, AES.MODE_CBC, iv)
                ct_bytes = base64.b64decode(ciphertext_b64)
                pt_bytes = cipher.decrypt(ct_bytes)
                return unpad(pt_bytes, AES.block_size).decode('utf-8')
            except Exception:
                return original_text
        else:
            return original_text

    def raw_url(self, original_url):
        try:
            response = self.fetch(original_url, allow_redirects=False, stream=True, timeout=20)
            if 300 <= response.status_code < 400:
                redirect_location = response.headers.get('Location')
                if redirect_location:
                    real_url = urljoin(original_url, redirect_location)
                    return real_url
            return original_url
        except Exception:
            return original_url

    def check_paly_url(self, content):
        pattern = r"https?://.*(?:\.(?:mp4|m3u8|flv|avi|mkv|ts|mov|wmv|webm)|lyyytv\.cn/)"
        return bool(re.search(pattern, content, re.IGNORECASE))

    def getName(self):
        pass

    def localProxy(self, param):
        pass

    def isVideoFormat(self, url):
        pass

    def manualVideoCheck(self):
        pass

    def destroy(self):
        pass
