"""Service protocols for dependency injection."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Protocol

if TYPE_CHECKING:
    from pathlib import Path

    from portal.core.domain.models import BaseResult, DataResult
    from portal.core.domain.models.config import PortalConfig
    from portal.core.domain.models.template import WorktreeTemplate
    from portal.core.domain.value_objects import BranchName


class WorktreeServiceProtocol(Protocol):
    """Protocol for worktree operations."""

    async def create_worktree(
        self, branch_name: BranchName | str, base_branch: str = "main"
    ) -> DataResult[Any]:
        """Create a new worktree.

        Args:
            branch_name: Name of the branch for the worktree
            base_branch: Base branch to create from (default: "main")

        Returns:
            DataResult with success status, worktree info, and any errors
        """
        ...

    async def delete_worktree(self, worktree_id: str, force: bool = False) -> BaseResult:
        """Delete a worktree with safety checks.

        Args:
            worktree_id: Unique identifier of the worktree
            force: Force deletion even if worktree has uncommitted changes

        Returns:
            BaseResult with success status and any errors
        """
        ...

    async def list_worktrees(self) -> DataResult[list[Any]]:
        """List all worktrees.

        Returns:
            DataResult containing list of worktree objects
        """
        ...

    async def switch_worktree(self, worktree_id: str) -> BaseResult:
        """Switch to a different worktree.

        Args:
            worktree_id: Unique identifier of the worktree to switch to

        Returns:
            BaseResult with success status and any errors
        """
        ...


class ConfigServiceProtocol(Protocol):
    """Protocol for configuration management."""

    async def get_config(self, project_path: Path | None = None) -> PortalConfig:
        """Get merged configuration."""
        ...

    async def update_global_config(self, updates: dict[str, Any]) -> PortalConfig:
        """Update global configuration."""
        ...

    async def get_template(self, template_name: str) -> WorktreeTemplate | None:
        """Get a worktree template by name."""
        ...

    async def list_templates(self) -> list[str]:
        """List available template names."""
        ...

    def get_worktree_base_dir(self, project_name: str) -> Path:
        """Get the base directory for worktrees."""
        ...

    def get_editor_command(self, worktree_path: Path) -> str:
        """Get the command to open editor for a worktree."""
        ...


class HookServiceProtocol(Protocol):
    """Protocol for hook system operations."""

    async def execute_hooks(
        self,
        stage: Any,  # HookStage
        context: dict[str, Any],
    ) -> Any:  # HookResult
        """Execute hooks for a given stage.

        Args:
            stage: Hook stage being executed
            context: Context data for hook execution

        Returns:
            HookResult with execution details
        """
        ...


class ColorServiceProtocol(Protocol):
    """Protocol for color coding operations."""

    async def assign_color(self, worktree_id: str) -> DataResult[Any]:
        """Assign a color to a worktree.

        Args:
            worktree_id: Unique identifier of the worktree

        Returns:
            DataResult containing color object
        """
        ...

    async def get_color(self, worktree_id: str) -> DataResult[Any]:
        """Get the color assigned to a worktree.

        Args:
            worktree_id: Unique identifier of the worktree

        Returns:
            DataResult containing color object or None
        """
        ...


class YamlConfigRepositoryProtocol(Protocol):
    """Protocol for YAML configuration repository."""

    async def load_config(self, project_path: Path | None = None) -> PortalConfig:
        """Load merged configuration from all sources."""
        ...

    async def save_global_config(self, config: PortalConfig) -> None:
        """Save global configuration."""
        ...

    async def save_project_config(self, project_path: Path, config: dict[str, Any]) -> None:
        """Save project-specific configuration."""
        ...

    async def load_template(self, template_name: str) -> WorktreeTemplate | None:
        """Load a worktree template."""
        ...

    async def list_templates(self) -> list[str]:
        """List available template names."""
        ...


class GitRepositoryProtocol(Protocol):
    """Protocol for git repository operations."""

    async def create_worktree(
        self, path: str, branch: str, base_branch: str = "main"
    ) -> DataResult[Any]:
        """Create a git worktree.

        Args:
            path: Path where to create the worktree
            branch: Branch name for the worktree
            base_branch: Base branch to create from

        Returns:
            DataResult containing git worktree information
        """
        ...

    async def delete_worktree(self, path: str, force: bool = False) -> BaseResult:
        """Delete a git worktree.

        Args:
            path: Path of the worktree to delete
            force: Force deletion even with uncommitted changes

        Returns:
            BaseResult with success status and any errors
        """
        ...

    async def list_worktrees(self) -> DataResult[list[Any]]:
        """List all git worktrees.

        Returns:
            DataResult containing list of worktree information
        """
        ...
