"""Sidecar MCP registration in ~/.claude.json (global)."""
import json
from pathlib import Path


def _global_claude_json() -> Path:
    """Return path to ~/.claude.json."""
    return Path.home() / ".claude.json"


class MCPMixin:
    """Register/unregister sidecar MCP server in global ~/.claude.json."""

    def register_mcp(self) -> bool:
        """Register the sidecar MCP server in ~/.claude.json. Returns True if added."""
        path = _global_claude_json()
        data: dict = {}
        if path.exists():
            try:
                data = json.loads(path.read_text(encoding="utf-8"))
            except Exception:
                pass

        servers = data.get("mcpServers", {})
        if "sidecar" in servers:
            return False

        servers["sidecar"] = {
            "command": "python",
            "args": ["-m", "cmdop_claude.sidecar.server"],
        }
        data["mcpServers"] = servers
        path.write_text(json.dumps(data, indent=2), encoding="utf-8")
        return True

    def unregister_mcp(self) -> bool:
        """Remove the sidecar MCP server from ~/.claude.json. Returns True if removed."""
        path = _global_claude_json()
        if not path.exists():
            return False

        try:
            data = json.loads(path.read_text(encoding="utf-8"))
        except Exception:
            return False

        servers = data.get("mcpServers", {})
        if "sidecar" not in servers:
            return False

        del servers["sidecar"]
        data["mcpServers"] = servers
        path.write_text(json.dumps(data, indent=2), encoding="utf-8")
        return True

    def setup_project_hooks(self) -> list[str]:
        """Create .claude/settings.json with hooks in the current project.

        Returns list of what was set up. Skips if settings.json already exists.
        """
        settings_path = self._claude_dir / "settings.json"
        created: list[str] = []

        if settings_path.exists():
            # Merge hooks into existing settings
            try:
                data = json.loads(settings_path.read_text(encoding="utf-8"))
            except Exception:
                data = {}
        else:
            data = {}
            self._claude_dir.mkdir(parents=True, exist_ok=True)

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

        # PostToolUse: map-update on Write|Edit
        post_hooks = hooks.get("PostToolUse", [])
        has_map = any("map-update" in (h.get("command", "") if isinstance(h, dict) else "") for h in post_hooks)
        if not has_map:
            post_hooks.append({
                "matcher": "Write|Edit",
                "command": "python -m cmdop_claude.sidecar.hook map-update",
            })
            hooks["PostToolUse"] = post_hooks
            created.append("PostToolUse → map-update")
            changed = True

        # UserPromptSubmit: inject-tasks
        user_hooks = hooks.get("UserPromptSubmit", [])
        has_inject = any("inject-tasks" in (h.get("command", "") if isinstance(h, dict) else "") for h in user_hooks)
        if not has_inject:
            user_hooks.append({
                "command": "python -m cmdop_claude.sidecar.hook inject-tasks",
            })
            hooks["UserPromptSubmit"] = user_hooks
            created.append("UserPromptSubmit → inject-tasks")
            changed = True

        # plansDirectory: store plans in project, not ~/.claude/plans/
        if "plansDirectory" not in data:
            data["plansDirectory"] = ".claude/plans"
            created.append("plansDirectory → .claude/plans")
            changed = True

        if changed:
            data["hooks"] = hooks
            settings_path.write_text(json.dumps(data, indent=2), encoding="utf-8")

        # Create plans directory
        plans_dir = self._claude_dir / "plans"
        if not plans_dir.exists():
            plans_dir.mkdir(parents=True, exist_ok=True)

        return created

    def is_mcp_registered(self) -> bool:
        """Check if the sidecar MCP server is in ~/.claude.json."""
        path = _global_claude_json()
        if not path.exists():
            return False
        try:
            data = json.loads(path.read_text(encoding="utf-8"))
            return "sidecar" in data.get("mcpServers", {})
        except Exception:
            return False
