import uuid
from datetime import datetime

from pydantic import BaseModel, ConfigDict, model_validator

from api.models.decision import DecisionStatus, DecisionType
from api.schemas.compat import OptionalWorkplanIdCompatMixin
from pydantic import AliasChoices, Field


class DecisionCreate(BaseModel):
    topic_id: uuid.UUID | None = None
    workplan_id: uuid.UUID | None = Field(
        default=None,
        validation_alias=AliasChoices("workplan_id", "workstream_id"),
    )
    title: str
    description: str | None = None
    decision_type: DecisionType = DecisionType.pending
    status: DecisionStatus = DecisionStatus.open
    rationale: str | None = None
    decided_by: str | None = None
    decided_at: datetime | None = None
    deadline: datetime | None = None
    escalation_note: str | None = None

    @model_validator(mode="after")
    def topic_or_workplan_required(self) -> "DecisionCreate":
        if self.topic_id is None and self.workplan_id is None:
            raise ValueError("At least one of topic_id or workplan_id must be set")
        return self


class DecisionResolve(BaseModel):
    rationale: str
    decided_by: str
    write_log: bool = True  # append to DECISIONS.md in the registered project directory


class DecisionUpdate(BaseModel):
    title: str | None = None
    description: str | None = None
    decision_type: DecisionType | None = None
    status: DecisionStatus | None = None
    rationale: str | None = None
    decided_by: str | None = None
    decided_at: datetime | None = None
    deadline: datetime | None = None
    escalation_note: str | None = None
    superseded_by: uuid.UUID | None = None


class DecisionRead(OptionalWorkplanIdCompatMixin, BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    topic_id: uuid.UUID | None = None
    title: str
    description: str | None = None
    decision_type: DecisionType
    status: DecisionStatus
    rationale: str | None = None
    decided_by: str | None = None
    decided_at: datetime | None = None
    deadline: datetime | None = None
    escalation_note: str | None = None
    superseded_by: uuid.UUID | None = None
    created_at: datetime
    updated_at: datetime