from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
import json
import logging
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.triggers.interval import IntervalTrigger
from selenium.webdriver.support.ui import WebDriverWait
from playwright.sync_api import sync_playwright
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# ====================== 【定时开关】在这里 ======================
# True = 开启定时任务
# False = 关闭定时任务（只执行一次，然后自动退出程序）
AUTO_SCHEDULE_ENABLE = False


def requests_finance_api(url, max_retries=3):
    """获取人民币兑韩元数据（含重试机制）"""
    for attempt in range(1, max_retries + 1):
        opt = Options()
        opt.add_argument("--headless=new")
        opt.add_argument("--no-sandbox")
        opt.add_argument("--disable-dev-shm-usage")
        opt.add_argument("--disable-gpu")
        opt.add_argument("--disable-software-rasterizer")
        opt.add_argument("--disable-setuid-sandbox")
        opt.page_load_strategy = "eager"

        driver = None
        try:
            driver = webdriver.Chrome(options=opt)
            driver.set_page_load_timeout(8)
            driver.implicitly_wait(0)

            driver.get(url)
            wait = WebDriverWait(driver, 3)
            prize = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//*[@id="main"]/div/div/div[2]/div/div[2]/div[1]/div/div/div[1]/div[1]'))).text
            increase = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//*[@id="main"]/div/div/div[2]/div/div[2]/div[1]/div/div/div[1]/div[3]'))).text
            ratio = wait.until(EC.presence_of_element_located(
                (By.XPATH, '//*[@id="main"]/div/div/div[2]/div/div[2]/div[1]/div/div/div[1]/div[4]'))).text
            data = {
                "prize": prize,
                "increase": increase,
                "ratio": ratio,
            }
            logger.info(f"成功获取数据: {data}")
            return data
        except Exception as e:
            logger.warning(f"第{attempt}次获取数据失败: {e}")
            if attempt < max_retries:
                import time
                logger.info(f"等待后重试({attempt + 1}/{max_retries})…")
                time.sleep(3)
            else:
                logger.error(f"{max_retries}次重试均失败，跳过汇率数据")
                return None
        finally:
            if driver:
                driver.quit()


def requests_finance_asia_api(code_list):
    finance_data_list = []
    try:
        with sync_playwright() as p:
            browser = p.chromium.launch(headless=True)  # 无头模式
            page = browser.new_page()
            # 先访问主页，建立会话
            page.goto("https://finance.pae.baidu.com/")
            response = page.request.get("https://finance.pae.baidu.com/vapi/v1/globalindexrank?area=asia&type=index&sort_key=default&rn=500&pn=0&finClientType=pc")
            if response.status == 200:
                data = response.json()
                index_list = data.get("Result", {}).get("body", [])
                for item in index_list:
                    code = item.get("exchange", "") + item.get("code", "")
                    if code in code_list:
                        finance_data_list.append({
                            "code": code,
                            "name": item.get('name'),
                            "last_px": item.get('last_px'),
                            "px_change": item.get('px_change'),
                            "px_change_rate": item.get('px_change_rate')
                        })
    except Exception as e:
        logger.error(f"获取指数数据出错: {e}")
    logger.info(f"成功获取 {len(finance_data_list)} 条指数数据")
    return finance_data_list


def collect_all_data():
    """主采集任务"""
    logger.info("=" * 50)
    logger.info("开始执行数据采集任务")

    result = {
        "finance_date": None,
        "finance_asia_date": None
    }

    # 采集汇率数据
    try:
        url = 'https://finance.baidu.com/foreign/global-CNYKRW'
        result["finance_date"] = requests_finance_api(url)
        logger.info("汇率数据采集完成")
    except Exception as e:
        logger.error(f"汇率数据采集失败: {e}")

    # 采集指数数据
    try:
        code_list = ['SH000001', 'SZ399001', 'HKHSI']
        result["finance_asia_date"] = requests_finance_asia_api(code_list)
        logger.info("指数数据采集完成")
    except Exception as e:
        logger.error(f"指数数据采集失败: {e}")

    # 保存数据
    try:
        output_path = "/data/news/json/finance-data.json"
        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(result, f, ensure_ascii=False, indent=4)
        logger.info(f"数据已保存到: {output_path}")
    except Exception as e:
        logger.error(f"保存数据失败: {e}")

    logger.info("采集任务完成")
    logger.info("=" * 50)
    return result

def main():
    """主函数"""
    if AUTO_SCHEDULE_ENABLE:
        # ============== 开启：定时执行模式 ==============
        logger.info("定时任务已开启，启动调度器...")
        scheduler = BlockingScheduler()

        scheduler.add_job(
            collect_all_data,
            trigger=IntervalTrigger(minutes=1),  # 正式：每30分钟
            id='finance_collector',
            name='金融数据采集',
            max_instances=1
        )

        logger.info("调度器已启动，将每30分钟执行一次，按 Ctrl+C 停止")
        try:
            scheduler.start()
        except KeyboardInterrupt:
            logger.info("正在关闭调度器...")
            scheduler.shutdown()
            logger.info("调度器已关闭")

    else:
        # ============== 关闭：只执行一次，然后退出 ==============
        logger.info("定时任务已关闭，仅执行一次数据采集")
        collect_all_data()
        logger.info("单次任务执行完毕，程序自动退出")


if __name__ == '__main__':
    main()
