"""Pydantic schemas for SPC statistics responses."""
from datetime import datetime
from typing import Optional

from pydantic import BaseModel, Field


class StatisticsQuery(BaseModel):
    """Common query parameters for statistics endpoints."""
    recipe_id: int
    version_id: Optional[int] = None
    subtask_id: Optional[int] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    operator_id: Optional[int] = None
    lot_number: Optional[str] = None
    serial_number: Optional[str] = None


class ControlChartData(BaseModel):
    """Data for X-bar/R control chart."""
    values: list[float]
    timestamps: list[datetime]
    mean: float
    ucl: float  # Upper Control Limit
    lcl: float  # Lower Control Limit
    utl: Optional[float] = None
    uwl: Optional[float] = None
    lwl: Optional[float] = None
    ltl: Optional[float] = None
    nominal: Optional[float] = None
    out_of_control: list[int] = []  # Indices of OOC points


class HistogramData(BaseModel):
    """Data for histogram with normal curve."""
    bins: list[float]
    counts: list[int]
    normal_x: list[float]
    normal_y: list[float]
    mean: float
    std_dev: float
    n: int


class CapabilityData(BaseModel):
    """Capability indices."""
    cp: Optional[float] = None
    cpk: Optional[float] = None
    pp: Optional[float] = None
    ppk: Optional[float] = None
    mean: float
    std_dev: float
    n: int
    utl: Optional[float] = None
    ltl: Optional[float] = None
    nominal: Optional[float] = None


class TrendData(BaseModel):
    """Temporal trend data for capability indices."""
    dates: list[datetime]
    cpk_values: list[Optional[float]]
    ppk_values: list[Optional[float]]
    n_per_period: list[int]


class SummaryData(BaseModel):
    """Pass/fail/warning summary counts."""
    total: int
    pass_count: int
    warning_count: int
    fail_count: int
    pass_rate: float
    warning_rate: float
    fail_rate: float


class AlertData(BaseModel):
    """Western Electric rules violations."""
    rule: str
    description: str
    points: list[int]  # Indices of violating points
    severity: str = Field(..., pattern="^(info|warning|critical)$")


class StatisticsResponse(BaseModel):
    """Combined statistics response."""
    summary: SummaryData
    capability: Optional[CapabilityData] = None
    control_chart: Optional[ControlChartData] = None
    histogram: Optional[HistogramData] = None
    trend: Optional[TrendData] = None
    alerts: list[AlertData] = []
