"""
Gitea domain models.

These models represent the core entities in Gitea and provide a clean interface
independent of the underlying API representation.
"""

from dataclasses import dataclass
from datetime import datetime
from enum import Enum
from typing import List, Optional, Dict, Any


class ProjectState(Enum):
    """Standard project states using labels."""
    TODO = "status:todo"
    ACTIVE = "status:active"
    REVIEW = "status:review"
    DONE = "status:done"
    BLOCKED = "status:blocked"


class Priority(Enum):
    """Priority levels using labels."""
    LOW = "priority:low"
    MEDIUM = "priority:medium"
    HIGH = "priority:high"
    CRITICAL = "priority:critical"


@dataclass
class Label:
    """Represents a Gitea issue label."""
    id: int
    name: str
    color: str
    description: str = ""


@dataclass
class User:
    """Represents a Gitea user."""
    id: int
    login: str
    full_name: str = ""
    email: str = ""
    avatar_url: str = ""


@dataclass
class Milestone:
    """Represents a Gitea milestone (used as projects)."""
    id: int
    title: str
    description: str
    state: str  # 'open' or 'closed'
    open_issues: int
    closed_issues: int
    due_on: Optional[str] = None
    created_at: Optional[datetime] = None
    updated_at: Optional[datetime] = None


@dataclass
class Issue:
    """Represents a Gitea issue."""
    number: int
    title: str
    body: str
    state: str  # 'open' or 'closed'
    created_at: datetime
    updated_at: datetime
    html_url: str
    assignee: Optional[User] = None
    labels: List[Label] = None
    milestone: Optional[Milestone] = None

    def __post_init__(self):
        if self.labels is None:
            self.labels = []

    @property
    def priority(self) -> Optional[str]:
        """Get issue priority from labels."""
        for label in self.labels:
            if label.name.startswith('priority:'):
                return label.name.replace('priority:', '')
        return None

    @property
    def status(self) -> Optional[str]:
        """Get issue status from labels."""
        for label in self.labels:
            if label.name.startswith('status:'):
                return label.name.replace('status:', '')
        return None

    def has_label(self, label_name: str) -> bool:
        """Check if issue has a specific label."""
        return any(label.name == label_name for label in self.labels)

    def has_priority(self, priority: Priority) -> bool:
        """Check if issue has a specific priority."""
        return self.has_label(priority.value)

    def has_status(self, status: ProjectState) -> bool:
        """Check if issue has a specific status."""
        return self.has_label(status.value)


@dataclass
class IssueCreateData:
    """Data for creating a new issue."""
    title: str
    body: str = ""
    assignees: List[str] = None
    milestone: Optional[int] = None
    labels: List[str] = None

    def __post_init__(self):
        if self.assignees is None:
            self.assignees = []
        if self.labels is None:
            self.labels = []


@dataclass
class IssueUpdateData:
    """Data for updating an existing issue."""
    title: Optional[str] = None
    body: Optional[str] = None
    state: Optional[str] = None
    assignees: Optional[List[str]] = None
    milestone: Optional[int] = None
    labels: Optional[List[str]] = None


@dataclass
class MilestoneCreateData:
    """Data for creating a new milestone."""
    title: str
    description: str = ""
    due_on: Optional[str] = None


@dataclass
class LabelCreateData:
    """Data for creating a new label."""
    name: str
    color: str
    description: str = ""