#!/usr/bin/env python3
"""
批量日程导入工具。

接收 JSON 格式的事件列表，批量写入 Google Calendar，并可选注册 OpenClaw 提醒任务。
配合 table_parser.py 使用：先解析文件/OCR 内容得到 JSON，再由本脚本批量写入 GCal。

输入格式（每条事件）：
    {
        "summary":     "产品评审",         # 必填
        "date":        "2026-04-02",       # 必填 YYYY-MM-DD
        "start":       "14:00",            # 必填 HH:MM
        "end":         "15:30",            # 可选（省略则 start + 60 分钟）
        "location":    "线上",             # 可选
        "description": "Q2 规划",          # 可选
        "remind":      15                  # 可选，提前提醒分钟数（0=不提醒）
    }

用法：
    # 从 JSON 字符串
    python3 apps/import_events.py --json '[{"summary":"...","date":"...","start":"..."}]'

    # 从 JSON 文件
    python3 apps/import_events.py --file /tmp/events.json

    # 通过 stdin（配合 table_parser 管道）
    python3 apps/import_events.py --stdin

    # 干运行（不写 GCal）
    python3 apps/import_events.py --file /tmp/events.json --dry-run

    # 覆盖所有事件的提醒时间
    python3 apps/import_events.py --file /tmp/events.json --remind-default 15

输出（JSON）：
    {"ok": true, "added": 3, "failed": 0, "skipped": 0, "results": [...]}
"""

from __future__ import annotations

import argparse
import json
import sys
from datetime import timedelta
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent))

from config.settings import TIMEZONE
from gcal.client import CalendarAPIError, CalendarAuthError
from services.calendar_backend import active_provider, create_event as backend_create_event
from services.datetime_utils import DateTimeValidationError, build_event_range
from services.job_store import append_job_if_absent
from services.task_builder import build_reminder_task, build_reminder_task_name


# ─────────────────────────── 事件写入 ────────────────────────────

def _import_one(
    event: dict,
    dry_run: bool,
    remind_override: int | None,
) -> dict:
    """
    导入单个事件，返回结果 dict。
    result: {"summary": ..., "ok": bool, "event_id": ..., "error": ...}
    """
    summary = event.get("summary", "").strip()
    date_str = event.get("date", "").strip()
    start_str = event.get("start", "").strip()

    if not summary or not date_str or not start_str:
        return {"summary": summary or "(无标题)", "ok": False,
                "error": "缺少必填字段 summary/date/start"}

    end_str = event.get("end", "")
    try:
        start, end = build_event_range(
            date_str,
            start_str,
            end_str or None,
            60,
            TIMEZONE,
        )
    except DateTimeValidationError as e:
        return {"summary": summary, "ok": False, "error": str(e)}

    location    = event.get("location",    "")
    description = event.get("description", "")
    remind = remind_override if remind_override is not None else int(event.get("remind", 0))

    if dry_run:
        return {
            "summary":  summary,
            "ok":       True,
            "dry_run":  True,
            "provider": active_provider(),
            "date":     date_str,
            "start":    start.strftime("%H:%M"),
            "end":      end.strftime("%H:%M"),
            "location": location,
            "remind":   remind,
        }

    try:
        created = backend_create_event(
            summary=summary, start=start, end=end,
            location=location, description=description,
            remind_minutes=remind,
        )
    except (CalendarAuthError, CalendarAPIError) as e:
        return {"summary": summary, "ok": False, "error": str(e)}

    # 可选：注册 OpenClaw 提醒
    reminder_status = {"registered": False, "existed": False, "error": None}
    if remind > 0:
        try:
            from datetime import timezone as _tz
            remind_at_utc = (start - timedelta(minutes=remind)).astimezone(_tz.utc)
            payload = build_reminder_task(
                name=build_reminder_task_name(summary, start, created.event_id),
                remind_at_utc=remind_at_utc,
                message=(
                    f"⏰ **{summary}** 将在 {remind} 分钟后开始\n"
                    f"🕐 {start.strftime('%H:%M')}"
                    + (f"\n📍 {location}" if location else "")
                ),
            )
            if append_job_if_absent(payload):
                reminder_status["registered"] = True
                reminder_status["existed"] = False
            else:
                reminder_status["registered"] = True
                reminder_status["existed"] = True
        except Exception as e:
            reminder_status["error"] = str(e)

    return {
        "summary":              summary,
        "ok":                   True,
        "provider":             created.provider,
        "sync_state":           created.sync_state,
        "event_id":             created.event_id,
        "date":                 date_str,
        "start":                start.strftime("%H:%M"),
        "end":                  end.strftime("%H:%M"),
        "location":             location,
        "remind":               remind,
        "reminder_registered":  reminder_status["registered"],
        "reminder_existed":     reminder_status["existed"],
        "reminder_error":       reminder_status["error"],
    }


# ─────────────────────────── main ────────────────────────────────

def main() -> None:
    parser = argparse.ArgumentParser(
        description="批量导入日程事件到 Google Calendar",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    src = parser.add_mutually_exclusive_group(required=True)
    src.add_argument("--json",  help="事件 JSON 字符串（数组）")
    src.add_argument("--file",  help="事件 JSON 文件路径")
    src.add_argument("--stdin", action="store_true", help="从 stdin 读取 JSON")
    parser.add_argument("--remind-default", type=int, default=None,
                        help="覆盖所有事件的提前提醒分钟数（0=不提醒）")
    parser.add_argument("--dry-run", action="store_true",
                        help="只打印 payload，不写入 Google Calendar")
    args = parser.parse_args()

    # ── 读取事件列表 ──────────────────────────────────────────────
    try:
        if args.json:
            events = json.loads(args.json)
        elif args.file:
            with open(args.file, encoding="utf-8") as f:
                events = json.load(f)
        else:
            events = json.load(sys.stdin)
    except Exception as e:
        print(json.dumps({"ok": False, "error": f"读取事件失败: {e}"}, ensure_ascii=False))
        sys.exit(1)

    if not isinstance(events, list):
        events = [events]

    if not events:
        print(json.dumps({"ok": True, "added": 0, "failed": 0, "skipped": 0, "results": []},
                         ensure_ascii=False))
        return

    # ── 逐条写入 ─────────────────────────────────────────────────
    results = []
    added = failed = skipped = 0

    for ev in events:
        r = _import_one(ev, args.dry_run, args.remind_default)
        results.append(r)
        if r["ok"]:
            added += 1
        else:
            failed += 1

    summary = {
        "ok":      failed == 0,
        "added":   added,
        "failed":  failed,
        "skipped": skipped,
        "results": results,
    }
    print(json.dumps(summary, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    main()
