from __future__ import annotations

import time
from datetime import datetime, timedelta


def 定时放行(目标时间: str) -> bool:
    """等待到每天指定时间后再继续往下执行。

    功能说明:
        - 这个函数用于让程序卡在这里，等到每天某个固定时刻到了再继续执行后面的代码。
        - 参数要写成 ``HH:MM`` 这种 24 小时格式，比如 ``09:30``、``23:05``。
        - 如果当前时间已经晚于今天的目标时间，函数会自动等到明天同一时间。
        - 过程中不会一直空转占用 CPU，而是内部用 ``sleep`` 等待。
        - 成功等到目标时间返回 ``True``，参数错误或异常时返回 ``False``。

    Args:
        目标时间: 每天要放行的时间，格式为 ``HH:MM``。

    Returns:
        成功放行返回 ``True``；失败返回 ``False``。
    """
    try:
        now = datetime.now()
        today_str = now.strftime("%Y-%m-%d")
        target_dt = datetime.strptime(f"{today_str} {目标时间}", "%Y-%m-%d %H:%M")

        if now >= target_dt:
            target_dt += timedelta(days=1)

        wait_seconds = (target_dt - now).total_seconds()

        if wait_seconds > 0:
            time.sleep(wait_seconds)

        return True
    except Exception:
        return False


if __name__ == "__main__":
    from unittest.mock import patch

    class 上午八点(datetime):
        @classmethod
        def now(cls):
            return cls(2026, 3, 20, 8, 0, 0)

    class 上午八点十分(datetime):
        @classmethod
        def now(cls):
            return cls(2026, 3, 20, 8, 10, 0)

    print("===== 示例1：当前时间早于目标时间，会等待到今天目标时间 =====")
    with patch("__main__.datetime", 上午八点), patch("__main__.time.sleep") as 假睡眠:
        结果 = 定时放行("08:05")
        print("结果:", 结果, "等待秒数:", int(假睡眠.call_args[0][0]))

    print("\n===== 示例2：当前时间晚于目标时间，会等待到明天同一时间 =====")
    with patch("__main__.datetime", 上午八点十分), patch("__main__.time.sleep") as 假睡眠:
        结果 = 定时放行("08:05")
        print("结果:", 结果, "等待秒数:", int(假睡眠.call_args[0][0]))

    print("\n===== 示例3：目标时间写成整点 =====")
    with patch("__main__.datetime", 上午八点), patch("__main__.time.sleep") as 假睡眠:
        结果 = 定时放行("09:00")
        print("结果:", 结果, "等待秒数:", int(假睡眠.call_args[0][0]))

    print("\n===== 示例4：目标时间格式错误 =====")
    print("结果:", 定时放行("8点05分"))

    print("\n===== 示例5：目标时间为空字符串 =====")
    print("结果:", 定时放行(""))

    print("\n===== 示例6：应用场景-每天 18:00 再生成日报 =====")
    class 下午五点五十五(datetime):
        @classmethod
        def now(cls):
            return cls(2026, 3, 20, 17, 55, 0)

    with patch("__main__.datetime", 下午五点五十五), patch("__main__.time.sleep") as 假睡眠:
        结果 = 定时放行("18:00")
        print("结果:", 结果, "等待秒数:", int(假睡眠.call_args[0][0]))
