"""Acceptance Criteria models for PRD validation."""

from __future__ import annotations

from pydantic import BaseModel, Field


class AcceptanceCriterion(BaseModel):
    """Single acceptance criterion in Given/When/Then format."""

    ac_id: str = Field(..., description="Unique identifier (e.g., AC-001)")
    title: str = Field(..., description="Short descriptive title")
    given: str = Field(..., description="Precondition state")
    when: str = Field(..., description="Action or trigger")
    then_clause: str = Field(..., description="Expected result or outcome")
    and_clauses: list[str] = Field(
        default_factory=list, description="Additional assertions (optional)"
    )

    def to_markdown(self) -> str:
        """Convert to markdown format.

        Example:
            AC-001: User can log in
            Given: A registered user with valid credentials
            When: The user submits the login form
            Then: The user is redirected to the dashboard
            And: A success message is displayed
            And: The session token is set
        """
        lines = [
            f"{self.ac_id}: {self.title}",
            f"Given: {self.given}",
            f"When: {self.when}",
            f"Then: {self.then_clause}",
        ]
        for and_clause in self.and_clauses:
            lines.append(f"And: {and_clause}")
        return "\n".join(lines)


class AcceptanceCriteriaSection(BaseModel):
    """Collection of acceptance criteria for a PRD."""

    criteria: list[AcceptanceCriterion] = Field(default_factory=list)

    def to_markdown(self) -> str:
        """Convert all criteria to markdown format."""
        if not self.criteria:
            return ""

        lines = ["## Acceptance Criteria", ""]
        for criterion in self.criteria:
            lines.append(criterion.to_markdown())
            lines.append("")  # Blank line between criteria
        return "\n".join(lines)

    def validate_not_empty(self) -> bool:
        """Validate that at least one acceptance criterion exists."""
        return len(self.criteria) > 0
