"""Module 3 — complaints and status workflow."""
from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field

from app.models.enums import ComplaintPriority, ComplaintStatus, ComplaintType
from app.schemas.auth import UserBrief
from app.schemas.customer import ConnectionWithCustomer
from app.schemas.types import BDPhone, DhakaDateTime, TrimmedStr


class ComplaintCreate(BaseModel):
    #: The name of whoever is complaining, as given — not necessarily a system customer.
    customer_name: TrimmedStr = Field(min_length=1, max_length=120)
    #: Customer ID as typed or picked from suggestions. Optional free text.
    customer_ref: TrimmedStr | None = Field(None, max_length=80)
    #: Optional link to a connection. A ticket taken over the phone may have none.
    connection_id: int | None = None
    complaint_type: ComplaintType
    description: TrimmedStr = Field(min_length=5)
    priority: ComplaintPriority = ComplaintPriority.MEDIUM
    contact_phone: BDPhone = None
    address: TrimmedStr | None = None
    assigned_technician_id: int | None = None
    #: Back-date a call that was taken before it reached the system. Never in the future.
    reported_at: datetime | None = None


class ComplaintUpdate(BaseModel):
    """PATCH semantics. Status moves via the status endpoint, not here."""

    customer_name: TrimmedStr | None = Field(None, min_length=1, max_length=120)
    customer_ref: TrimmedStr | None = Field(None, max_length=80)

    complaint_type: ComplaintType | None = None
    description: TrimmedStr | None = Field(None, min_length=5)
    priority: ComplaintPriority | None = None
    contact_phone: BDPhone = None
    address: TrimmedStr | None = None
    assigned_technician_id: int | None = None


class ComplaintStatusChange(BaseModel):
    status: ComplaintStatus
    remarks: str | None = None
    #: Required when moving to `resolved` (or closing a ticket that was never resolved).
    resolution_notes: str | None = None


class ComplaintAssign(BaseModel):
    """Quick reassignment from the list view, without touching anything else."""

    assigned_technician_id: int | None
    remarks: str | None = None


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

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


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

    id: int
    ticket_no: str
    complaint_type: ComplaintType
    priority: ComplaintPriority
    status: ComplaintStatus
    description: str
    connection: ConnectionWithCustomer | None = None
    customer_name: str | None
    customer_ref: str | None
    technician: UserBrief | None
    contact_phone: str | None
    address: str | None
    #: Billing-panel POP for the linked `customer_ref` (cust_id/username match),
    #: if the ticket was logged from a billing lookup. Never edited directly.
    pop_name: str | None = None
    reported_at: DhakaDateTime
    resolved_at: DhakaDateTime | None
    created_at: DhakaDateTime


class ComplaintDetail(ComplaintListItem):
    resolution_notes: str | None
    closed_at: DhakaDateTime | None
    created_by: UserBrief | None
    updated_at: DhakaDateTime
    status_history: list[ComplaintHistoryOut]
    #: Statuses this ticket may move to next, so the UI can build its buttons.
    allowed_transitions: list[ComplaintStatus] = []


class ComplaintStatusCount(BaseModel):
    status: ComplaintStatus
    count: int


class ComplaintSummary(BaseModel):
    """Headline numbers for the module header and the dashboard."""

    total: int
    open: int
    in_progress: int
    unassigned: int
    reported_today: int
    resolved_today: int
