import uuid
from datetime import datetime

from pydantic import BaseModel, ConfigDict, model_validator

from api.models.intake import IntakeLane, IntakeOutcome, IntakeStatus


class IntakeCreate(BaseModel):
    id: uuid.UUID | None = None
    topic_id: uuid.UUID | None = None
    workplan_id: uuid.UUID | None = None
    repo_id: uuid.UUID | None = None
    title: str
    description: str | None = None
    lane: IntakeLane = IntakeLane.green
    origin: str | None = None
    origin_ref: str | None = None
    source_repo_path: str | None = None

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


class IntakeUpdate(BaseModel):
    title: str | None = None
    description: str | None = None
    lane: IntakeLane | None = None
    status: IntakeStatus | None = None
    origin: str | None = None
    origin_ref: str | None = None
    routed_note: str | None = None


class IntakeRoute(BaseModel):
    """Move an intake from open/vetted into routed — the state that makes
    it eligible for the promotion transition (CUST-WP-0061-T03)."""

    routed_note: str | None = None


class IntakeClose(BaseModel):
    outcome: IntakeOutcome
    promoted_to: str | None = None
    note: str | None = None

    @model_validator(mode="after")
    def promoted_requires_target(self) -> "IntakeClose":
        if self.outcome == IntakeOutcome.promoted and not self.promoted_to:
            raise ValueError("outcome=promoted requires promoted_to")
        return self


class IntakeNoteCreate(BaseModel):
    content: str
    author: str | None = None


class IntakeNoteRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    author: str | None = None
    content: str
    created_at: datetime


class IntakeRead(BaseModel):
    model_config = ConfigDict(from_attributes=True)
    id: uuid.UUID
    topic_id: uuid.UUID | None = None
    workplan_id: uuid.UUID | None = None
    repo_id: uuid.UUID | None = None
    title: str
    description: str | None = None
    lane: IntakeLane
    status: IntakeStatus
    outcome: IntakeOutcome | None = None
    origin: str | None = None
    origin_ref: str | None = None
    promoted_to: str | None = None
    source_repo_path: str | None = None
    routed_note: str | None = None
    closed_at: datetime | None = None
    created_at: datetime
    updated_at: datetime
    notes: list[IntakeNoteRead] = []
