from __future__ import annotations

from uuid import uuid4

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import List, Optional, Dict, Any
from Copilot.numericLayer.Core.SignalInsight import SignalInsight, SignalStatus
from Copilot.dataAcquisition.Core.CollectedData import MachineRef , ParameterRef
from Copilot.SituationLayer.Core.machineParameterSnapshot import MachineParameterSnapshot
from Copilot.SituationLayer.Core.parmsHistory import ParameterHistory
from Copilot.SituationLayer.Core.IncidentEvents import IncidentEvents


class IncidentSeverity(str, Enum):
    HIGH = "high"
    MEDIUM = "medium"
    LOW = "low"


@dataclass
class IncidentRef:

    incident_type: IncidentEvents
    severity: IncidentSeverity

    machine: MachineRef
    trigger_parameter: ParameterRef

    trigger_value: float
    trigger_timestamp: datetime
    trigger_rules: List[str] = field(default_factory=list)

    summary: str = ""
    active_signals: List[SignalInsight] = field(default_factory=list)
    machine_snapshot: List["MachineParameterSnapshot"] = field(default_factory=list)

    metadata: Dict[str, Any] = field(default_factory=dict)

    parameter_histories: List[ParameterHistory] = field(default_factory=list)
    id: str = field(default_factory=lambda: str(uuid4()))

    def to_dict(self) -> dict:
        return {
            "id": self.id,

            "incident_type": self.incident_type,
            "severity": self.severity,

            "machine": self.machine.to_dict(),
            "trigger_parameter": self.trigger_parameter.to_dict(),

            "trigger_value": self.trigger_value,
            "trigger_timestamp": self.trigger_timestamp.isoformat(),

            "trigger_rules": self.trigger_rules,

            "summary": self.summary,

            "active_signals": [
                s.to_dict()
                for s in self.active_signals
            ],

            "machine_snapshot": [
                s.to_dict()
                for s in self.machine_snapshot
            ],

            "metadata": self.metadata,

            "parameter_histories": [
                h.to_dict()
                for h in self.parameter_histories
            ],
        }

    @classmethod
    def from_dict(cls, data: dict) -> "IncidentRef":

        return cls(

            id=data.get("id", str(uuid4())),

            incident_type=data["incident_type"],
            severity=data["severity"],

            machine=MachineRef.from_dict(
                data["machine"]
            ),

            trigger_parameter=ParameterRef.from_dict(
                data["trigger_parameter"]
            ),

            trigger_value=data["trigger_value"],

            trigger_timestamp=datetime.fromisoformat(
                data["trigger_timestamp"]
            ),

            trigger_rules=data.get("trigger_rules", []),

            summary=data.get("summary", ""),

            active_signals=[
                SignalInsight.from_dict(s)
                for s in data.get("active_signals", [])
            ],

            machine_snapshot=[
                MachineParameterSnapshot.from_dict(s)
                for s in data.get("machine_snapshot", [])
            ],

            metadata=data.get("metadata", {}),

            parameter_histories=[
                ParameterHistory.from_dict(h)
                for h in data.get("parameter_histories", [])
            ],
        )



@dataclass
class IncidentSignalGroup:
    started_at: datetime
    last_signal_at: datetime
    signals: List[SignalInsight] = field(default_factory=list)

    def add(self, signal: SignalInsight) -> None:
        self.signals.append(signal)
        if signal.timestamp > self.last_signal_at:
            self.last_signal_at = signal.timestamp

    def to_dict(self) -> Dict[str, Any]:
        return {
            "started_at": self.started_at.isoformat(),
            "last_signal_at": self.last_signal_at.isoformat(),
            "signals": [s.to_dict() for s in self.signals],
        }

    @classmethod
    def from_dict(cls, data: Dict[str, Any]) -> "IncidentSignalGroup":
        return cls(
            started_at=datetime.fromisoformat(data["started_at"]),
            last_signal_at=datetime.fromisoformat(data["last_signal_at"]),
            signals=[SignalInsight.from_dict(s) for s in data.get("signals", [])],
        )
