from __future__ import annotations

import argparse
import json
import sys

from niannian import NianNian


def _print_json(data: object) -> None:
    if hasattr(data, "to_dict"):
        data = data.to_dict()  # type: ignore[union-attr]
    elif hasattr(data, "to_dict") is False and hasattr(data, "__dataclass_fields__"):
        from dataclasses import asdict

        data = asdict(data)
    print(json.dumps(data, ensure_ascii=False, indent=2))


def main(argv: list[str] | None = None) -> int:
    argv = list(argv) if argv is not None else sys.argv[1:]
    if argv and argv[0] == "cloud":
        from niannian.cli import cloud as cloud_cli

        return cloud_cli.run(argv[1:])

    parser = argparse.ArgumentParser(prog="niannian", description="念念 — 外置记忆大脑 CLI")
    parser.add_argument("--home", help="NIANNIAN_HOME 覆盖路径")
    parser.add_argument("--project", default="global", help="项目命名空间，如 novelstudio")

    sub = parser.add_subparsers(dest="cmd", required=True)

    p_ingest = sub.add_parser("ingest", help="小忆：记入碎片")
    p_ingest.add_argument("text")
    p_ingest.add_argument("--tags", default="", help="逗号分隔标签")
    p_ingest.add_argument("--source", default="cli")

    p_query = sub.add_parser("query", help="念念：联想问答")
    p_query.add_argument("question")

    p_assist = sub.add_parser("assist", help="念念：碎片化思考辅助，输出 context_block")
    p_assist.add_argument("task")
    p_assist.add_argument("--context", default="", help="宿主当前上下文")

    sub.add_parser("dream", help="小海：记忆提炼")
    sub.add_parser("health", help="健康检查")

    p_sync = sub.add_parser("sync", help="云端同步（夸克+百度双写）")
    sync_sub = p_sync.add_subparsers(dest="sync_cmd", required=True)
    p_sync_push = sync_sub.add_parser("push", help="推送到 L1 主库")
    p_sync_push.add_argument("--force", action="store_true", help="忽略 Mac 条件限制")
    sync_sub.add_parser("pull", help="从 L1 拉取并合并")
    sync_sub.add_parser("status", help="同步状态")

    p_serve = sub.add_parser("serve", help="启动 HTTP JSON API")
    p_serve.add_argument("--host", default="127.0.0.1")
    p_serve.add_argument("--port", type=int, default=18765)
    p_serve.add_argument("--static", default="", help="Console 静态目录（覆盖 config console.static_dir）")

    p_bridge = sub.add_parser("bridge-client", help="Mac Bridge 客户端 stub（配对后常驻）")
    p_bridge.add_argument("--server", default="http://127.0.0.1:18765")
    p_bridge.add_argument("--device-token", default="")
    p_bridge.add_argument("--once", action="store_true")

    p_worker = sub.add_parser("worker", help="Docker worker 循环（sync/dream/archive）")
    p_worker.add_argument("--once", action="store_true", help="立即执行一轮后退出（冒烟）")

    args = parser.parse_args(argv)
    nn = NianNian(home=args.home, project=args.project)

    if args.cmd == "ingest":
        tags = [t.strip() for t in args.tags.split(",") if t.strip()]
        atom = nn.ingest(args.text, tags=tags, source=args.source)
        _print_json(atom)
        return 0

    if args.cmd == "query":
        _print_json(nn.query(args.question))
        return 0

    if args.cmd == "assist":
        result = nn.assist(args.task, context=args.context)
        _print_json(result)
        return 0

    if args.cmd == "dream":
        _print_json(nn.dream())
        return 0

    if args.cmd == "health":
        _print_json(nn.health())
        return 0

    if args.cmd == "sync":
        if args.sync_cmd == "push":
            _print_json(nn.sync_push(force=args.force))
            return 0
        if args.sync_cmd == "pull":
            _print_json(nn.sync_pull())
            return 0
        if args.sync_cmd == "status":
            _print_json(nn.sync_status())
            return 0

    if args.cmd == "worker":
        from niannian.storage.sync.worker import DockerWorker

        worker = DockerWorker(home=args.home, project=args.project)
        if args.once:
            _print_json(worker.run_once())
            return 0
        worker.run()
        return 0

    if args.cmd == "serve":
        try:
            from niannian.http.server import run_server
        except ImportError as e:
            print("请安装 HTTP 依赖: pip install 'niannian[http]'", file=sys.stderr)
            raise SystemExit(1) from e
        if getattr(args, "static", ""):
            nn._config.setdefault("console", {})["static_dir"] = args.static
            nn._config.setdefault("console", {})["enabled"] = True
        run_server(nn, host=args.host, port=args.port)
        return 0

    if args.cmd == "bridge-client":
        from niannian.cli import bridge_client

        return bridge_client.run(
            server=args.server,
            device_token=args.device_token,
            once=args.once,
        )

    parser.print_help()
    return 1


if __name__ == "__main__":
    raise SystemExit(main())
