"""Issue-related schemas."""

from datetime import datetime
from enum import Enum
from typing import Annotated

from pydantic import AliasChoices, BaseModel, ConfigDict, Field, field_validator


class Issue(BaseModel):
    """Platform-agnostic issue representation."""

    id: Annotated[str, Field(description="Issue ID")]
    number: Annotated[int, Field(description="Issue number")]
    title: Annotated[str, Field(description="Issue title")]
    description: Annotated[str | None, Field(description="Issue description/body")] = ""

    @field_validator("description", mode="before")
    @classmethod
    def coerce_none_description(cls, v: str | None) -> str:
        return v or ""

    state: Annotated[str, Field(description="Issue state (open, closed, etc.)")]
    labels: Annotated[list[str], Field(description="Issue labels")]
    created_at: Annotated[datetime, Field(description="When the issue was created")]
    updated_at: Annotated[datetime, Field(description="When the issue was last updated")]
    web_url: Annotated[
        str,
        Field(
            description="Web URL to view the issue",
            validation_alias=AliasChoices("html_url", "web_url"),
        ),
    ]


class IssueComment(BaseModel):
    """A single comment on an issue."""

    id: Annotated[str, Field(description="Comment ID")]
    author: Annotated[str, Field(description="Comment author username")]
    body: Annotated[str, Field(description="Comment body text")]
    created_at: Annotated[datetime, Field(description="When the comment was created")]
    updated_at: Annotated[datetime, Field(description="When the comment was last updated")]


class LinkedIssueRelation(str, Enum):
    """Types of issue relationships."""

    CLOSES = "closes"  # PR closes this issue
    REFERENCES = "references"  # Just mentioned/referenced
    PARENT = "parent"  # Epic/parent issue
    CHILD = "child"  # Sub-issue/child
    RELATED = "related"  # Generic relationship


class LinkedIssue(BaseModel):
    """An issue linked to the MR or another issue."""

    issue: Annotated[Issue, Field(description="The linked issue")]
    relation: Annotated[LinkedIssueRelation, Field(description="Type of relationship")]
    source: Annotated[
        str,
        Field(description="Where this link was discovered (mr_description, api, issue_body)"),
    ]


class IssueWithContext(BaseModel):
    """Issue with full context including comments and relationships."""

    issue: Annotated[Issue, Field(description="The issue")]
    comments: Annotated[
        list[IssueComment], Field(default_factory=list, description="Issue comments")
    ]
    linked_issues: Annotated[
        list[LinkedIssue], Field(default_factory=list, description="Linked issues")
    ]
    task_list_items: Annotated[
        list[str],
        Field(default_factory=list, description="Parsed markdown task list items"),
    ]
    is_epic: Annotated[
        bool, Field(default=False, description="Whether this is an epic/parent issue")
    ]


class IssueSummary(BaseModel):
    """Summarized issue context for downstream agents.

    Note: Full Issue objects are returned separately in IssueAnalysis.issues.
    This schema only contains the summarized/extracted information.
    """

    model_config = ConfigDict(extra="forbid")

    acceptance_criteria: Annotated[
        list[str],
        Field(default_factory=list, description="Extracted acceptance criteria"),
    ]
    key_requirements: Annotated[
        list[str],
        Field(default_factory=list, description="Main requirements identified"),
    ]
    discussion_highlights: Annotated[
        list[str],
        Field(default_factory=list, description="Important points from comments"),
    ]
    unresolved_questions: Annotated[
        list[str], Field(default_factory=list, description="Open questions found")
    ]
    related_context: Annotated[
        str, Field(default="", description="Brief summary of related issues")
    ]
