#!/usr/bin/env python3
"""
使用 OpenClaw API 注册 Cron 任务（不依赖 openclaw 命令）
"""

import json
import sys
from datetime import datetime, timezone
from pathlib import Path
from typing import List, Optional, Dict, Any

# Handle zoneinfo import for Python 3.8 compatibility
try:
    from zoneinfo import ZoneInfo
except ImportError:
    from backports.zoneinfo import ZoneInfo

# 添加父目录到路径
sys.path.insert(0, str(Path(__file__).parent.parent))

from config.settings import (
    TIMEZONE,
    TASK_REGISTRY_FILE,
)
from services.task_builder import (
    build_reminder_task,
    build_periodic_silent_task,
    build_report_task,
)
from services.job_store import append_job_if_absent, list_job_names
from services.runtime_utils import expand_command_vars
from services.datetime_utils import now_local
from services.calendar_backend import active_provider


def _utc_str(dt: datetime) -> str:
    """转换为 UTC 时间字符串"""
    if dt.tzinfo is None:
        dt = dt.replace(tzinfo=timezone.utc)
    return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")


def is_task_enabled(task: Dict[str, Any], provider: str | None = None) -> bool:
    required = task.get("requires_provider", "any")
    current = provider or active_provider()
    return required in {"", "any", current}


def load_fixed_tasks(provider: str | None = None) -> List[Dict[str, Any]]:
    """加载固定任务配置"""
    import yaml
    with open(TASK_REGISTRY_FILE) as f:
        data = yaml.safe_load(f)
    tasks = data.get("tasks", [])
    return [task for task in tasks if is_task_enabled(task, provider=provider)]


def build_cron_job_from_task(task: Dict[str, Any], today: datetime) -> Optional[Dict[str, Any]]:
    """根据任务配置构建 Cron Job"""
    name = task.get("name", "")
    task_type = task.get("type", "")
    message = expand_command_vars(task.get("message", task.get("command", "")))
    schedule = task.get("schedule", {})
    delete = task.get("delete_after_run", True)

    if not name or not schedule:
        return None

    kind = schedule.get("kind")
    zone = ZoneInfo(TIMEZONE)

    if kind == "at":
        time_str = schedule.get("time", "")
        try:
            h, m = map(int, time_str.split(":"))
            bj_time = today.astimezone(zone).replace(hour=h, minute=m, second=0, microsecond=0)
        except (ValueError, IndexError):
            print("⚠️  无法解析时间 '{}', 跳过任务 {}".format(time_str, name))
            return None

        if task_type == "silent":
            # 静默一次性任务
            return {
                "name": name,
                "schedule": {"kind": "at", "at": _utc_str(bj_time)},
                "sessionTarget": "isolated",
                "payload": {"kind": "agentTurn", "message": message},
                "delivery": {"mode": "none"},
                "deleteAfterRun": delete,
                "enabled": True,
            }
        else:
            # 报告任务
            return build_report_task(
                name, message,
                at_utc=bj_time, delete_after_run=delete,
            )

    elif kind == "cron":
        cron_expr = schedule.get("expr", "")
        tz = schedule.get("tz", TIMEZONE)
        if task_type == "silent":
            return build_periodic_silent_task(name, cron_expr, message, tz)
        else:
            return build_report_task(
                name, message,
                cron_expr=cron_expr, tz=tz, delete_after_run=delete,
            )

    return None


def main():
    import argparse
    parser = argparse.ArgumentParser(description="使用 OpenClaw API 注册 Cron 任务")
    parser.add_argument("--dry-run", action="store_true", help="只生成，不注册")
    parser.add_argument("--days", type=int, default=1, help="生成 N 天的任务")
    args = parser.parse_args()

    # 加载任务配置
    tasks = load_fixed_tasks()
    print("📋 加载了 {} 个固定任务配置\n".format(len(tasks)))

    # 生成任务
    today = now_local(TIMEZONE)
    jobs = []

    for task in tasks:
        job = build_cron_job_from_task(task, today)
        if job:
            jobs.append(job)
            if args.dry_run:
                print("[dry-run] 将注册: {}".format(job['name']))
            else:
                print("✅ 准备注册: {}".format(job['name']))

    if args.dry_run:
        print("\n📊 共 {} 个任务（dry-run 模式，未注册）".format(len(jobs)))
        return

    try:
        existing_names = list_job_names()
        print("\n📄 已有 {} 个任务".format(len(existing_names)))

        new_jobs = []
        for job in jobs:
            name = job.get("name", "")
            if name not in existing_names:
                if append_job_if_absent(job):
                    new_jobs.append(job)
                    existing_names.add(name)
                    print("✅ 已注册: {}".format(name))
                else:
                    print("⏭️  任务已存在，跳过: {}".format(name))
            else:
                print("⏭️  任务已存在，跳过: {}".format(name))

        print("\n🎉 成功注册 {} 个新任务！".format(len(new_jobs)))
        print("📁 任务已保存到: {}".format(Path.home() / ".openclaw" / "cron" / "jobs.json"))

    except Exception as e:
        print("\n❌ 注册失败: {}".format(e))
        import traceback
        traceback.print_exc()
        sys.exit(1)


if __name__ == "__main__":
    main()
