from __future__ import annotations

from typing import Literal

from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator


class OEEInput(BaseModel):
    model_config = ConfigDict(extra="forbid")

    tiempo_turno_min: float = Field(..., gt=0)
    paradas_planificadas_min: float = Field(default=0, ge=0)
    paradas_no_planificadas_min: float = Field(default=0, ge=0)
    produccion_total: float = Field(..., gt=0)
    produccion_buena: float = Field(..., ge=0)
    ciclo_ideal_seg: float = Field(..., gt=0)
    unidad_produccion: str = Field(default="unidades", min_length=1, max_length=40)

    @field_validator("unidad_produccion")
    @classmethod
    def normalize_unit(cls, value: str) -> str:
        normalized = value.strip()
        return normalized or "unidades"

    @model_validator(mode="after")
    def validate_consistency(self) -> "OEEInput":
        tiempo_planificado = self.tiempo_turno_min - self.paradas_planificadas_min
        if tiempo_planificado <= 0:
            raise ValueError("Las paradas planificadas deben ser menores que el tiempo de turno.")

        tiempo_operativo = tiempo_planificado - self.paradas_no_planificadas_min
        if tiempo_operativo <= 0:
            raise ValueError("Las paradas no planificadas deben ser menores que el tiempo planificado.")

        if self.produccion_buena > self.produccion_total:
            raise ValueError("La produccion buena no puede ser mayor que la produccion total.")

        return self


class OEEResult(BaseModel):
    entrada: OEEInput
    tiempo_planificado_min: float
    tiempo_operativo_min: float
    produccion_teorica: float
    disponibilidad: float
    rendimiento: float
    calidad: float
    oee: float
    cuello_botella: Literal["disponibilidad", "rendimiento", "calidad"]
    clasificacion: str
    nivel_color: Literal["excelente", "advertencia", "bajo", "critico"]
    advertencias: list[str] = Field(default_factory=list)
    recomendaciones: list[str] = Field(default_factory=list)


class OEECaseExtraction(BaseModel):
    model_config = ConfigDict(extra="ignore")

    estado: Literal["completo", "incompleto", "inconsistente"] = "incompleto"
    confianza: float = Field(default=0.0, ge=0, le=1)
    tiempo_turno_min: float | None = None
    paradas_planificadas_min: float | None = None
    paradas_no_planificadas_min: float | None = None
    produccion_total: float | None = None
    produccion_buena: float | None = None
    ciclo_ideal_seg: float | None = None
    unidad_produccion: str | None = None
    faltantes: list[str] = Field(default_factory=list)
    advertencias: list[str] = Field(default_factory=list)
    supuestos: list[str] = Field(default_factory=list)


class InterpretationRequest(BaseModel):
    text: str = Field(..., min_length=3)


class AudioTranscriptionResponse(BaseModel):
    text: str


class OEEInterpretationResponse(BaseModel):
    texto: str
    extraccion: OEECaseExtraction
    calculable: bool
    entrada: OEEInput | None = None
    resultado: OEEResult | None = None
