from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field
from datetime import datetime

from Copilot.numericLayer.Core.SignalInsight import SignalInsight, SignalStatus
from Copilot.SituationLayer.Core.parmsHistory import ParameterHistory
from Copilot.SituationLayer.Core.Incident import IncidentSignalGroup


@dataclass
class MachineSituationState:
    machine_id: int

    latest_signals_insight: Dict[str, SignalInsight] = field(default_factory=dict)
    active_alerts: Dict[str, SignalInsight] = field(default_factory=dict)

    open_group: Optional[IncidentSignalGroup] = None
    pending_groups: List[IncidentSignalGroup] = field(default_factory=list)

    last_emitted_incident_by_type: Dict[str, datetime] = field(default_factory=dict)


    history_by_parameter: Dict[str, ParameterHistory] = field(
        default_factory=dict
    )


    # -------------------------
    # Serialization
    # -------------------------
    def to_dict(self) -> Dict[str, Any]:
        return {
            "machine_id": self.machine_id,

            "latest_signals_insight": {
                k: v.to_dict() for k, v in self.latest_signals_insight.items()
            },

            "active_alerts": {
                k: v.to_dict() for k, v in self.active_alerts.items()
            },

            "open_group": self.open_group.to_dict() if self.open_group else None,

            "pending_groups": [
                g.to_dict() for g in self.pending_groups
            ],

            "last_emitted_incident_by_type": {
                k: v.isoformat()
                for k, v in self.last_emitted_incident_by_type.items()
            },

            "history_by_parameter": {
                k: v.to_dict() for k, v in self.history_by_parameter.items()
            },
        }

    # -------------------------
    # Deserialization
    # -------------------------
    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "MachineSituationState":
        return cls(
            machine_id=data["machine_id"],

            latest_signals_insight={
                k: SignalInsight.from_dict(v)
                for k, v in data.get("latest_signals_insight", {}).items()
            },

            active_alerts={
                k: SignalInsight.from_dict(v)
                for k, v in data.get("active_alerts", {}).items()
            },

            open_group=IncidentSignalGroup.from_dict(data["open_group"])
            if data.get("open_group") else None,

            pending_groups=[
                IncidentSignalGroup.from_dict(g)
                for g in data.get("pending_groups", [])
            ],

            last_emitted_incident_by_type={
                k: datetime.fromisoformat(v)
                for k, v in data.get("last_emitted_incident_by_type", {}).items()
            },

            history_by_parameter={
                k: ParameterHistory.from_dict(v)
                for k, v in data.get("history_by_parameter", {}).items()
            },
        )

