"""Claude Code 插件安装/卸载

index1 setup        — 安装插件（hooks + MCP 自动注册）
index1 setup --remove — 卸载插件

插件安装后，所有项目的 Claude Code 对话自动触发 index1 认知记录。
_detect_collection() 按 CLAUDE_PROJECT_DIR 自动分 collection。
"""

from __future__ import annotations

import json
import logging
import shutil
from pathlib import Path

logger = logging.getLogger(__name__)

# 插件目录（marketplace 格式）
_MARKETPLACE_DIR = Path.home() / ".claude" / "plugins" / "marketplaces" / "index1-marketplace" / "plugins" / "index1"
_SETTINGS_PATH = Path.home() / ".claude" / "settings.json"

# ── hooks.json 内容 ──

_HOOKS_JSON = {
    "description": "index1 memory system hooks — cognitive fact capture",
    "hooks": {
        "SessionStart": [{
            "matcher": "startup|resume|compact",
            "hooks": [{
                "type": "command",
                "command": "index1 hook",
                "timeout": 60,
            }],
        }],
        "UserPromptSubmit": [{
            "hooks": [{
                "type": "command",
                "command": "index1 hook",
                "timeout": 5,
            }],
        }],
        "PostToolUse": [{
            "matcher": "Bash|Edit|Write|MultiEdit",
            "hooks": [{
                "type": "command",
                "command": "index1 hook",
                "timeout": 30,
            }],
        }],
        "SessionEnd": [{
            "hooks": [{
                "type": "command",
                "command": "index1 hook",
                "timeout": 120,
            }],
        }],
    },
}


def _get_plugin_json() -> dict:
    """plugin.json 元数据"""
    try:
        from . import __version__
        version = __version__
    except Exception:
        version = "0.0.0"

    return {
        "name": "index1",
        "description": "AI memory system — code index + cognitive facts across sessions",
        "version": version,
        "author": {"name": "gladego"},
        "license": "Apache-2.0",
        "keywords": ["memory", "search", "index", "cognitive", "hooks", "mcp"],
    }


def _get_mcp_json() -> dict:
    """.mcp.json — MCP server 配置"""
    return {
        "mcpServers": {
            "index1": {
                "type": "stdio",
                "command": "index1",
                "args": ["serve"],
            },
        },
    }


def _write_json(path: Path, data: dict) -> None:
    path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n")


# ── 安装 ──


def install_plugin() -> Path:
    """安装 index1 Claude Code 插件

    1. 在 marketplace 目录创建/更新插件文件
    2. 清理 settings.json 中手动添加的 hooks（由插件接管）
    3. 确保 enabledPlugins 中注册

    Returns: 插件目录路径
    Raises: OSError — 磁盘满/权限不足时
    """
    plugin_dir = _MARKETPLACE_DIR

    # 创建目录结构（两个子目录共享 plugin_dir 父级）
    for sub in (".claude-plugin", "hooks"):
        (plugin_dir / sub).mkdir(parents=True, exist_ok=True)

    # 写入文件（OSError 向上传播 — CLI 层处理）
    _write_json(plugin_dir / ".claude-plugin" / "plugin.json", _get_plugin_json())
    _write_json(plugin_dir / "hooks" / "hooks.json", _HOOKS_JSON)
    _write_json(plugin_dir / ".mcp.json", _get_mcp_json())

    # CLAUDE.md
    (plugin_dir / "CLAUDE.md").write_text(
        "# index1 Plugin\n\n"
        "AI memory system for Claude Code — persistent code index + cognitive facts.\n\n"
        "## Hooks\n\n"
        "- **SessionStart**: Inject awakening brief (recent facts + universal knowledge)\n"
        "- **UserPromptSubmit**: Search relevant cognitive context\n"
        "- **PostToolUse**: Extract facts from Bash/Edit/Write tool outputs\n"
        "- **SessionEnd**: Launch maintenance + generate session summary\n\n"
        "## MCP Tools\n\n"
        "| Tool | Description |\n"
        "|------|-------------|\n"
        "| `recall` | Unified search — code + facts + tactics |\n"
        "| `learn` | Record insights/decisions/lessons |\n"
        "| `read` | File content + index metadata |\n"
        "| `status` | System health |\n"
        "| `reindex` | Rebuild index |\n"
        "| `config` | View/modify config |\n"
    )

    # 清理 settings.json 中手动添加的 index1 hooks
    _cleanup_manual_hooks()

    # 确保 enabledPlugins 中注册
    _ensure_enabled()

    return plugin_dir


