import threading
from time import sleep
from typing import List, Dict
from mycode.DBManager import DBManager
from datetime import datetime, timedelta
from mycode.TaskManager import g_TaskM

class PollingManager:
    def __init__(self):
        self.DBM = DBManager()
        self.brun = True
        self.bUpdate = False
        self.p_th = None

    def parse_time(self,time_str: str) -> datetime:
        """将时间字符串转为 datetime 对象"""
        if not time_str:
            return None
        try:
            return datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
        except ValueError:
            return None

    def need_check(self,target: Dict) -> bool:
        now = datetime.datetime.now()
        period = target[5]
        start_time_str = target[6]
        last_time = self.parse_time(target[7])

        # 不巡检的目标
        if target[4] == 0 or period == 0:
            return False

        # 当前时间是否达到设定开始时间
        if start_time_str:
            try:
                # 只取时间部分用于每天/每周的对比
                st_hour, st_minute = map(int, start_time_str.strip().split(':')[:2])
            except Exception:
                return False
        else:
            st_hour, st_minute = 0, 0

        # 当天设定执行时间点
        target_time = now.replace(hour=st_hour, minute=st_minute, second=0, microsecond=0)

        # 如果 last_time 已经检查过今天了,就跳过
        if last_time and last_time >= target_time:
            return False

        if period == 1:  # 每天
            return now >= target_time
        elif period == 2:  # 每周
            return now.weekday() == 0 and now >= target_time  # 每周一执行
        elif period == 3:  # 每月
            return now.day == 1 and now >= target_time  # 每月1号执行
        else:
            return False

    def should_poll(self,polling_period: int, start_time_str: str, last_time_str: str = None) -> bool:
        now = datetime.now()

        # 无周期,直接返回 False
        if polling_period == 0:
            return False

        try:
            # 获取比较基准时间
            if last_time_str:
                base_time = datetime.strptime(last_time_str, "%Y-%m-%d %H:%M:%S")
            elif start_time_str:
                base_time = datetime.strptime(start_time_str, "%Y-%m-%d %H:%M:%S")
                if now > base_time:
                    return True
            else:
                return False
        except Exception as e:
            print(f"时间格式错误: {e}")
            return False

        if polling_period == 1:
            # 每天:超过 24 小时
            return (now - base_time) >= timedelta(days=1)

        elif polling_period == 2:
            # 每周:要到下一个“周一的那个时间点”
            weekday = base_time.weekday()  # 0=周一, ..., 6=周日
            days_to_next_monday = (7 - weekday) % 7 or 7  # 至少是下一个周一
            next_monday = base_time + timedelta(days=days_to_next_monday)
            next_monday = next_monday.replace(hour=base_time.hour, minute=base_time.minute, second=base_time.second)
            return now >= next_monday

        elif polling_period == 3:
            # 每月:下个月的 1 号,时间点与原始时间相同
            year = base_time.year + (base_time.month // 12)
            month = (base_time.month % 12) + 1
            next_month_first = datetime(year, month, 1, base_time.hour, base_time.minute, base_time.second)
            return now >= next_month_first

        return False

    def do_check(self,target):
        print(f"巡检中: {target[2]} (类型: {target[9]})")
        #创建task---并初始化待办
        g_TaskM.create_polling_task(target)


    def update_last_time(self, target_id):
        now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        strsql = "UPDATE target SET polling_last_time=%s WHERE ID=%s;"
        params = (now_str,target_id)
        bok,_ = self.DBM.safe_do_sql(strsql,params)

    def needUpdateTargets(self):
        self.bUpdate = True

    def polling_th(self):
        strsql = "select * from target;"
        targets = self.DBM.do_select(strsql)
        while self.brun:
            if self.bUpdate:
                targets = self.DBM.do_select(strsql)
                self.bUpdate =False

            for target in targets:
                if self.should_poll(target[5],target[6],target[7]):
                    self.do_check(target)
                    self.update_last_time(target[0])

            sleep(60 * 60) #一个小时

    def run_polling(self):
        self.p_th = threading.Thread(target=self.polling_th(), name=f"p_th")
        self.p_th.start()


if __name__ == "__main__":
    PM = PollingManager()
    PM.polling_th()