import re
import time
import html
import subprocess
import json
import urllib.parse


UA = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/117.0.0.0 Safari/537.36"
)

OKHTTP_UA = "okhttp/5.0.0-alpha.6"

MP4PLUS_UA = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/70.0.3538.77 Safari/537.36"
)


MEDIA_RE = re.compile(
    r'https?://[^"\'>\s]+?'
    r'(?:m3u8|mp4|mpd|master\.txt|\.txt)'
    r'(?:[^"\'>\s]*)?',
    re.I
)

STREAMWISH_FILE_RE = re.compile(
    r'''file\s*:\s*["']([^"']+)["']''',
    re.I
)

MP4PLUS_FILE_RE = re.compile(
    r'''(?:file|source|src)\s*[:=]\s*["']([^"']+)["']''',
    re.I
)

MP4PLUS_SOURCES_RE = re.compile(
    r'''["'](?:file|src|source)["']\s*:\s*["']([^"']+)["']''',
    re.I
)


BAD_DOMAINS = [
    "scdns.io",
]

TURKI_DOMAINS = [
    "mwdy.cc",
    "vidspeed.org",
    "vidoba.org",
]

VIDTUBE_DOMAINS = [
    "vidtube.",
    "vidtube.one",
    "vidtube.cam",
]

ALVID_DOMAINS = [
    "liiivideo.com",
    "vipserver.liiivideo.com",
]

MP4PLUS_DOMAINS = [
    "mp4plus.org",
]


def clean_url(u):
    return html.unescape(
        str(u or "").replace("\\/", "/")
    ).strip()


def bad_url(u):
    low = clean_url(u).lower()

    return any(
        domain in low
        for domain in BAD_DOMAINS
    )


def detect_type(u):
    u = clean_url(u).lower()

    path = urllib.parse.urlsplit(u).path.lower()

    if (
        path.endswith(".m3u8")
        or ".m3u8?" in u
        or path.endswith(".txt")
        or "master.txt" in u
    ):
        return "m3u8"

    if (
        path.endswith(".mpd")
        or ".mpd?" in u
    ):
        return "mpd"

    if (
        path.endswith(".mp4")
        or ".mp4?" in u
    ):
        return "mp4"

    return "unknown"


def extract_urls(text):
    text = html.unescape(
        str(text or "")
    ).replace("\\/", "/")

    out = []

    for match in MEDIA_RE.findall(text):
        link = clean_url(match)

        if (
            link.startswith("http")
            and not bad_url(link)
        ):
            out.append(link)

    return list(dict.fromkeys(out))


def normalize_api_response(body):
    try:
        data = json.loads(body)

        return json.dumps(
            data,
            ensure_ascii=False
        )

    except Exception:
        return body or ""


def curl_get(
    url,
    ua=UA,
    timeout=30,
    referer="",
    extra_headers=None
):
    cmd = [
        "curl",
        "-sS",
        "-L",
        "--compressed",
        "--retry", "3",
        "--retry-delay", "1",
        "--connect-timeout", "10",
        "--max-time", str(timeout),
        "-H", f"User-Agent: {ua}",
        "-H", "Accept: */*",
        "-H", "Accept-Encoding: gzip, deflate, br",
    ]

    if referer:
        cmd.extend([
            "-H", f"Referer: {referer}"
        ])

    if extra_headers:
        for key, value in extra_headers.items():
            cmd.extend([
                "-H", f"{key}: {value}"
            ])

    cmd.append(url)

    return subprocess.check_output(
        cmd,
        timeout=timeout + 5,
        stderr=subprocess.DEVNULL
    ).decode(
        "utf-8",
        "ignore"
    )


def curl_post_form(
    url,
    data,
    ua=OKHTTP_UA,
    timeout=30,
    referer=""
):
    post_data = urllib.parse.urlencode(data)

    cmd = [
        "curl",
        "-sS",
        "-L",
        "--compressed",
        "--retry", "3",
        "--retry-delay", "1",
        "--connect-timeout", "10",
        "--max-time", str(timeout),
        "-X", "POST",
        "-H", f"User-Agent: {ua}",
        "-H",
        "Content-Type: application/x-www-form-urlencoded",
    ]

    if referer:
        cmd.extend([
            "-H", f"Referer: {referer}"
        ])

    cmd.extend([
        "--data", post_data,
        url
    ])

    return subprocess.check_output(
        cmd,
        timeout=timeout + 5,
        stderr=subprocess.DEVNULL
    ).decode(
        "utf-8",
        "ignore"
    )


def score_link(link):
    link_type = detect_type(link)
    low = link.lower()

    score = 0

    if link_type == "m3u8":
        score += 120

    elif link_type == "mpd":
        score += 90

    elif link_type == "mp4":
        score += 80

    if "master" in low:
        score += 20

    if "1080" in low:
        score += 15

    if "720" in low:
        score += 10

    if "480" in low:
        score += 5

    if "playlist" in low:
        score += 10

    if "index" in low:
        score += 5

    return score


