"""Report response shapes.

Trend points are deliberately flat and uniform — one `bucket` key plus integer series —
because every chart in the UI reads them the same way and recharts wants plain rows.
"""
from datetime import date

from pydantic import BaseModel

from app.models.enums import (
    ApplicationStatus,
    ComplaintPriority,
    ComplaintStatus,
    ComplaintType,
    DistributionStatus,
    EquipmentCondition,
)
from app.schemas.equipment import StockByType
from app.schemas.types import DhakaDateTime

# --- dashboard ---


class ApplicationSnapshot(BaseModel):
    created_today: int
    installed_today: int
    pending: int
    in_survey: int
    #: Approved but not yet installed — the install queue.
    pending_installs: int
    total: int


class ComplaintSnapshot(BaseModel):
    open: int
    in_progress: int
    unassigned: int
    reported_today: int
    resolved_today: int


class EquipmentSnapshot(BaseModel):
    in_stock: int
    issued_out: int
    quarantined: int
    overdue_returns: int
    types_below_reorder: int
    issued_today: int
    collected_today: int


class DashboardOut(BaseModel):
    """The auto-refreshing snapshot.

    `generated_at` is what the UI shows as "updated HH:MM" — without it a polling screen
    cannot tell a fresh response from a cached one.
    """

    generated_at: DhakaDateTime
    #: The Asia/Dhaka day every "today" figure above was counted against.
    day: date
    applications: ApplicationSnapshot
    complaints: ComplaintSnapshot
    equipment: EquipmentSnapshot
    active_connections: int
    stock_by_type: list[StockByType]


# --- trends ---


class ApplicationTrendPoint(BaseModel):
    bucket: date
    created: int
    installed: int
    rejected: int


class ComplaintTrendPoint(BaseModel):
    bucket: date
    reported: int
    resolved: int


class StockMovementPoint(BaseModel):
    bucket: date
    inbound: int
    issued: int
    returned: int
    adjusted: int
    written_off: int
    #: Signed against on-hand stock, so this is the number that reconciles.
    net: int


# --- tabular reports ---


class ApplicationReportRow(BaseModel):
    application_no: str
    created_at: DhakaDateTime
    applicant_name: str
    phone: str
    address: str
    area: str
    status: ApplicationStatus
    requested_date: date
    technician: str | None
    installed_at: DhakaDateTime | None


class ComplaintReportRow(BaseModel):
    ticket_no: str
    reported_at: DhakaDateTime
    customer_code: str
    customer: str
    connection_code: str
    area: str | None
    complaint_type: ComplaintType
    priority: ComplaintPriority
    status: ComplaintStatus
    technician: str | None
    resolved_at: DhakaDateTime | None
    description: str


class EquipmentReportRow(BaseModel):
    #: "Issued" or "Returned" — the two sides of a loan, interleaved by time.
    movement: str
    at: DhakaDateTime
    equipment_type: str
    serial_number: str | None
    quantity: int
    counterparty: str | None
    expected_return_date: date | None
    condition_on_return: EquipmentCondition | None
    status: DistributionStatus | None
    by: str | None


class CombinedReportRow(BaseModel):
    bucket: date
    applications_created: int
    applications_installed: int
    applications_rejected: int
    complaints_reported: int
    complaints_resolved: int
    equipment_issued: int
    equipment_returned: int
