import random
import json
import time
import logging as logger

from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from MediaSpiders.settings import REDIS_HOST, REDIS_PORT, REDIS_PWD, SOCIAL_USER_QUERY_ALL_API, SOCIAL_USER_UPDATE_API, \
    WECHAT_USER_TYPE
from MediaSpiders.utils.http_utils import http_post, UA

class login:
    def __init__(self):
        self.name = None
        self.url = None



    def login_with_selenium(self, login_url, site_name, login_users=None, response=None, drivers=None):
        """
        使用 Selenium 自动登录指定站点（从 Redis 账号池中随机选一个账号）

        :param driver: Selenium WebDriver 实例
        :param login_url: 登录页面 URL
        :param site_name: 站点名称（如 'Facebook'）
        :param login_users: Redis 客户端获取的账号密码
        """
        self.name = site_name
        self.url = login_url
        logger.info(f"Starting login to {site_name}...")
        if response is not None:
            driver = response.request.meta['driver']
        elif drivers is not None:
            driver = drivers

        if login_users is not None:
            # 解析 redis 中 账号密码
            user_list = [json.loads(u.decode()) for u in login_users]
            self.login_user = random.choice(user_list)

        if self.name == 'FacebookUserSpider':
            self.facebook_login(driver)
        elif self.name == 'TwitterUserSpider' or self.name == 'TwitterUserInfoSpider' :
            self.twitter_login(driver)
        elif self.name == 'wechat_links_fetcher':
            self.wechat_links_login(driver)


        time.sleep(10)  # 等待登录完成（可优化为显式等待）

        return driver

    """
        FaceBook 登录 获取cookie
    """
    def facebook_login(self, driver):
        # 打开登录页
        driver.maximize_window() # 注意：原代码中有空格！
        time.sleep(3)
        driver.get(self.url)

        driver.find_element_by_xpath(
            '//input[@name="email"]').send_keys(self.login_user['uid'])
        driver.find_element_by_xpath(
            '//input[@name="pass"]').send_keys(self.login_user['pwd'])
        driver.find_element_by_xpath('//button[@name="login"]').click()
        time.sleep(10)
        logger.info(f"Logged in to {self.name} as {self.login_user['uid']}")

    """
        Twitter 登录 获取cookie
    """
    def twitter_login(self, driver):
        # 打开登录页
        driver.maximize_window() # 注意：原代码中有空格！
        time.sleep(3)
        driver.get(self.url)

        # 隐藏指纹
        driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument', {
            'source': '''
                                            delete navigator.__proto__.webdriver;
                                            Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
                                        '''
        })
        wait = WebDriverWait(driver, 15)
        # 2. 通过 JS 打开第二个标签页（新 Tab）
        time.sleep(5)
        driver.execute_script("window.open('');")
        driver.execute_script("window.open('https://x.com/i/flow/login', '_blank');")

        # 3. 获取所有标签页句柄
        handles = driver.window_handles  # [handle1, handle2]

        # 4. 切换到第二个标签页（可选）
        driver.switch_to.window(handles[1])

        logger.info(f"login as user {self.login_user['uid']}")
        # time.sleep(random.uniform(1.5, 3.0))
        # driver.find_element_by_xpath("//input").send_keys(login_user['uid'])
        # 等待并定位用户名输入框
        username_input = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, 'input[autocomplete="username"]'))
        )

        # 模拟真人逐字输入（带随机延迟）
        username = self.login_user['uid']
        for char in username:
            username_input.send_keys(char)
            time.sleep(random.uniform(0.05, 0.2))  # 每个字符间隔 50~200ms

        time.sleep(random.uniform(0.3, 0.8))  # 输入完后稍作停顿

        # 尝试点击 "Next" 按钮（主逻辑：带文本的按钮）
        try:
            next_button = wait.until(
                EC.element_to_be_clickable(
                    (By.XPATH, "//button[.//span[contains(text(), 'Next') or contains(text(), '下一步')]]")
                )
            )
            body = driver.find_element(By.TAG_NAME, "body")
            ActionChains(driver).move_to_element_with_offset(body, 100, 100).perform()
            time.sleep(0.5)
            # 模拟鼠标移动到按钮并点击
            actions = ActionChains(driver)
            actions.move_to_element(next_button).pause(random.uniform(0.2, 0.6)).click().perform()

        except Exception as e:
            logger.info("主 Next 按钮未找到，尝试备用定位方式")
            try:
                # 备用：通过 role 定位第二个 button
                next_button = driver.find_element(By.XPATH, "//button[@role='button'][2]")
                actions = ActionChains(driver)
                actions.move_to_element(next_button).pause(random.uniform(0.2, 0.6)).click().perform()
            except Exception as e2:
                logger.error(f"两种方式均无法点击 Next 按钮: {e}, {e2}")
                raise
        time.sleep(random.uniform(1.5, 5.0))  # 等待页面加载
        try:
            logger.info("输入手机号验证...")
            driver.find_element_by_xpath("//input[@name='text']").send_keys("+8619962025641")
            # driver.find_element_by_xpath("//button[@data-testid='ocfEnterTextNextButton']").click()
            driver.find_element_by_xpath(driver.find_element_by_xpath("//button[.//span[text()='下一步']]")).click()
            time.sleep(random.uniform(1.5, 5.0))  # 等待页面加载
        except Exception:
            logger.info("无需输入手机号验证")
        driver.find_element_by_xpath("//input[@name='password']").send_keys(self.login_user['pwd'])
        driver.find_element_by_xpath("//button[@data-testid='LoginForm_Login_Button']").click()
        time.sleep(random.uniform(1.5, 5.0))  # 等待页面加载
        try:
            driver.find_element_by_xpath("//button[@data-testid='confirmationSheetConfirm']").click()
            time.sleep(random.uniform(1.5, 10.0))  # 等待页面加载
        except:
            time.sleep(5)
        logger.info(f"Logged in to {self.name} as {self.login_user['uid']}")

    def wechat_links_login(self, driver):
        driver.maximize_window()
        driver.get(self.url)
        print("等待打开登录后的页面...")
        while True:
            delay = random.randint(5, 11)
            time.sleep(delay)
            if 'token=' in driver.current_url:
                print("登录成功！")
                logger.info(f"Logged in to {self.name}")
                break

