import hashlib
import json
import urllib.parse
import time
from playwright.sync_api import sync_playwright
from selenium.webdriver import Chrome, ChromeOptions


def md5(input_string):
    """Generate MD5 hash of input string."""
    def safe_add(x, y):
        lsw = (x & 0xFFFF) + (y & 0xFFFF)
        msw = (x >> 16) + (y >> 16) + (lsw >> 16)
        return (msw << 16) | (lsw & 0xFFFF)

    def bit_rotate_left(num, cnt):
        return (num << cnt) | (num >> (32 - cnt))

    def md5cmn(q, a, b, x, s, t):
        return safe_add(bit_rotate_left(safe_add(safe_add(a, q), safe_add(x, t)), s), b)

    def md5ff(a, b, c, d, x, s, t):
        return md5cmn((b & c) | ((~b) & d), a, b, x, s, t)

    def md5gg(a, b, c, d, x, s, t):
        return md5cmn((b & d) | (c & (~d)), a, b, x, s, t)

    def md5hh(a, b, c, d, x, s, t):
        return md5cmn(b ^ c ^ d, a, b, x, s, t)

    def md5ii(a, b, c, d, x, s, t):
        return md5cmn(c ^ (b | (~d)), a, b, x, s, t)

    def binl_md5(x, len_):
        # Ensure x has enough space for padding and length
        blocks = (((len_ + 64) >> 9) + 1)  # Ceiling division for blocks
        words_needed = blocks * 16  # Each block is 16 words
        if len(x) < words_needed:
            x.extend([0] * (words_needed - len(x)))  # Extend x to required size

        # Add padding
        x[len_ >> 5] |= 0x80 << (len_ % 32)
        x[(((len_ + 64) >> 9) << 4) + 14] = len_

        a = 1732584193
        b = -271733879
        c = -1732584194
        d = 271733878

        for i in range(0, len(x), 16):
            olda, oldb, oldc, oldd = a, b, c, d

            a = md5ff(a, b, c, d, x[i], 7, -680876936)
            d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
            c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
            b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
            a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
            d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
            c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
            b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
            a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
            d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
            c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
            b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
            a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
            d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
            c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
            b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)

            a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
            d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
            c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
            b = md5gg(b, c, d, a, x[i], 20, -373897302)
            a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
            d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
            c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
            b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
            a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
            d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
            c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
            b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
            a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
            d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
            c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
            b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)

            a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
            d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
            c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
            b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
            a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
            d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
            c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
            b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
            a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
            d = md5hh(d, a, b, c, x[i], 11, -358537222)
            c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
            b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
            a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
            d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
            c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
            b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)

            a = md5ii(a, b, c, d, x[i], 6, -198630844)
            d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
            c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
            b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
            a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
            d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
            c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
            b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
            a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
            d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
            c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
            b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
            a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
            d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
            c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
            b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)

            a = safe_add(a, olda)
            b = safe_add(b, oldb)
            c = safe_add(c, oldc)
            d = safe_add(d, oldd)

        return [a, b, c, d]

    def binl2rstr(input_):
        output = ''
        for i in range(0, len(input_) * 32, 8):
            output += chr((input_[i >> 5] >> (i % 32)) & 0xFF)
        return output

    def rstr2binl(input_):
        print("Input is", input_)
        output = [0] * ((len(input_) * 8 + 31) // 32)  # Ceiling division to ensure enough space
        for i in range(0, len(input_) * 8, 8):  # Step by 8 to process each byte
            output[i >> 5] |= (ord(input_[i // 8]) & 0xFF) << (i % 32)
        return output

    def rstr_md5(s):
        return binl2rstr(binl_md5(rstr2binl(s), len(s) * 8))

    def rstr2hex(input_):
        hex_tab = '0123456789abcdef'
        output = ''
        for i in range(len(input_)):
            x = ord(input_[i])
            output += hex_tab[(x >> 4) & 0x0F] + hex_tab[x & 0x0F]
        return output

    def str2rstr_utf8(input_):
        return urllib.parse.unquote(urllib.parse.quote(input_, safe=''))

    def raw_md5(s):
        return rstr_md5(str2rstr_utf8(s))

    def hex_md5(s):
        return rstr2hex(raw_md5(s))

    return hex_md5(input_string)


import requests
from twocaptcha import TwoCaptcha

class AlibabaCaptchaSolver:
    def __init__(self, api_key):
        self.solver = TwoCaptcha(api_key)
    
    def solve_alibaba_captcha(self, site_key, url):
        """
        Solve Alibaba's CAPTCHA using 2Captcha service
        site_key: Usually found in the page source
        url: The page URL where CAPTCHA appears
        """
        try:
            result = self.solver.recaptcha(
                sitekey=site_key,
                url=url
            )
            return result['code']
        except Exception as e:
            print(f"CAPTCHA solving error: {e}")
            return None

# Usage
# solver = AlibabaCaptchaSolver('YOUR_2CAPTCHA_API_KEY')
# token = solver.solve_alibaba_captcha('SITE_KEY', 'PAGE_URL')
def generate_mtop_sign(token, app_key, data, t):
    """Generate MTOP signature."""
    sign_content = f"{token}&{t}&{app_key}&{json.dumps(data)}"
    return md5(sign_content)


def get_driver():
    options = ChromeOptions()
    options.add_argument('--disable-blink-features=AutomationControlled')
    driver = Chrome(options=options)
    return driver

def main():
    # API parameters
    api_name = "mtop.relationrecommend.WirelessRecommend.recommend"
    api_version = "2.0"
    app_key = "12574478"
    data = {
        "appId": 32517,
        "params": "{\"verticalProductFlag\":\"pcmarket\",\"searchScene\":\"pcOfferSearch\",\"charset\":\"GBK\",\"beginPage\":1, \"pageSize\":60,\"keywords\":\"%C6%BB%B9%FB16max\",\"spm\":\"a260k.home2025.searchbox.0\",\"method\":\"getOfferList\"}"
    }

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)  # Set to True for headless mode
        context = browser.new_context()

        # Navigate to 1688.com to capture cookies
        page = context.new_page()
        page.goto("https://www.1688.com", wait_until="domcontentloaded", timeout=40000)

        time.sleep(12)

        # Extract cookies
        cookies = context.cookies()
        token = None
        for cookie in cookies:
            if cookie["name"] == "_m_h5_tk":
                token = cookie["value"].split('_')[0]
                break

        if not token:
            print("Error: Could not find _m_h5_tk cookie")
            browser.close()
            return

        print(f"Extracted token: {token}")

        # Generate timestamp and signature
        t = int(time.time() * 1000)
        print("Time is",t)
        sign = generate_mtop_sign(token, app_key, data, t)

        # Encode data for URL
        encoded_data = urllib.parse.quote(json.dumps(data))

        # Construct the URL
        url = f"https://h5api.m.1688.com/h5/{api_name}/{api_version}/?jsv=2.7.4&appKey={app_key}&t={t}&sign={sign}&api={api_name}&v={api_version}&dataType=json&type=originaljson&data={encoded_data}"

        print(f"\nGenerated URL: {url}")

        new_page = context.new_page()
        new_page.goto(url)
        
        # Get the content (JSON response)
        content = new_page.content()
        print("\nAPI Response:")
        print(content)

        # Optionally, save to file
        with open("api_response.json", "w", encoding="utf-8") as f:
            f.write(content)

        # Display debug info
        print("\nDebug Information:")
        debug_info = {
            "apiName": api_name,
            "apiVersion": api_version,
            "appKey": app_key,
            "token": token,
            "timestamp": t,
            "signContent": f"{token}&{t}&{app_key}&{json.dumps(data)}",
            "generatedSign": sign
        }
        print(json.dumps(debug_info, indent=2))

        # Keep the browser open for inspection
        input("Press Enter to close the browser...")
        browser.close()

def main2():
    # API parameters
    api_name = "mtop.relationrecommend.WirelessRecommend.recommend"
    api_version = "2.0"
    app_key = "12574478"
    data = {
        "appId": 32517,
        "params": "{\"verticalProductFlag\":\"pcmarket\",\"searchScene\":\"pcOfferSearch\",\"charset\":\"GBK\",\"beginPage\":1, \"pageSize\":60,\"keywords\":\"%C6%BB%B9%FB16max\",\"spm\":\"a260k.home2025.searchbox.0\",\"method\":\"getOfferList\"}"
    }
    driver = get_driver()
    url = "https://www.1688.com"
    driver.get(url)
    time.sleep(12)


    # Extract cookies
    cookies = driver.get_cookies()
    token = None
    for cookie in cookies:
        if cookie["name"] == "_m_h5_tk":
            token = cookie["value"].split('_')[0]
            break

    if not token:
        print("Error: Could not find _m_h5_tk cookie")
        driver.quit()
        return

    print(f"Extracted token: {token}")

    # Generate timestamp and signature
    t = int(time.time() * 1000)
    print("Time is",t)
    sign = generate_mtop_sign(token, app_key, data, t)

    # Encode data for URL
    encoded_data = urllib.parse.quote(json.dumps(data))

    # Construct the URL
    url = f"https://h5api.m.1688.com/h5/{api_name}/{api_version}/?jsv=2.7.4&appKey={app_key}&t={t}&sign={sign}&api={api_name}&v={api_version}&dataType=json&type=originaljson&data={encoded_data}"

    print(f"\nGenerated URL: {url}")

    # Open new tab for API Request
    driver.execute_script(f"window.open('{url}','_blank')")
    driver.switch_to.window(driver.window_handles[-1])
    time.sleep(5)
    
    # Get the content (JSON response)
    content = driver.page_source
    print("\nAPI Response:")
    print(content)

    # Optionally, save to file
    with open("api_response.json", "w", encoding="utf-8") as f:
        f.write(content)

    # Display debug info
    print("\nDebug Information:")
    debug_info = {
        "apiName": api_name,
        "apiVersion": api_version,
        "appKey": app_key,
        "token": token,
        "timestamp": t,
        "signContent": f"{token}&{t}&{app_key}&{json.dumps(data)}",
        "generatedSign": sign
    }
    print(json.dumps(debug_info, indent=2))

    # Keep the browser open for inspection
    input("Press Enter to close the browser...")


if __name__ == "__main__":
    main2()