def uninstall_plugin() -> bool:
    """卸载 index1 Claude Code 插件

    1. 删除 hooks 目录（保留其他插件文件）
    2. 清理 settings.json 中的手动 hooks
    3. 从 enabledPlugins 中移除
    """
    hooks_dir = _MARKETPLACE_DIR / "hooks"
    if hooks_dir.exists():
        shutil.rmtree(hooks_dir)

    _cleanup_manual_hooks()
    _remove_enabled()
    return True


# ── settings.json 操作 ──


def _cleanup_manual_hooks() -> None:
    """移除 settings.json 中手动添加的 index1 hooks"""
    if not _SETTINGS_PATH.exists():
        return

    try:
        with open(_SETTINGS_PATH) as f:
            settings = json.load(f)

        hooks = settings.get("hooks", {})
        changed = False

        for event in list(hooks.keys()):
            configs = hooks[event]
            filtered = [
                c for c in configs
                if not any(
                    "index1 hook" in h.get("command", "")
                    for h in c.get("hooks", [])
                )
            ]
            if len(filtered) != len(configs):
                hooks[event] = filtered
                changed = True
            # 删除空事件
            if not hooks[event]:
                del hooks[event]
                changed = True

        if changed:
            with open(_SETTINGS_PATH, "w") as f:
                json.dump(settings, f, indent=2, ensure_ascii=False)
                f.write("\n")
            logger.info("已清理 settings.json 中的 index1 手动 hooks")
    except (json.JSONDecodeError, OSError) as e:
        logger.debug("清理 settings.json 失败: %s", e)


def _ensure_enabled() -> None:
    """确保 enabledPlugins 中有 index1"""
    if not _SETTINGS_PATH.exists():
        return

    try:
        with open(_SETTINGS_PATH) as f:
            settings = json.load(f)

        plugins = settings.setdefault("enabledPlugins", {})
        key = "index1@index1-marketplace"
        if not plugins.get(key):
            plugins[key] = True
            with open(_SETTINGS_PATH, "w") as f:
                json.dump(settings, f, indent=2, ensure_ascii=False)
                f.write("\n")
    except (json.JSONDecodeError, OSError) as e:
        logger.debug("更新 enabledPlugins 失败: %s", e)


def _remove_enabled() -> None:
    """从 enabledPlugins 中移除 index1"""
    if not _SETTINGS_PATH.exists():
        return

    try:
        with open(_SETTINGS_PATH) as f:
            settings = json.load(f)

        plugins = settings.get("enabledPlugins", {})
        key = "index1@index1-marketplace"
        if key in plugins:
            del plugins[key]
            with open(_SETTINGS_PATH, "w") as f:
                json.dump(settings, f, indent=2, ensure_ascii=False)
                f.write("\n")
    except (json.JSONDecodeError, OSError) as e:
        logger.debug("更新 enabledPlugins 失败: %s", e)


# ── 状态查询 ──


def check_status() -> dict:
    """检查插件安装状态"""
    hooks_json = _MARKETPLACE_DIR / "hooks" / "hooks.json"
    plugin_json = _MARKETPLACE_DIR / ".claude-plugin" / "plugin.json"

    manual_hooks = False
    enabled = False
    try:
        with open(_SETTINGS_PATH) as f:
            settings = json.load(f)
        # 检查 settings.json 中是否有手动 hooks
        for configs in settings.get("hooks", {}).values():
            for c in configs:
                if any("index1 hook" in h.get("command", "") for h in c.get("hooks", [])):
                    manual_hooks = True
                    break
        # 检查 enabledPlugins
        enabled = settings.get("enabledPlugins", {}).get("index1@index1-marketplace", False)
    except (json.JSONDecodeError, OSError):
        pass

    return {
        "plugin_dir": str(_MARKETPLACE_DIR),
        "hooks_json": hooks_json.exists(),
        "plugin_json": plugin_json.exists(),
        "enabled": enabled,
        "manual_hooks": manual_hooks,
    }
