"""Repository-related schemas."""

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

from pydantic import BaseModel, ConfigDict, Field


class BasicReviewOutput(BaseModel):
    """Basic review output structure with general comments.

    This class is used for simple reviews that do not require file-specific comments.

    Exemple usage:
        - Used by guardrail agent to provide general feedback on the code changes.
        - Used to add LGTM comments without file-specific context.
    """

    model_config = ConfigDict(extra="forbid")

    body: Annotated[str, Field(description="General review comments/body")]


class MergeRequest(BaseModel):
    """
    Core MergeRequest model used throughout the workflow.
    Platform-specific models convert to this base model.
    """

    id: Annotated[str, Field(description="Unique identifier for the merge request")]
    repo: Annotated[str, Field(description="Repository identifier (format depends on platform)")]
    title: Annotated[str, Field(description="Title of the merge request")]
    description: Annotated[str, Field(description="Description/body of the merge request")]
    source_branch: Annotated[str, Field(description="Source branch name")]
    target_branch: Annotated[str, Field(description="Target branch name")]
    head_sha: Annotated[str, Field(description="HEAD commit SHA")]
    base_sha: Annotated[str | None, Field(description="Base commit SHA (for GitLab)")] = None
    diffs: Annotated[str, Field(description="Raw diff string (unified diff format)")]


class DiscussionItemType(str, Enum):
    """Discussion item type."""

    COMMENT = "comment"
    THREAD = "thread"


class DiscussionNote(BaseModel):
    """A single note within a discussion thread."""

    body: Annotated[str, Field(description="Note body/content")]
    updated_at: Annotated[datetime, Field(description="When this note was last updated")]


class DiscussionItem(BaseModel):
    """
    A discussion item (either a standalone comment or a thread).
    Platform-agnostic representation of discussions/comments.
    """

    type: Annotated[DiscussionItemType, Field(description="Type of discussion item")]
    body: Annotated[
        str | None, Field(default=None, description="Comment body (for COMMENT type)")
    ] = None
    notes: Annotated[
        list[DiscussionNote] | None,
        Field(default=None, description="All notes in the thread (for THREAD type)"),
    ] = None
    updated_at: Annotated[
        datetime | None, Field(default=None, description="When the item was last updated")
    ] = None

    def get_updated_at(self) -> datetime:
        """Get the updated_at timestamp for sorting."""
        if self.updated_at is not None:
            return self.updated_at
        raise ValueError("DiscussionItem must have updated_at")
