from __future__ import annotations

from typing import Any

from pydantic import ValidationError

from app.models import OEEInput


FIELD_LABELS = {
    "tiempo_turno_min": "Tiempo de turno",
    "paradas_planificadas_min": "Paradas planificadas",
    "paradas_no_planificadas_min": "Paradas no planificadas",
    "produccion_total": "Produccion total",
    "produccion_buena": "Produccion buena",
    "ciclo_ideal_seg": "Ciclo ideal",
    "unidad_produccion": "Unidad de produccion",
}


def parse_oee_form(raw: dict[str, Any]) -> OEEInput:
    parsed = {
        "tiempo_turno_min": _parse_float(raw.get("tiempo_turno_min"), "tiempo_turno_min"),
        "paradas_planificadas_min": _parse_float(
            raw.get("paradas_planificadas_min", 0),
            "paradas_planificadas_min",
        ),
        "paradas_no_planificadas_min": _parse_float(
            raw.get("paradas_no_planificadas_min", 0),
            "paradas_no_planificadas_min",
        ),
        "produccion_total": _parse_float(raw.get("produccion_total"), "produccion_total"),
        "produccion_buena": _parse_float(raw.get("produccion_buena"), "produccion_buena"),
        "ciclo_ideal_seg": _parse_float(raw.get("ciclo_ideal_seg"), "ciclo_ideal_seg"),
        "unidad_produccion": _parse_text(raw.get("unidad_produccion", "unidades")),
    }
    return OEEInput.model_validate(parsed)


def validation_messages(exc: ValidationError | ValueError) -> list[str]:
    if isinstance(exc, ValidationError):
        messages: list[str] = []
        for error in exc.errors():
            loc = error.get("loc") or []
            field = str(loc[0]) if loc else ""
            label = FIELD_LABELS.get(field, "Datos")
            msg = str(error.get("msg", "Valor invalido")).replace("Value error, ", "")
            messages.append(f"{label}: {msg}")
        return messages

    return [str(exc)]


def _parse_float(value: Any, field: str) -> float:
    label = FIELD_LABELS.get(field, field)
    if value is None or str(value).strip() == "":
        raise ValueError(f"{label}: el campo es obligatorio.")

    normalized = str(value).strip().replace(",", ".")
    try:
        return float(normalized)
    except ValueError as exc:
        raise ValueError(f"{label}: ingrese un numero valido.") from exc


def _parse_text(value: Any) -> str:
    text = str(value or "").strip()
    return text or "unidades"