def extract_egybest(url):
    try:
        page_html = curl_get(
            url,
            UA,
            30,
            referer=url
        )

        if not page_html:
            return ""

        body = curl_post_form(
            "https://hrrejhp.com/"
            "scrapeamine/scriptEgybest.php",
            {
                "content": page_html,
                "url": url
            },
            OKHTTP_UA,
            30,
            referer=url
        )

        return normalize_api_response(body)

    except Exception:
        return ""


def extract_vidtube(url):
    try:
        page_html = curl_get(
            url,
            UA,
            30,
            referer=url
        )

        if not page_html:
            return ""

        body = curl_post_form(
            "https://hrrejhp.com/"
            "scrapefinal/vidtubepost.php",
            {
                "content": page_html,
                "url": url
            },
            OKHTTP_UA,
            30,
            referer=url
        )

        return normalize_api_response(body)

    except Exception:
        return ""


def extract_streamwish(url):
    """
    يرسل رابط StreamWish إلى API:

    https://hrrejhp.com/scrapefinal/
    streamwish.php?api=...

    والرد قد يكون مثل:

    file:"https://domain/.../master.txt"
    """

    try:
        encoded_url = urllib.parse.quote(
            url,
            safe=""
        )

        api_url = (
            "https://hrrejhp.com/"
            "scrapefinal/streamwish.php?api="
            + encoded_url
        )

        body = curl_get(
            api_url,
            OKHTTP_UA,
            30,
            referer=url
        )

        if not body:
            return ""

        body = html.unescape(
            body
        ).replace(
            "\\/",
            "/"
        ).strip()

        match = STREAMWISH_FILE_RE.search(body)

        if match:
            final_url = clean_url(
                match.group(1)
            )

            if (
                final_url.startswith("http")
                and not bad_url(final_url)
            ):
                return final_url

        links = extract_urls(body)

        if links:
            links.sort(
                key=score_link,
                reverse=True
            )

            return links[0]

        return normalize_api_response(body)

    except Exception:
        return ""


def extract_mp4plus(url):
    """
    استخراج رابط الفيديو من mp4plus.org.

    يستخدم نفس User-Agent وReferer الخاصين
    بطلب صفحة المشغل.
    """

    try:
        page_html = curl_get(
            url=url,
            ua=MP4PLUS_UA,
            timeout=30,
            referer=url,
            extra_headers={
                "Origin": "https://mp4plus.org",
                "Sec-Fetch-Dest": "iframe",
                "Sec-Fetch-Mode": "navigate",
                "Sec-Fetch-Site": "same-origin",
                "Upgrade-Insecure-Requests": "1",
            }
        )

        if not page_html:
            return ""

        page_html = html.unescape(
            page_html
        ).replace(
            "\\/",
            "/"
        )

        found = []

        # file: "https://..."
        for match in MP4PLUS_FILE_RE.findall(
            page_html
        ):
            link = clean_url(match)

            if (
                link.startswith("http")
                and not bad_url(link)
                and detect_type(link) != "unknown"
            ):
                found.append(link)

        # {"file":"https://..."}
        for match in MP4PLUS_SOURCES_RE.findall(
            page_html
        ):
            link = clean_url(match)

            if (
                link.startswith("http")
                and not bad_url(link)
                and detect_type(link) != "unknown"
            ):
                found.append(link)

        # بحث عام عن روابط الفيديو
        found.extend(
            extract_urls(page_html)
        )

        # إزالة التكرار
        unique = []

        for link in found:
            link = clean_url(link)

            if (
                not link
                or bad_url(link)
                or detect_type(link) == "unknown"
            ):
                continue

            if link not in unique:
                unique.append(link)

        unique.sort(
            key=score_link,
            reverse=True
        )

        if unique:
            return "\n".join(unique)

        # في حال كان داخل الصفحة JSON أو كود مختلف
        return normalize_api_response(
            page_html
        )

    except Exception:
        return ""


def api_target(url):
    low = url.lower()
    encoded_url = urllib.parse.quote(
        url,
        safe=""
    )

    if "fasel-hd.com" in low:
        return (
            "https://hrrejhp.com/"
            "scripttestfasel.php?api="
            + encoded_url
        )

    if "streamwish." in low:
        return (
            "https://hrrejhp.com/"
            "scrapefinal/streamwish.php?api="
            + encoded_url
        )

    if "updown." in low:
        return (
            "https://hrrejhp.com/"
            "scrapefinal/updown.php?api="
            + encoded_url
        )

    if "uqload." in low:
        return (
            "https://hrrejhp.com/"
            "scrapefinal/uqload.php?api="
            + encoded_url
        )

    if any(
        domain in low
        for domain in TURKI_DOMAINS
    ):
        return (
            "https://hrrejhp.com/"
            "scrapefinal/turki.php?api="
            + encoded_url
        )

    if any(
        domain in low
        for domain in ALVID_DOMAINS
    ):
        return (
            "https://hrrejhp.com/"
            "scrapefinal/scriptalvid.php?api="
            + encoded_url
        )

    return url


