"""
Repository interfaces for issue domain.

Defines contracts for data access without infrastructure dependencies.
"""

from abc import ABC, abstractmethod
from typing import List, Optional, Dict, Any
from .models import Issue


class IssueRepository(ABC):
    """Repository interface for issue persistence."""

    @abstractmethod
    async def get_issue(self, issue_number: int) -> Issue:
        """Retrieve issue by number.

        Args:
            issue_number: The issue number to retrieve

        Returns:
            Issue domain object

        Raises:
            IssueNotFoundError: If issue doesn't exist
        """
        pass

    @abstractmethod
    async def list_issues(self, state: Optional[str] = None, limit: Optional[int] = None) -> List[Issue]:
        """List issues, optionally filtered by state.

        Args:
            state: Optional state filter (open, closed)
            limit: Optional limit on number of results

        Returns:
            List of Issue domain objects
        """
        pass

    @abstractmethod
    async def save_issue(self, issue: Issue) -> None:
        """Save issue changes.

        Args:
            issue: Issue domain object to save
        """
        pass

    @abstractmethod
    async def create_issue(self, title: str, description: str, labels: List[str]) -> Issue:
        """Create a new issue.

        Args:
            title: Issue title
            description: Issue description
            labels: List of label names

        Returns:
            Created Issue domain object
        """
        pass

    @abstractmethod
    async def delete_issue(self, issue_number: int) -> None:
        """Delete an issue.

        Args:
            issue_number: The issue number to delete
        """
        pass


class ProjectRepository(ABC):
    """Repository interface for project information."""

    @abstractmethod
    async def get_issue_project_info(self, issue_number: int) -> Dict[str, Any]:
        """Get project information for an issue.

        Args:
            issue_number: The issue number

        Returns:
            Dictionary containing project context information
        """
        pass

    @abstractmethod
    async def get_kanban_columns(self) -> List[str]:
        """Get available kanban columns for the project.

        Returns:
            List of kanban column names
        """
        pass

    @abstractmethod
    async def get_project_labels(self) -> List[Dict[str, Any]]:
        """Get available labels for the project.

        Returns:
            List of label definitions
        """
        pass

    @abstractmethod
    async def get_milestones(self) -> List[Dict[str, Any]]:
        """Get available milestones for the project.

        Returns:
            List of milestone information
        """
        pass