"""Requisition schemas — a purchase order with line items and a status workflow."""
from typing import Annotated

from pydantic import BaseModel, ConfigDict, Field

from app.models.enums import RequisitionStatus
from app.schemas.auth import UserBrief
from app.schemas.types import DhakaDateTime, TrimmedStr


class RequisitionItemIn(BaseModel):
    item_name: TrimmedStr = Field(min_length=1, max_length=200)
    quantity: int = Field(gt=0, le=100_000)
    unit: TrimmedStr = Field(default="pcs", max_length=20)


class RequisitionCreate(BaseModel):
    purpose: TrimmedStr = Field(min_length=3, max_length=1000)
    notes: TrimmedStr | None = None
    items: Annotated[list[RequisitionItemIn], Field(min_length=1, max_length=50)]


class RequisitionUpdate(BaseModel):
    """PATCH semantics. Only a pending order may be edited, and status moves via the
    status endpoint, never here."""

    purpose: TrimmedStr | None = Field(None, min_length=3, max_length=1000)
    notes: TrimmedStr | None = None
    items: Annotated[list[RequisitionItemIn], Field(min_length=1, max_length=50)] | None = None


class RequisitionStatusChange(BaseModel):
    """Admin decides a pending order (approve/reject) or completes an approved one.
    Re-opening a rejected order goes through the same endpoint."""

    status: RequisitionStatus
    #: Required when rejecting — the requester needs to know why.
    remarks: TrimmedStr | None = None


class RequisitionItemOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    item_name: str
    quantity: int
    unit: str


class RequisitionHistoryOut(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: int
    from_status: RequisitionStatus | None
    to_status: RequisitionStatus
    changed_at: DhakaDateTime
    remarks: str | None
    changed_by: UserBrief | None


class RequisitionListItem(BaseModel):
    """Row shape for the list view — items ride along so no second fetch is needed."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    req_no: str
    status: RequisitionStatus
    purpose: str
    items: list[RequisitionItemOut]
    requested_by: UserBrief | None
    requested_at: DhakaDateTime
    approved_by: UserBrief | None
    approved_at: DhakaDateTime | None
    completed_by: UserBrief | None
    completed_at: DhakaDateTime | None
    created_at: DhakaDateTime


class RequisitionDetail(RequisitionListItem):
    notes: str | None
    rejected_by: UserBrief | None
    rejected_at: DhakaDateTime | None
    created_by: UserBrief | None
    updated_at: DhakaDateTime
    status_history: list[RequisitionHistoryOut]
    #: Statuses this order may move to next, so the UI can build its buttons.
    allowed_transitions: list[RequisitionStatus] = []


class RequisitionStatusCount(BaseModel):
    status: RequisitionStatus
    count: int


class RequisitionSummary(BaseModel):
    """Headline numbers for the module header."""

    pending: int
    approved: int
    rejected: int
    completed: int
    requested_today: int
    #: Decided but not yet delivered — the part of the pipeline that is moving.
    total: int
