"""
定时任务管理和执行。

本模块负责定义、调度和执行所有后台定时任务，
例如每日自动登录/登出、QMT重启以及连接状态检查等。
"""
import schedule
import threading
import time
import subprocess
import os

from config import Config
from logger_config import get_logger
from core.base_trader import BaseTrader
from core.app_state import login, logout, is_real_mode, _trader_instance, logger as app_logger # 使用 app_state中的logger

# 如果需要独立的 logger，可以取消下面这行的注释
# logger = get_logger("scheduler") 
logger = app_logger # 复用 app_state 的 logger

def _run_scheduler() -> None:
    """定时任务执行线程的主循环。"""
    while True:
        try:
            schedule.run_pending()
            time.sleep(1)
        except Exception as e:
            logger.error(f"调度器执行错误: {str(e)}")

def _check_reconnect() -> None:
    """定期检查交易实例是否需要重连（仅实盘模式）。"""
    while True:
        try:
            # 直接使用 app_state 中的 _trader_instance
            if is_real_mode() and _trader_instance is not None and hasattr(_trader_instance, 'check_reconnect'):
                _trader_instance.check_reconnect()
            time.sleep(60)  # 每分钟检查一次
        except Exception as e:
            logger.error(f"重连检查错误: {str(e)}")

def login_on_trading_day() -> None:
    """仅在交易日执行登录操作。"""
    if BaseTrader.is_trading_date():
        logger.info("今天是交易日，执行计划的登录操作")
        login() # 调用 app_state.login
    else:
        logger.info("今天不是交易日，跳过计划的登录操作")

def logout_on_trading_day() -> None:
    """仅在交易日执行登出操作。"""
    if BaseTrader.is_trading_date():
        logger.info("今天是交易日，执行计划的登出操作")
        logout() # 调用 app_state.logout
    else:
        logger.info("今天不是交易日，跳过计划的登出操作")

def restart_qmt() -> None:
    """重启QMT客户端软件。"""
    try:
        if not os.path.exists(Config.XT_LAUNCHER):
            logger.error(f"QMT启动路径不存在: {Config.XT_LAUNCHER}")
            return

        for proc_name in [Config.XT_PROCESS1, Config.XT_PROCESS2]:
            try:
                kill_cmd = f'taskkill /F /IM {proc_name}'
                result = subprocess.run(kill_cmd, shell=True, capture_output=True, text=True, check=False)
                if result.returncode == 0:
                    logger.info(f"已关闭进程: {proc_name}")
                else:
                    # 进程不存在通常返回码 128 或 1
                    if result.returncode not in [1, 128]: 
                        logger.warning(f"关闭进程 {proc_name} 时返回码: {result.returncode}, 输出: {result.stdout}, 错误: {result.stderr}")
            except Exception as e:
                logger.error(f"关闭进程 {proc_name} 时发生异常: {str(e)}")

        time.sleep(3)
        subprocess.Popen(Config.XT_LAUNCHER)
        time.sleep(10)
        logger.info(f"已尝试启动QMT软件: {Config.XT_LAUNCHER}")
    except Exception as e:
        logger.error(f"重启QMT软件时发生错误: {str(e)}")

def restart_qmt_on_trading_day() -> None:
    """仅在交易日执行QMT软件重启操作。"""
    if BaseTrader.is_trading_date():
        logger.info("今天是交易日，执行计划的QMT软件重启操作")
        restart_qmt()
    else:
        logger.info("今天不是交易日，跳过计划的QMT软件重启")

def setup_scheduler() -> threading.Thread:
    """
    设置所有定时任务并启动调度线程。

    Returns:
        threading.Thread: 启动的调度器线程实例。
    """
    schedule.every().day.at(Config.MARKET_OPEN_TIME).do(login_on_trading_day)
    schedule.every().day.at(Config.MARKET_CLOSE_TIME).do(logout_on_trading_day)
    schedule.every().day.at(Config.XT_RESTART_TIME).do(restart_qmt_on_trading_day)
    
    scheduler_thread = threading.Thread(target=_run_scheduler, daemon=True)
    scheduler_thread.start()
    logger.info("定时任务调度器已启动")
    
    if is_real_mode():
        reconnect_thread = threading.Thread(target=_check_reconnect, daemon=True)
        reconnect_thread.start()
        logger.info("重连检查线程已启动")
    
    return scheduler_thread 