"""Schemas for the unified daily log.

One day, one payload. The screen that uses this is a data-entry desk, not a report, so
it carries three things: what has already been logged today (`counts` + the per-module
lists), what is still waiting to be dealt with (`pending`), and a single chronological
`timeline` so the operator can see the day as it actually happened rather than as four
separate tables.
"""
from datetime import date
from enum import Enum

from pydantic import BaseModel, ConfigDict

from app.schemas.application import ApplicationListItem
from app.schemas.auth import UserBrief
from app.schemas.complaint import ComplaintListItem
from app.schemas.equipment import CollectionOut, DistributionListItem
from app.schemas.types import DhakaDateTime


class DailyLogEventKind(str, Enum):
    """Which module an entry in the timeline came from."""

    APPLICATION = "application"
    COMPLAINT = "complaint"
    EQUIPMENT_ISSUE = "equipment_issue"
    EQUIPMENT_COLLECTION = "equipment_collection"


class DailyLogEvent(BaseModel):
    """One thing that happened, flattened so the feed renders without per-kind lookups."""

    kind: DailyLogEventKind
    at: DhakaDateTime
    #: Id of the record the event belongs to, for deep-linking into its module.
    ref_id: int
    #: Human-facing identifier — application no, ticket no, or the item's serial.
    ref_no: str | None
    title: str
    detail: str | None = None
    #: Present only for status transitions; None on a create or an equipment move.
    from_status: str | None = None
    to_status: str | None = None
    actor: UserBrief | None = None


class DailyLogCounts(BaseModel):
    """What was logged on the day itself."""

    applications_created: int
    applications_installed: int
    complaints_reported: int
    complaints_resolved: int
    equipment_issued: int
    equipment_collected: int

    @property
    def total(self) -> int:
        return (
            self.applications_created
            + self.applications_installed
            + self.complaints_reported
            + self.complaints_resolved
            + self.equipment_issued
            + self.equipment_collected
        )


class DailyLogPending(BaseModel):
    """Live backlog as of right now — deliberately *not* scoped to the selected day.

    A queue is a queue whichever day you are looking at; scoping it to a past date would
    show a number nobody can act on.
    """

    applications_pending: int
    applications_awaiting_install: int
    complaints_open: int
    complaints_unassigned: int
    equipment_overdue_returns: int


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

    day: date
    is_today: bool
    #: True when `mine=true` narrowed everything to the calling user's own entries.
    mine_only: bool
    counts: DailyLogCounts
    pending: DailyLogPending
    timeline: list[DailyLogEvent]
    #: The feed is capped; the counts above stay exact. Shown as a note on the screen
    #: rather than letting a busy day quietly look like a short one.
    timeline_truncated: bool = False
    applications: list[ApplicationListItem]
    complaints: list[ComplaintListItem]
    distributions: list[DistributionListItem]
    collections: list[CollectionOut]
