"""Cursor IDE adapter for Portal external integrations."""

from __future__ import annotations

import json
import subprocess
from typing import TYPE_CHECKING, Any

from portal.infrastructure.editors.base_editor_adapter import BaseEditorAdapter
from portal.interfaces.cli.utils.input_validator import InputValidator

if TYPE_CHECKING:
    from pathlib import Path

    from portal.core.domain.models.color import WorktreeColor
    from portal.core.services.color_theme_service import ColorThemeService


class CursorAdapter(BaseEditorAdapter):
    """Adapter for Cursor IDE integration."""

    def __init__(self, color_theme_service: ColorThemeService) -> None:
        """Initialize Cursor adapter with color theme service."""
        super().__init__(color_theme_service)

    def is_available(self) -> bool:
        """Check if Cursor is installed."""
        try:
            result = subprocess.run(["which", "cursor"], capture_output=True, text=True)
            return result.returncode == 0
        except Exception:
            return False

    async def open_worktree(self, worktree_path: Path) -> bool:
        """Open worktree in Cursor with security validation."""
        if not self.is_available():
            return False

        # Validate path for security
        try:
            path_str = str(worktree_path.resolve())
            if not InputValidator.validate_path_safety(path_str):
                return False
        except Exception:
            return False

        success, _ = await self._safe_subprocess_run(["cursor", path_str])
        return success

    async def configure_workspace_colors(self, worktree_path: Path, color: WorktreeColor) -> bool:
        """Configure Cursor workspace with color theme."""
        # Cursor uses the same .vscode/settings.json as VS Code
        vscode_dir = worktree_path / ".vscode"

        try:
            vscode_dir.mkdir(exist_ok=True)
        except Exception:
            return False

        settings_file = vscode_dir / "settings.json"

        # Load existing settings
        if settings_file.exists():
            try:
                with open(settings_file) as f:
                    settings = json.load(f)
            except (json.JSONDecodeError, OSError):
                settings = {}
        else:
            settings = {}

        # Apply comprehensive color customizations using theme service
        theme = self._color_theme_service.generate_cursor_theme(color)
        settings["workbench.colorCustomizations"] = theme["workbench.colorCustomizations"]

        # Add Portal metadata
        settings["portal"] = {
            "worktree": worktree_path.name,
            "color": color.name,
            "colorHex": color.hex,
        }

        # Save settings
        try:
            with open(settings_file, "w") as f:
                json.dump(settings, f, indent=2)
            return True
        except Exception:
            return False

    async def create_workspace(self, worktree_path: Path, project_name: str) -> bool:
        """Create Cursor workspace file."""

        workspace_file = worktree_path / f"{project_name}.cursor-workspace"

        workspace = {
            "folders": [{"path": ".", "name": worktree_path.name}],
            "settings": {},
            "extensions": {"recommendations": []},
        }

        try:
            with open(workspace_file, "w") as f:
                json.dump(workspace, f, indent=2)
            return True
        except Exception:
            return False

    def get_status(self) -> dict[str, Any]:
        """Get Cursor integration status."""
        return {
            "available": self.is_available(),
            "name": "Cursor",
            "version": self._get_cursor_version(),
            "features": {
                "workspace_colors": self.is_available(),
                "auto_open": self.is_available(),
                "workspace_files": self.is_available(),
            },
        }

    def _get_cursor_version(self) -> str:
        """Get Cursor version if available."""
        if not self.is_available():
            return "Not available"

        try:
            result = subprocess.run(
                ["cursor", "--version"], capture_output=True, text=True, timeout=5
            )
            if result.returncode == 0:
                return result.stdout.strip().split("\n")[0]
        except Exception:
            pass

        return "Unknown"
