# coding=utf-8
# //@name:红果AI短剧
# //@version:1
try:
    from base.spider import Spider as BaseSpider
except Exception:
    class BaseSpider:
        def getName(self): return ""
        def init(self, extend=""): pass
        def homeContent(self, filter=None): return {}
        def homeVideoContent(self): return {}
        def categoryContent(self, tid, pg, filter=None, extend=None): return {}
        def detailContent(self, ids): return {}
        def searchContent(self, key, quick=False, pg="1"): return {}
        def playerContent(self, flag, id, vipFlags=None): return {}
        def localProxy(self, param): return [404, "text/plain", ""]
        def getDependence(self): return ""
        def isVideoFormat(self, url): return False
        def manualVideoCheck(self): return False

import re, time, json, gzip, ssl, http.cookiejar, urllib.request
from urllib.parse import quote, unquote, urljoin, urlparse

SKIP_TYPE = {"55"}
SKIP_KEYS = ("萝莉", "幼女", "小学生", "儿童", "未成年", "幼幼", "初中", "小孩", "女童")

class Spider(BaseSpider):
    def getName(self):
        return "红果AI短剧"

    def init(self, extend=""):
        self.host = "https://123456.hoguo.sbs"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Mobile Safari/537.36",
            "Referer": self.host + "/",
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Accept-Encoding": "gzip, deflate",
        }
        self._ctx = ssl._create_unverified_context()
        self._opener = urllib.request.build_opener(
            urllib.request.HTTPSHandler(context=self._ctx),
            urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()),
        )

    def getDependence(self):
        return ""

    def _req(self, path, retry=3):
        url = path if str(path).startswith("http") else (self.host + str(path))
        for i in range(retry):
            try:
                req = urllib.request.Request(url, headers=self.headers)
                with self._opener.open(req, timeout=18) as resp:
                    raw = resp.read()
                    if len(raw) >= 2 and raw[0] == 0x1F and raw[1] == 0x8B:
                        try: raw = gzip.decompress(raw)
                        except Exception: pass
                    return raw.decode("utf-8", "ignore")
            except Exception:
                time.sleep(0.25 * (i + 1))
        return ""

    def _bad(self, name):
        return any(k in (name or "") for k in SKIP_KEYS)

    def _unescape(self, s):
        try:
            import html as H
            return H.unescape(s or "")
        except Exception:
            return s or ""

    def homeContent(self, filter=None):
        html = self._req("/")
        classes, seen = [], set()
        for m in re.finditer(r'href="/index\.php/vod/type/id/(\d+)\.html"[^>]*>([^<]+)<', html or ""):
            tid, name = m.group(1), m.group(2).strip()
            if tid in seen or tid in SKIP_TYPE or self._bad(name):
                continue
            seen.add(tid)
            classes.append({"type_id": tid, "type_name": name})
        return {"class": classes, "filters": {}}

    def homeVideoContent(self):
        return {"list": self._parse_list(self._req("/") or "")}

    def categoryContent(self, tid, pg, filter=None, extend=None):
        page = int(pg) if str(pg).isdigit() else 1
        tid = str(tid)
        if tid in SKIP_TYPE:
            return {"page": 1, "pagecount": 1, "limit": 0, "total": 0, "list": []}
        path = "/index.php/vod/type/id/{}.html".format(tid) if page <= 1 else "/index.php/vod/type/id/{}/page/{}.html".format(tid, page)
        html = self._req(path)
        videos = self._parse_list(html or "")
        pages = [int(x) for x in re.findall(r"/page/(\d+)", html or "") if str(x).isdigit()]
        pagecount = max(pages) if pages else (page + 1 if len(videos) >= 20 else page)
        return {"page": page, "pagecount": max(pagecount, page), "limit": 30, "total": max(pagecount, page) * 30, "list": videos}

    def _parse_list(self, html):
        videos, seen = [], set()
        for m in re.finditer(r'detail/id/(\d+)\.html"><img src="(https?://[^"]+)" alt="([^"]*)"', html or ""):
            vid, pic, name = m.group(1), m.group(2), self._unescape(m.group(3)).strip()
            if vid in seen or self._bad(name):
                continue
            seen.add(vid)
            videos.append({"vod_id": vid, "vod_name": name or vid, "vod_pic": pic, "vod_remarks": ""})
        if videos:
            return videos
        for m in re.finditer(r'href="/index\.php/vod/detail/id/(\d+)\.html"[^>]*title="([^"]+)"[\s\S]{0,250}?src="(https?://[^"]+)"', html or ""):
            vid, name, pic = m.group(1), self._unescape(m.group(2)).strip(), m.group(3)
            if vid in seen or self._bad(name):
                continue
            seen.add(vid)
            videos.append({"vod_id": vid, "vod_name": name, "vod_pic": pic, "vod_remarks": ""})
        return videos

    def detailContent(self, ids):
        if not ids:
            return {"list": []}
        vid = str(ids[0] if isinstance(ids, (list, tuple)) else ids)
        m = re.search(r"(\d+)", vid)
        if m: vid = m.group(1)
        html = self._req("/index.php/vod/detail/id/{}.html".format(vid))
        name = ""
        h1 = re.search(r"<h1[^>]*>([\s\S]*?)</h1>", html or "")
        if h1:
            name = re.sub(r"<[^>]+>", "", h1.group(1)).strip()
        if not name:
            tm = re.search(r"<title>([^<]+)</title>", html or "")
            if tm:
                name = self._unescape(tm.group(1))
                mm = re.search(r"《([^》]+)》", name)
                name = mm.group(1) if mm else re.sub(r"\s*-\s*.*$", "", name).strip()
        if self._bad(name):
            return {"list": []}
        pic = ""
        pm = re.search(r'property="og:image"\s+content="([^"]+)"', html or "")
        if pm: pic = pm.group(1)
        if not pic:
            pm = re.search(r'<img[^>]+src="(https?://[^"]+)"', html or "")
            if pm: pic = pm.group(1)
        desc = name
        links = re.findall(r'href="(/index\.php/vod/play/id/{}/sid/(\d+)/nid/(\d+)\.html)"[^>]*>([\s\S]*?)</a>'.format(vid), html or "")
        by_sid = {}
        for href, sid, nid, title in links:
            title = re.sub(r"<[^>]+>", "", title).strip() or "第{}集".format(nid)
            by_sid.setdefault(sid, []).append((nid, title))
        if not by_sid:
            by_sid = {"1": [("1", "正片")]}
        froms, urls = [], []
        for sid, eps in by_sid.items():
            froms.append("线路{}".format(sid))
            urls.append("#".join("{}${}/sid/{}/nid/{}".format(t, vid, sid, n) for n, t in eps))
        return {"list": [{"vod_id": vid, "vod_name": name or vid, "vod_pic": pic, "vod_content": desc,
                          "vod_play_from": "$$$".join(froms), "vod_play_url": "$$$".join(urls)}]}

    def searchContent(self, key, quick=False, pg="1"):
        if self._bad(key):
            return {"list": [], "page": 1, "pagecount": 1, "limit": 0, "total": 0}
        page = int(pg) if str(pg).isdigit() else 1
        path = "/index.php/vod/search/wd/{}.html".format(quote(key)) if page <= 1 else "/index.php/vod/search/wd/{}/page/{}.html".format(quote(key), page)
        html = self._req(path)
        videos = self._parse_list(html or "")
        pages = [int(x) for x in re.findall(r"/page/(\d+)", html or "") if str(x).isdigit()]
        pagecount = max(pages) if pages else (page + 1 if len(videos) >= 20 else page)
        return {"list": videos, "page": page, "pagecount": pagecount, "limit": 30, "total": pagecount * 30}

    def playerContent(self, flag, id, vipFlags=None):
        header = {"User-Agent": self.headers["User-Agent"], "Referer": self.host + "/"}
        raw = str(id or "").strip()
        if raw.startswith("http"):
            return {"parse": 0, "jx": 0, "url": raw, "header": header}
        vid, sid, nid = raw, "1", "1"
        m = re.match(r"(\d+)(?:/sid/(\d+)/nid/(\d+))?", raw)
        if m:
            vid, sid, nid = m.group(1), m.group(2) or "1", m.group(3) or "1"
        html = self._req("/index.php/vod/play/id/{}/sid/{}/nid/{}.html".format(vid, sid, nid))
        play = ""
        sm = re.search(r'<source[^>]+src="(https?://[^"]+\.m3u8[^"]*)"', html or "")
        if sm: play = sm.group(1)
        if not play:
            mm = re.search(r'(https?://[^"\'\\s]+\.m3u8[^"\'\\s]*)', html or "")
            if mm: play = mm.group(1)
        if not play:
            return {"parse": 0, "jx": 0, "url": "", "header": header}
        return {"parse": 0, "jx": 0, "url": play, "header": header}

    def localProxy(self, param):
        try:
            url = param.get("url") if isinstance(param, dict) else ""
            if not url: return [404, "text/plain", ""]
            text = self._req(url)
            if not text: return [502, "text/plain", "fail"]
            if "#EXT-X-STREAM-INF" in text and "#EXTINF" not in text:
                for line in text.splitlines():
                    line = line.strip()
                    if line and not line.startswith("#"):
                        sub = line if line.startswith("http") else urljoin(url, line)
                        text = self._req(sub); url = sub; break
            return [200, "application/vnd.apple.mpegurl", self._clean(text or "", url)]
        except Exception as e:
            return [500, "text/plain", str(e)[:200]]

    def _clean(self, content, base_url=""):
        if not content or "#EXTM3U" not in content: return content
        parsed = urlparse(base_url)
        origin = "{}://{}".format(parsed.scheme, parsed.netloc)
        base_dir = base_url.rsplit("/", 1)[0] + "/"
        out = []
        for line in content.splitlines():
            s = line.strip()
            if not s: continue
            if s.startswith("#"): out.append(s)
            elif s.startswith("http"): out.append(s)
            elif s.startswith("/"): out.append(origin + s)
            else: out.append(urljoin(base_dir, s))
        return "\n".join(out)

    def isVideoFormat(self, url):
        return ".m3u8" in (url or "") or ".mp4" in (url or "")

    def manualVideoCheck(self):
        return False
