"""
OpenClaw Cron Job payload 构造器。

统一管理三种任务类型的 payload 格式，防止配置混乱。

投递规则：
  - 一次性提醒    → sessionTarget=main + payload.kind=systemEvent
  - 周期静默监控  → sessionTarget=isolated + delivery.mode=none
  - 报告/推送任务 → sessionTarget=isolated + delivery.mode=announce + channel 指定
"""

from __future__ import annotations

import uuid
import time
from datetime import datetime, timezone
from typing import Any


def _new_id() -> str:
    return str(uuid.uuid4())


def _now_ms() -> int:
    return int(time.time() * 1000)


def build_reminder_task_name(
    summary: str,
    start_dt: datetime,
    event_id: str = "",
) -> str:
    if event_id:
        suffix = event_id
    else:
        if start_dt.tzinfo is None:
            raise ValueError("start_dt 必须是 timezone-aware datetime")
        suffix = start_dt.astimezone(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
    return f"提醒-{summary}-{suffix}"


def build_reminder_task(
    name: str,
    remind_at_utc: datetime,
    message: str,
) -> dict[str, Any]:
    """
    一次性提醒任务。

    投递方式：main + systemEvent。
    不设置 delivery，避免 webchat / announce 渠道兼容性问题。
    """
    now = _now_ms()
    return {
        "id":            _new_id(),
        "name":          name,
        "enabled":       True,
        "deleteAfterRun": True,
        "createdAtMs":   now,
        "updatedAtMs":   now,
        "schedule": {
            "kind": "at",
            "at":   _utc_str(remind_at_utc),
        },
        "sessionTarget": "main",
        "wakeMode":      "next-heartbeat",
        "payload": {
            "kind":    "systemEvent",
            "message": message,
        },
    }


def build_periodic_silent_task(
    name: str,
    cron_expr: str,
    message: str,
    tz: str = "Asia/Shanghai",
) -> dict[str, Any]:
    """
    周期性静默监控任务。

    投递方式：isolated + delivery.mode=none。
    适用：日程变化监控、context 使用率检查等。
    """
    now = _now_ms()
    return {
        "id":          _new_id(),
        "name":        name,
        "enabled":     True,
        "createdAtMs": now,
        "updatedAtMs": now,
        "schedule": {
            "kind": "cron",
            "expr": cron_expr,
            "tz":   tz,
        },
        "sessionTarget": "isolated",
        "wakeMode":      "next-heartbeat",
        "payload": {
            "kind":    "agentTurn",
            "message": message,
        },
        "delivery": {"mode": "none"},
    }


def build_report_task(
    name: str,
    message: str,
    channel: str = "",
    to: str = "",
    at_utc: datetime | None = None,
    cron_expr: str | None = None,
    tz: str = "Asia/Shanghai",
    delete_after_run: bool = False,
) -> dict[str, Any]:
    """
    报告/推送任务。

    - channel/to 均为空（默认）：deliver to channel="last"（最近活跃频道，不依赖 Telegram）
    - to 有值：deliver to 指定 channel + to（Telegram 等具体频道）

    at_utc 和 cron_expr 二选一：
      - at_utc    ：一次性任务
      - cron_expr ：周期性任务
    """
    if at_utc is not None:
        schedule: dict[str, Any] = {"kind": "at", "at": _utc_str(at_utc)}
    elif cron_expr is not None:
        schedule = {"kind": "cron", "expr": cron_expr, "tz": tz}
    else:
        raise ValueError("at_utc 和 cron_expr 必须提供其中一个")

    # 默认用 "last"，Telegram 未配置时也能正常推送
    if to:
        delivery: dict[str, Any] = {"mode": "announce", "channel": channel, "to": to}
    else:
        delivery = {"mode": "announce", "channel": "last"}

    now = _now_ms()
    job: dict[str, Any] = {
        "id":          _new_id(),
        "name":        name,
        "enabled":     True,
        "createdAtMs": now,
        "updatedAtMs": now,
        "schedule":    schedule,
        "sessionTarget": "isolated",
        "wakeMode":      "next-heartbeat",
        "payload": {
            "kind":    "agentTurn",
            "message": message,
        },
        "delivery":    delivery,
    }
    if delete_after_run:
        job["deleteAfterRun"] = True
    return job


# ─────────────────────────── 内部工具 ────────────────────────────

def _utc_str(dt: datetime) -> str:
    if dt.tzinfo is None:
        raise ValueError("datetime 必须携带时区信息，不能把 naive datetime 当作 UTC")
    return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
