# -*- coding: utf-8 -*-
# @Time: 2023/9/6
import json
import os
import re
import sys
import time
from appium import webdriver
from appium.webdriver.extensions.android.nativekey import AndroidKey
from appium.webdriver.webdriver import WebDriver
from bs4 import BeautifulSoup
from selenium.common import NoSuchElementException
from selenium.webdriver.common.by import By

sys.path.append(os.getcwd())
from common.common import Common
from common.mq import MQ
from common.public import download_rule, get_config_from_mysql
from common.scheduling_db import MysqlHelper


class KanyikanRecommend:
    platform = "看一看+"
    download_cnt = 0
    element_list = []
    i = 0

    @classmethod
    def start_wechat(cls, log_type, crawler, env, rule_dict, our_uid):
        if env == "dev":
            chromedriverExecutable = "/Users/tzld/Downloads/chromedriver_v111/chromedriver"
        else:
            chromedriverExecutable = "/Users/piaoquan/Downloads/chromedriver"

        Common.logger(log_type, crawler).info("启动微信")
        Common.logging(log_type, crawler, env, '启动微信')
        caps = {
            "platformName": "Android",
            "devicesName": "Android",
            # "platformVersion": "11",
            # "udid": "emulator-5554",
            "appPackage": "com.tencent.mm",
            "appActivity": ".ui.LauncherUI",
            "autoGrantPermissions": "true",
            "noReset": True,
            "resetkeyboard": True,
            "unicodekeyboard": True,
            "showChromedriverLog": True,
            "printPageSourceOnFailure": True,
            "recreateChromeDriverSessions": True,
            "enableWebviewDetailsCollection": True,
            "setWebContentsDebuggingEnabled": True,
            "newCommandTimeout": 6000,
            "automationName": "UiAutomator2",
            "chromedriverExecutable": chromedriverExecutable,
            "chromeOptions": {"androidProcess": "com.tencent.mm:appbrand0"},
        }
        driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
        driver.implicitly_wait(30)

        for i in range(120):
            try:
                if driver.find_elements(By.ID, "com.tencent.mm:id/f2s"):
                    Common.logger(log_type, crawler).info("微信启动成功")
                    Common.logging(log_type, crawler, env, '微信启动成功')
                    break
                elif driver.find_element(By.ID, "com.android.systemui:id/dismiss_view"):
                    Common.logger(log_type, crawler).info("发现并关闭系统下拉菜单")
                    Common.logging(log_type, crawler, env, '发现并关闭系统下拉菜单')
                    driver.find_element(By.ID, "com.android.system:id/dismiss_view").click()
                else:
                    pass
            except NoSuchElementException:
                time.sleep(1)

        Common.logger(log_type, crawler).info("下滑，展示小程序选择面板")
        Common.logging(log_type, crawler, env, '下滑，展示小程序选择面板')
        size = driver.get_window_size()
        driver.swipe(int(size['width'] * 0.5), int(size['height'] * 0.2),
                     int(size['width'] * 0.5), int(size['height'] * 0.8), 200)
        time.sleep(1)
        Common.logger(log_type, crawler).info('打开小程序"看一看+"')
        Common.logging(log_type, crawler, env, '打开小程序"看一看+"')
        driver.find_elements(By.XPATH, '//*[@text="看一看+"]')[-1].click()
        time.sleep(5)

        cls.get_videoList(log_type, crawler, driver, env, rule_dict, our_uid)

        time.sleep(1)
        driver.quit()

    @classmethod
    def search_elements(cls, driver: WebDriver, xpath):
        time.sleep(1)
        windowHandles = driver.window_handles
        for handle in windowHandles:
            driver.switch_to.window(handle)
            time.sleep(1)
            try:
                elements = driver.find_elements(By.XPATH, xpath)
                if elements:
                    return elements
            except NoSuchElementException:
                pass

    @classmethod
    def check_to_applet(cls, log_type, crawler, env, driver: WebDriver):
        time.sleep(1)
        webViews = driver.contexts
        Common.logger(log_type, crawler).info(f"webViews:{webViews}")
        Common.logging(log_type, crawler, env, f"webViews:{webViews}")
        driver.switch_to.context(webViews[1])
        windowHandles = driver.window_handles
        for handle in windowHandles:
            driver.switch_to.window(handle)
            time.sleep(1)
            try:
                driver.find_element(By.XPATH, "//wx-view[@class='snapshot--video-button']//wx-view[1]")
                Common.logger(log_type, crawler).info("切换到小程序成功\n")
                Common.logging(log_type, crawler, env, '切换到小程序成功\n')
                return
            except NoSuchElementException:
                time.sleep(1)

    @classmethod
    def repeat_video(cls, log_type, crawler, video_id, env):
        sql = f""" select * from crawler_video where platform in ("{crawler}","{cls.platform}") and out_video_id="{video_id}"; """

        repeat_video = MysqlHelper.get_values(log_type, crawler, sql, env)
        return len(repeat_video)

    @classmethod
    def swipe_up(cls, driver: WebDriver):
        cls.search_elements(driver, '//*[@class="snapshot--title snapshot--shadow"]')
        size = driver.get_window_size()
        driver.swipe(int(size["width"] * 0.7), int(size["height"] * 0.8),
                     int(size["width"] * 0.7), int(size["height"] * 0.4), 200)

    @classmethod
    def get_video_url(cls, log_type, crawler, driver: WebDriver, video_title_element):
        for i in range(3):
            cls.search_elements(driver, '//*[@class="snapshot--title snapshot--shadow"]')
            Common.logger(log_type, crawler).info(f"video_title_element:{video_title_element[0]}")
            time.sleep(1)
            Common.logger(log_type, crawler).info("滑动标题至可见状态")
            driver.execute_script("arguments[0].scrollIntoView({block:'center',inline:'center'});", video_title_element[0])
            time.sleep(3)
            Common.logger(log_type, crawler).info("点击标题")
            video_title_element[0].click()
            Common.logger(log_type, crawler).info("点击标题完成")
            time.sleep(1)
            video_url_elements = cls.search_elements(driver, "//wx-video[@class='videofull--video']")
            if video_url_elements:
                return video_url_elements[0].get_attribute("src")

    @classmethod
    def get_videoList(cls, log_type, crawler, driver: WebDriver, env, rule_dict, our_uid):
        mq = MQ(topic_name="topic_crawler_etl_" + env)
        driver.implicitly_wait(20)
        # 鼠标左键点击， 1为x坐标， 2为y坐标
        cls.check_to_applet(log_type=log_type, crawler=crawler, env=env, driver=driver)
        time.sleep(1)

        page = 0
        while True:
            if cls.search_elements(driver, "//wx-view[@class='snapshot--video-button']//wx-view[1]") is None:
                Common.logger(log_type, crawler).info("窗口已销毁\n")
                Common.logging(log_type, crawler, env, '窗口已销毁\n')
                cls.i = 0
                cls.download_cnt = 0
                cls.element_list = []
                return

            cls.swipe_up(driver)

            page_source = driver.page_source
            soup = BeautifulSoup(page_source, 'html.parser')
            soup.prettify()

            video_list_elements = soup.findAll("wx-snapshotcomp", class_="snap-shot-comp")
            # video_list_elements 有，cls.element_list 中没有的元素
            video_list_elements = list(set(video_list_elements).difference(set(cls.element_list)))
            # video_list_elements 与 cls.element_list 的并集
            cls.element_list = list(set(video_list_elements) | set(cls.element_list))
            Common.logger(log_type, crawler).info(f"正在抓取第{page + 1}页，共:{len(video_list_elements)}条视频")
            Common.logging(log_type, crawler, env, f"正在抓取第{page + 1}页，共:{len(video_list_elements)}条视频")

            if len(video_list_elements) == 0:
                for i in range(10):
                    Common.logger(log_type, crawler).info(f"向上滑动第{i + 1}次")
                    cls.swipe_up(driver)
                    time.sleep(0.5)
                continue

            for i, video_element in enumerate(video_list_elements):
                try:
                    Common.logger(log_type, crawler).info(f"本轮已抓取{cls.download_cnt}条视频\n")
                    Common.logging(log_type, crawler, env, f"本轮已抓取{cls.download_cnt}条视频\n")
                    if cls.download_cnt >= int(rule_dict.get("videos_cnt", {}).get("min", 10)):
                        cls.i = 0
                        cls.download_cnt = 0
                        cls.element_list = []
                        return
                    cls.i += 1
                    Common.logger(log_type, crawler).info(f"第{cls.i}条视频")
                    Common.logging(log_type, crawler, env, f"第{cls.i}条视频")

                    video_title = video_element.find("wx-view", class_="snapshot--title snapshot--shadow").text
                    cover_url = video_element.find("wx-image", class_="snapshot--snapshoot")["src"]
                    user_name = video_element.find("wx-view", class_="snapshot--author-name").text
                    out_video_id = video_element.get("id")
                    play_str = video_element.find("wx-text", class_="snapshot--comment-text").select_one(
                        "span:nth-of-type(2)").text.strip()
                    play_cnt = play_str.replace("+", "").replace("播放", "")
                    if "万" in play_cnt:
                        match = re.search(r'(\d+(?:\.\d+)?)万', play_cnt)
                        if match:
                            number = float(match.group(1))
                            play_cnt = int(number * 10000)
                    else:
                        play_cnt = int(play_cnt)
                    video_dict = {
                        "video_title": video_title,
                        "video_id": out_video_id,
                        "duration": 0,
                        "play_str": play_str,
                        "play_cnt": play_cnt,
                        "user_name": user_name,
                        "user_id": '',
                        'publish_time_stamp': int(time.time()),
                        'publish_time_str': time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(time.time()))),
                        "avatar_url": cover_url,
                        "cover_url": cover_url,
                        "session": ""
                    }
                    for k, v in video_dict.items():
                        Common.logger(log_type, crawler).info(f"{k}:{v}")
                    Common.logging(log_type, crawler, env, f"video_dict:{video_dict}")
                    # Common.logger(log_type, crawler).info(f"==========分割线==========\n")

                    if video_title is None or cover_url is None:
                        Common.logger(log_type, crawler).info("无效视频\n")
                        Common.logging(log_type, crawler, env, '无效视频\n')
                        cls.swipe_up(driver)
                        time.sleep(0.5)
                    elif download_rule(log_type=log_type, crawler=crawler, video_dict=video_dict,
                                       rule_dict=rule_dict) is False:
                        Common.logger(log_type, crawler).info("不满足抓取规则\n")
                        Common.logging(log_type, crawler, env, "不满足抓取规则\n")
                        cls.swipe_up(driver)
                        time.sleep(0.5)
                    elif any(str(word) if str(word) in video_dict["video_title"] else False
                             for word in get_config_from_mysql(log_type=log_type,
                                                               source=crawler,
                                                               env=env,
                                                               text="filter",
                                                               action="")) is True:
                        Common.logger(log_type, crawler).info('已中过滤词\n')
                        Common.logging(log_type, crawler, env, '已中过滤词\n')
                        cls.swipe_up(driver)
                        time.sleep(0.5)
                    # elif cls.repeat_video(log_type, crawler, out_video_id, env) != 0:
                    #     Common.logger(log_type, crawler).info('视频已下载\n')
                    #     Common.logging(log_type, crawler, env, '视频已下载\n')
                    #     cls.swipe_up(driver)
                    #     time.sleep(5)
                    else:
                        video_title_element = cls.search_elements(driver, f'//*[contains(text(), "{video_title}")]')
                        if video_title_element is None:
                            Common.logger(log_type, crawler).warning(f"未找到该视频标题的element:{video_title_element}")
                            Common.logging(log_type, crawler, env, f"未找到该视频标题的element:{video_title_element}")
                            continue
                        Common.logger(log_type, crawler).info("点击标题，进入视频详情页")
                        Common.logging(log_type, crawler, env, "点击标题，进入视频详情页")
                        video_url = cls.get_video_url(log_type, crawler, driver, video_title_element)
                        if video_url is None:
                            Common.logger(log_type, crawler).info("未获取到视频播放地址\n")
                            # driver.press_keycode(AndroidKey.BACK)
                            time.sleep(5)
                            continue
                        Common.logger(log_type, crawler).info(f"video_url:{video_url}")
                        comment_cnt = driver.find_element(By.XPATH,
                                                          "//wx-swiper-item[@data-key='A']//wx-view[@class='videofull--comments']//span[2]").text
                        like_cnt = driver.find_element(By.XPATH,
                                                        "//wx-swiper-item[@data-key='A']//wx-view[@class='videofull--large-btn-box videofull--share-model-timeline']//wx-view[2]//wx-text[1]//span[2]").text
                        share_cnt = driver.find_element(By.XPATH,
                                                         "//wx-swiper-item[@data-key='A']//wx-view[@class='videofull--large-btn-box videofull--share-model-timeline']//wx-view[3]//wx-text[1]//span[2]").text

                        # 评论
                        comment_cnt = comment_cnt.replace("+", "")
                        if "万" in comment_cnt:
                            comment_cnt = int(comment_cnt.split("万")[0]) * 10000
                        elif comment_cnt == "":
                            comment_cnt = 0
                        else:
                            comment_cnt = int(comment_cnt)
                        # 点赞
                        like_cnt = like_cnt.replace("+", "")
                        if "万" in like_cnt:
                            like_cnt = int(like_cnt.split("万")[0]) * 10000
                        elif like_cnt == "":
                            like_cnt = 0
                        else:
                            like_cnt = int(like_cnt)
                        # 分享
                        share_cnt = share_cnt.replace("+", "")
                        if "万" in share_cnt:
                            share_cnt = int(share_cnt.split("万")[0]) * 10000
                        elif share_cnt == "":
                            share_cnt = 0
                        else:
                            share_cnt = int(share_cnt)


                        video_dict['like_cnt'] = like_cnt
                        video_dict['comment_cnt'] = comment_cnt
                        video_dict['share_cnt'] = share_cnt
                        video_dict['video_url'] = video_url

                        video_dict["platform"] = crawler
                        video_dict["strategy"] = log_type
                        video_dict["out_video_id"] = video_dict["video_id"]
                        video_dict["crawler_rule"] = json.dumps(rule_dict)
                        video_dict["user_id"] = our_uid
                        video_dict["publish_time"] = video_dict["publish_time_str"]
                        mq.send_msg(video_dict)
                        cls.download_cnt += 1
                        driver.press_keycode(AndroidKey.BACK)
                        time.sleep(5)
                        cls.swipe_up(driver)
                except Exception as e:
                    driver.press_keycode(AndroidKey.BACK)
                    Common.logger(log_type, crawler).error(f"抓取单条视频异常:{e}\n")
                    Common.logging(log_type, crawler, env, f"抓取单条视频异常:{e}\n")
            Common.logger(log_type, crawler).info("已抓取完一组，休眠 5 秒\n")
            Common.logging(log_type, crawler, env, "已抓取完一组，休眠 5 秒\n")
            time.sleep(5)
            page += 1



if __name__ == "__main__":
    rule_dict1 = {"period": {"min": 0, "max": 365},
                  "duration": {"min": 0, "max": 1800},
                  "favorite_cnt": {"min": 0, "max": 0},
                  "videos_cnt": {"min": 10, "max": 20},
                  "share_cnt": {"min": 0, "max": 0}}
    KanyikanRecommend.start_wechat("recommend", "kanyikan", "dev", rule_dict1, 6267141)