def extract(url):
    start = time.time()
    found = []

    try:
        url = clean_url(url)

        if not url or bad_url(url):
            return {
                "ok": False,
                "page": url,
                "error": "bad or empty url",
                "count": 0,
                "best": None,
                "results": [],
                "networkCount": 0,
                "time": round(
                    time.time() - start,
                    2
                )
            }

        low = url.lower()
        bodies = []

        # الروابط المباشرة
        if (
            ".m3u8" in low
            or ".mp4" in low
            or ".mpd" in low
            or low.endswith(".txt")
            or "master.txt" in low
        ):
            bodies.append(url)

        # MP4Plus
        elif any(
            domain in low
            for domain in MP4PLUS_DOMAINS
        ):
            body = extract_mp4plus(url)

            if body:
                bodies.append(body)

        # EgyBest
        elif "egybestvid." in low:
            body = extract_egybest(url)

            if body:
                bodies.append(body)

        # VidTube
        elif any(
            domain in low
            for domain in VIDTUBE_DOMAINS
        ):
            body = extract_vidtube(url)

            if body:
                bodies.append(body)

        # StreamWish
        elif "streamwish." in low:
            body = extract_streamwish(url)

            if body:
                bodies.append(body)

        # باقي المصادر
        else:
            target_url = api_target(url)

            if (
                "hrrejhp.com/"
                "scrapefinal/turki.php"
                in target_url
            ):
                body = curl_get(
                    target_url,
                    OKHTTP_UA,
                    30,
                    referer=url
                )

            elif (
                "hrrejhp.com/"
                "scrapefinal/streamwish.php"
                in target_url
            ):
                body = curl_get(
                    target_url,
                    OKHTTP_UA,
                    30,
                    referer=url
                )

            else:
                body = curl_get(
                    target_url,
                    UA,
                    30,
                    referer=url
                )

            bodies.append(
                normalize_api_response(body)
            )

        for body in bodies:
            body = clean_url(body)

            # إذا كانت الدالة أعادت رابطًا مباشرًا واحدًا
            if (
                body.startswith("http")
                and "\n" not in body
                and detect_type(body) != "unknown"
            ):
                links = [body]

            else:
                links = extract_urls(body)

                # دعم عدة روابط كل رابط في سطر
                for line in body.splitlines():
                    line = clean_url(line)

                    if (
                        line.startswith("http")
                        and detect_type(line) != "unknown"
                    ):
                        links.append(line)

                links = list(
                    dict.fromkeys(links)
                )

            for link in links:
                link = clean_url(link)

                if not link or bad_url(link):
                    continue

                link_type = detect_type(link)

                if link_type == "unknown":
                    continue

                score = score_link(link)

                found.append({
                    "url": link,
                    "type": link_type,
                    "source": (
                        "mp4plus-curl"
                        if any(
                            domain in low
                            for domain in MP4PLUS_DOMAINS
                        )
                        else "api-curl"
                    ),
                    "contentType": "",
                    "status": 200,
                    "score": score,
                    "referer": (
                        url
                        if any(
                            domain in low
                            for domain in MP4PLUS_DOMAINS
                        )
                        else ""
                    ),
                    "useragent": (
                        MP4PLUS_UA
                        if any(
                            domain in low
                            for domain in MP4PLUS_DOMAINS
                        )
                        else UA
                    )
                })

        unique = {}

        for item in found:
            link = item["url"]

            if link not in unique:
                unique[link] = item

            elif (
                item["score"]
                > unique[link]["score"]
            ):
                unique[link] = item

        found = sorted(
            unique.values(),
            key=lambda item: item["score"],
            reverse=True
        )

        return {
            "ok": bool(found),
            "page": url,
            "title": "",
            "count": len(found),
            "best": (
                found[0]
                if found
                else None
            ),
            "results": found,
            "networkCount": 0,
            "time": round(
                time.time() - start,
                2
            )
        }

    except Exception as exc:
        return {
            "ok": False,
            "page": url,
            "error": str(exc),
            "count": 0,
            "best": None,
            "results": [],
            "networkCount": 0,
            "time": round(
                time.time() - start,
                2
            )
        }


if __name__ == "__main__":
    import sys

    test_url = (
        sys.argv[1]
        if len(sys.argv) > 1
        else (
            "https://mp4plus.org/"
            "embed-fnayiwmnh5ta.html"
        )
    )

    result = extract(test_url)

    print(
        json.dumps(
            result,
            ensure_ascii=False,
            indent=2
        )
    )