"""Task model representing a development task to execute."""

from dataclasses import dataclass, field
from typing import Any


@dataclass
class TaskHooks:
    """Hooks that run before and after a task."""

    pre_task: list[str] = field(default_factory=list)
    post_task: list[str] = field(default_factory=list)

    @classmethod
    def from_dict(cls, data: dict[str, Any] | None) -> "TaskHooks":
        """Create TaskHooks from a dictionary.

        Args:
            data: Dictionary containing hook definitions.

        Returns:
            TaskHooks instance.
        """
        if data is None:
            return cls()
        return cls(
            pre_task=data.get("pre_task", []),
            post_task=data.get("post_task", []),
        )

    def to_dict(self) -> dict[str, list[str]]:
        """Convert to dictionary representation.

        Returns:
            Dictionary with pre_task and post_task lists.
        """
        return {
            "pre_task": self.pre_task,
            "post_task": self.post_task,
        }


@dataclass
class Task:
    """A development task to be executed by Claude Code.

    Attributes:
        id: Unique task identifier (e.g., TASK-001).
        title: Short task title.
        description: Detailed task description.
        context: Project context and existing code references.
        acceptance_criteria: List of criteria to verify completion.
        depends_on: List of task IDs that must complete first.
        hooks: Task-specific hooks to run before/after execution.
    """

    id: str
    title: str
    description: str
    context: str
    acceptance_criteria: list[str]
    depends_on: list[str] = field(default_factory=list)
    hooks: TaskHooks = field(default_factory=TaskHooks)

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> "Task":
        """Create a Task from a dictionary.

        Args:
            data: Dictionary containing task data.

        Returns:
            Task instance.

        Raises:
            ValueError: If required fields are missing.
        """
        required_fields = ["id", "title", "description", "context", "acceptance_criteria"]
        for field_name in required_fields:
            if field_name not in data:
                raise ValueError(f"Missing required field: {field_name}")

        return cls(
            id=data["id"],
            title=data["title"],
            description=data["description"],
            context=data["context"],
            acceptance_criteria=data["acceptance_criteria"],
            depends_on=data.get("depends_on", []),
            hooks=TaskHooks.from_dict(data.get("hooks")),
        )

    def to_dict(self) -> dict[str, Any]:
        """Convert to dictionary representation.

        Returns:
            Dictionary containing all task data.
        """
        result: dict[str, Any] = {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "context": self.context,
            "acceptance_criteria": self.acceptance_criteria,
        }
        if self.depends_on:
            result["depends_on"] = self.depends_on
        if self.hooks.pre_task or self.hooks.post_task:
            result["hooks"] = self.hooks.to_dict()
        return result

    def slugify_title(self) -> str:
        """Create a URL-safe slug from the title.

        Returns:
            Slugified title suitable for branch names.
        """
        # Convert to lowercase and replace spaces with hyphens
        slug = self.title.lower().replace(" ", "-")
        # Remove non-alphanumeric characters except hyphens
        slug = "".join(c for c in slug if c.isalnum() or c == "-")
        # Remove consecutive hyphens
        while "--" in slug:
            slug = slug.replace("--", "-")
        # Remove leading/trailing hyphens
        slug = slug.strip("-")
        # Truncate to reasonable length
        return slug[:50]

    def get_branch_name(self) -> str:
        """Generate a git branch name for this task.

        Returns:
            Branch name in format: messirve/{task-id}-{slugified-title}
        """
        return f"messirve/{self.id}-{self.slugify_title()}"
