#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

from common import (
    build_agent_entry,
    default_openclaw_config_path,
    detect_installed_version,
    find_agent_entry,
    find_agent_by_workspace,
    get_agent_dependencies,
    is_agent_installed,
    load_agent_definition,
    load_openclaw_config,
    parse_version,
    resolve_existing_agent_entry,
)


def workspace_exists(path_value: object) -> bool:
    return isinstance(path_value, str) and bool(path_value) and Path(path_value).exists()


def normalized_name(value: object) -> str | None:
    if isinstance(value, str):
        stripped = value.strip()
        if stripped:
            return stripped
    return None


def current_agent_names(current_entry: dict[str, object]) -> tuple[str | None, str | None]:
    current_name = normalized_name(current_entry.get("name"))
    identity = current_entry.get("identity")
    identity_name = None
    if isinstance(identity, dict):
        identity_name = normalized_name(identity.get("name"))
    return current_name, identity_name


def build_user_prompt(result: dict[str, object]) -> str:
    status = result["status"]
    agent_id = str(result["agent_id"])
    target_version = str(result.get("target_version") or "")
    installed_version = str(result.get("installed_version") or "")
    missing_dependencies = result.get("missing_dependencies", [])

    if status == "DEPENDENCY_MISSING":
        deps = "、".join(missing_dependencies) if isinstance(missing_dependencies, list) else str(missing_dependencies)
        return f"检测到依赖 Agent 未安装：{deps}。\n\n请先安装依赖 Agent，再继续安装 `{agent_id}`。\n建议回复：先安装 {deps}"

    if status == "UPDATABLE":
        return (
            f"检测到 `{agent_id}` 有可用更新（{installed_version} -> {target_version}）。\n\n"
            "⚠️ 更新说明：\n"
            "• 更新前会先备份当前 Agent 配置\n"
            "• 更新后如果你之前手动修改过 Agent 配置，需要自行同步这些修改\n\n"
            "是否确认更新？请回复「确认更新」或「取消」。"
        )

    if status == "SAME_VERSION_REINSTALL":
        return (
            f"`{agent_id}` 当前已安装版本与下载版本一致（{target_version}）。\n\n"
            "⚠️ 本次操作不是升级，而是重置 Agent 配置：\n"
            "• 重置前会先备份当前 Agent 配置\n"
            "• 重置后如果你之前手动修改过 Agent 配置，需要自行同步这些修改\n\n"
            "是否确认继续重置？请回复「确认重置」或「取消」。"
        )

    if status == "NOT_INSTALLED":
        return f"`{agent_id}` 尚未安装，可以开始安装。"

    return str(result.get("message") or "当前配置存在异常，请先人工检查。")


