from flask import current_app

from threading import Lock


from extensions import db
from Copilot.dataAcquisition.Core.BaseSubscriber import BaseSubscriber
from models.factory_structure_model import Parameter, Machine
from Copilot.dataAcquisition.Core.CollectedData import CollectedData, ParameterRef, MachineRef
from Copilot.dataAcquisition.Core.eventBus import  EventBus
from Copilot.SituationLayer.Core.Incident import IncidentRef
from models.incident_model import IncidentModel

class IncidentStore(BaseSubscriber):
    def __init__(self, app=None):

        super().__init__()

        if app is None:
            app =  current_app._get_current_object()
        self.app = app

        self._lock = Lock()

        self.incidents:dict[str, IncidentRef] = {}
    
    def handle(self, event:IncidentRef):
        self.incidents[event.id] = event

        with self.app.app_context():
            incident = IncidentModel(
                id=event.id,
                incident_type = event.incident_type,
                severity = event.severity,
                machine_id = event.machine.id,
                trigger_parameter_id = event.trigger_parameter.id,
                trigger_value = event.trigger_value,
                trigger_timestamp = event.trigger_timestamp,
                summary = event.summary,
                payload = event.to_dict()
            )

            db.session.add(incident)
            db.session.commit()

    def _load_incident_from_db(self,incident_id: str) -> IncidentRef:
        with self.app.app_context():
            incident = db.session.get(IncidentModel, incident_id)

            if not incident:
                print( f"Incident with id {incident_id} not found" )
                return None

            payload = incident.payload

            if not payload:
                raise ValueError(f"Incident payload is empty for id {incident_id}")

            return IncidentRef.from_dict(payload)


    def remove_incident(self, incident_id:str):
        with self._lock:
            self.incidents.pop(incident_id)
    
    

    def load_incident(self, incident_id:str):
        with self._lock:
            incident:IncidentRef = None
            if incident_id in self.incidents:
                incident = self.incidents[incident_id]
            else:
                incident = self._load_incident_from_db(incident_id)
            
            return incident

                