def detect_status(
    agent_id: str,
    config_path: Path,
    *,
    source_path: Path | None = None,
    openclaw_id_override: str | None = None,
    workspace_override: str | None = None,
    name_override: str | None = None,
) -> dict[str, object]:
    agent_def = load_agent_definition(agent_id, source_path)
    desired_entry = build_agent_entry(
        agent_def,
        workspace_override=workspace_override,
        name_override=name_override,
    )
    desired_workspace = desired_entry["workspace"]
    desired_openclaw_id = (
        openclaw_id_override.strip()
        if isinstance(openclaw_id_override, str) and openclaw_id_override.strip()
        else agent_id
    )
    desired_name = normalized_name(desired_entry.get("name")) or normalized_name(
        desired_entry.get("identity", {}).get("name") if isinstance(desired_entry.get("identity"), dict) else None
    )
    dependencies = get_agent_dependencies(agent_def)

    try:
        openclaw = load_openclaw_config(config_path)
    except FileNotFoundError:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": False,
            "workspace": desired_workspace,
            "desired_workspace": desired_workspace,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "dependencies": dependencies,
            "missing_dependencies": dependencies,
            "reason": "openclaw_config_missing",
            "message": "openclaw.json 不存在，请先初始化 OpenClaw 环境。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    current_entry_by_id = find_agent_entry(openclaw, agent_id)
    desired_entry_by_openclaw_id = find_agent_entry(openclaw, desired_openclaw_id)
    workspace_owner = find_agent_by_workspace(openclaw, desired_workspace)
    current_entry = resolve_existing_agent_entry(config_path, openclaw, agent_id, desired_workspace)
    installed_by_id = current_entry_by_id is not None
    installed_by_workspace = workspace_owner is not None
    desired_workspace_exists = workspace_exists(desired_workspace)
    missing_dependencies = [dep for dep in dependencies if not is_agent_installed(config_path, openclaw, dep)]

    if missing_dependencies:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "DEPENDENCY_MISSING",
            "installed": current_entry is not None,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "workspace": current_entry.get("workspace", desired_workspace) if current_entry else desired_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": desired_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "message": f"依赖 Agent 未安装：{', '.join(missing_dependencies)}。请先安装依赖 Agent。",
            "suggested_action": f"先安装 {'、'.join(missing_dependencies)}",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if desired_entry_by_openclaw_id is not None and current_entry is None:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": False,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": desired_entry_by_openclaw_id.get("id"),
            "workspace": desired_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": desired_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "openclaw_id_conflict",
            "message": f"目标 openclaw id `{desired_openclaw_id}` 已存在，但不属于当前 Agent，请先人工检查。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if (
        desired_entry_by_openclaw_id is not None
        and current_entry is not None
        and desired_entry_by_openclaw_id is not current_entry
    ):
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_entry.get("id"),
            "workspace": desired_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": desired_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "openclaw_id_conflict",
            "message": f"目标 openclaw id `{desired_openclaw_id}` 已被其他条目占用，请先人工检查。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if current_entry is None and workspace_owner and workspace_owner.get("id") != agent_id:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": False,
            "installed_by_id": False,
            "installed_by_workspace": True,
            "workspace": desired_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": desired_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "workspace_owner_id": workspace_owner.get("id"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "workspace_conflict",
            "message": f"目标 workspace 已被 Agent {workspace_owner.get('id')} 占用，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if current_entry is None:
        if desired_workspace_exists:
            result = {
                "agent_id": agent_id,
                "target_version": agent_def["version"],
                "status": "CONFIG_ERROR",
                "installed": False,
                "installed_by_id": False,
                "installed_by_workspace": False,
                "workspace": desired_workspace,
                "desired_workspace": desired_workspace,
                "workspace_exists": True,
                "desired_name": desired_name,
                "desired_openclaw_id": desired_openclaw_id,
                "dependencies": dependencies,
                "missing_dependencies": missing_dependencies,
                "reason": "workspace_dir_exists_without_agent",
                "message": "目标 workspace 目录已存在，但 openclaw.json 中没有当前 Agent，无法确认目录归属，请先人工检查。",
            }
            result["user_prompt"] = build_user_prompt(result)
            return result

        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "NOT_INSTALLED",
            "installed": False,
            "installed_by_id": False,
            "installed_by_workspace": False,
            "workspace": desired_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": False,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "message": "Agent 尚未安装，可以开始安装。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    current_workspace = current_entry.get("workspace", desired_workspace)
    current_workspace_exists = workspace_exists(current_workspace)
    current_openclaw_id = current_entry.get("id")
    if desired_openclaw_id != current_openclaw_id:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_openclaw_id,
            "workspace": current_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": current_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "agent_dir": current_entry.get("agentDir"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "openclaw_id_mismatch",
            "message": "当前已安装 Agent 的 openclaw id 与本次确认值不一致，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if current_workspace != desired_workspace:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_openclaw_id,
            "workspace": current_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": current_workspace_exists,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "agent_dir": current_entry.get("agentDir"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "workspace_mismatch",
            "message": "当前 Agent 的 workspace 与配置文件不一致，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    if not current_workspace_exists:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_openclaw_id,
            "workspace": current_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": False,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "agent_dir": current_entry.get("agentDir"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "workspace_missing",
            "message": "当前 Agent 的 workspace 目录不存在，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    current_name, current_identity_name = current_agent_names(current_entry)
    if desired_name and current_identity_name and current_identity_name != desired_name:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_openclaw_id,
            "workspace": current_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": True,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "current_name": current_name,
            "current_identity_name": current_identity_name,
            "agent_dir": current_entry.get("agentDir"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "identity_name_mismatch",
            "message": "当前 Agent 的 identity.name 与本次确认名称不一致，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    desired_top_level_name = normalized_name(desired_entry.get("name"))
    if desired_top_level_name and current_name and current_name != desired_top_level_name:
        result = {
            "agent_id": agent_id,
            "target_version": agent_def["version"],
            "status": "CONFIG_ERROR",
            "installed": True,
            "installed_by_id": installed_by_id,
            "installed_by_workspace": installed_by_workspace,
            "current_openclaw_id": current_openclaw_id,
            "workspace": current_workspace,
            "desired_workspace": desired_workspace,
            "workspace_exists": True,
            "desired_name": desired_name,
            "desired_openclaw_id": desired_openclaw_id,
            "current_name": current_name,
            "current_identity_name": current_identity_name,
            "agent_dir": current_entry.get("agentDir"),
            "dependencies": dependencies,
            "missing_dependencies": missing_dependencies,
            "reason": "name_mismatch",
            "message": "当前 Agent 的 name 与本次确认名称不一致，请先人工检查配置。",
        }
        result["user_prompt"] = build_user_prompt(result)
        return result

    installed_version, version_source = detect_installed_version(config_path, agent_id, current_entry)
    target_version = agent_def["version"]

    if not installed_version:
        status = "CONFIG_ERROR"
        message = "无法判断当前已安装 Agent 的版本，请先人工检查配置。"
        reason = "installed_version_unknown"
    else:
        current_parsed = parse_version(str(installed_version))
        target_parsed = parse_version(str(target_version))
        if current_parsed and target_parsed:
            if current_parsed < target_parsed:
                status = "UPDATABLE"
                message = "检测到可用更新。更新前会先备份当前 Agent 配置，再执行更新；如果你对原 Agent 做过修改，需要手动同步相关配置。"
                reason = None
            elif current_parsed == target_parsed:
                status = "SAME_VERSION_REINSTALL"
                message = "当前已安装版本与下载版本一致，本次操作将重置 Agent 配置。继续前必须强提醒并先备份。"
                reason = None
            else:
                status = "CONFIG_ERROR"
                message = "当前已安装版本高于下载版本，请先人工确认是否允许回退。"
                reason = "installed_version_newer_than_target"
        elif str(installed_version) == str(target_version):
            status = "SAME_VERSION_REINSTALL"
            message = "当前已安装版本与下载版本一致，本次操作将重置 Agent 配置。继续前必须强提醒并先备份。"
            reason = None
        else:
            status = "CONFIG_ERROR"
            message = "无法可靠比较当前版本与目标版本，请先人工检查配置。"
            reason = "installed_version_compare_failed"

    result = {
        "agent_id": agent_id,
        "target_version": target_version,
        "installed_version": installed_version,
        "status": status,
        "installed": True,
        "installed_by_id": installed_by_id,
        "installed_by_workspace": installed_by_workspace,
        "current_openclaw_id": current_openclaw_id,
        "workspace": current_workspace,
        "desired_workspace": desired_workspace,
        "workspace_exists": True,
        "desired_name": desired_name,
        "desired_openclaw_id": desired_openclaw_id,
        "current_name": current_name,
        "current_identity_name": current_identity_name,
        "agent_dir": current_entry.get("agentDir"),
        "version_source": version_source,
        "dependencies": dependencies,
        "missing_dependencies": missing_dependencies,
        "message": message,
    }
    if reason:
        result["reason"] = reason
    result["user_prompt"] = build_user_prompt(result)
    return result


def main() -> int:
    parser = argparse.ArgumentParser(description="检测 Agent 安装状态")
    parser.add_argument("--agent-id", required=True, help="Agent ID")
    parser.add_argument("--source-path", help="Agent 下载目录（sophhub agent download 的 --path）")
    parser.add_argument("--openclaw-id", help="目标 openclaw id（resolve_install_params 与流程确认结果）")
    parser.add_argument("--workspace", help="目标 workspace（流程确认结果）")
    parser.add_argument("--name", help="显示名称 agent_name（流程确认结果）")
    parser.add_argument(
        "--config",
        default=str(default_openclaw_config_path()),
        help="openclaw.json 路径",
    )
    args = parser.parse_args()

    result = detect_status(
        args.agent_id,
        Path(args.config).expanduser().resolve(),
        source_path=Path(args.source_path).expanduser().resolve() if args.source_path else None,
        openclaw_id_override=args.openclaw_id,
        workspace_override=args.workspace,
        name_override=args.name,
    )
    json.dump(result, sys.stdout, indent=2, ensure_ascii=False)
    sys.stdout.write("\n")
    return 0


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