from src.uml.request_generator import Request


class UMLCreator:
    def __init__(self, request_generator: Request, path_to_save: str):
        self._request_generator = request_generator
        self.path_to_save = path_to_save


    def _build_data(self):
        real_data = []
        ideal_data = []
        if not self.theor_mode:
           
            for key, items in self.timings_dict.items():
                if key == 'closure': ideal_time = self._ideal_time[0]
                elif key == 'compression': ideal_time = self._ideal_time[1]
                elif key == 'welding': ideal_time = self.WeldTime
                elif key == 'opening': ideal_time = self._ideal_time[2]
                
                for item in items:
                    real_data.append([item[0]*self.scaler+0.0001, str(key) + '#green'])
                    real_data.append([item[1]*self.scaler, '{-}'])
                    
                    if key == 'compression':
                        ideal_data.append([(item[1]-ideal_time)*self.scaler, str(key) + '#yellow'])
                        ideal_data.append([(item[1]-0.0001)*self.scaler, '{-}'])
                    else:
                        ideal_data.append([item[0]*self.scaler+0.0001, str(key) + '#yellow'])
                        ideal_data.append([(item[0]+ideal_time)*self.scaler, '{-}'])
                        if key == 'opening':
                            ideal_data.append([item[1]*self.scaler+0.0001, 'coming #yellow'])
                            ideal_data.append([(item[1]+self._ideal_time[3])*self.scaler, '{-}'])

        else: 
            real_data = []
            ideal_data = [
                [0.0, 'closure #yellow'],
                [self._ideal_time[0] * self.scaler, '{-}'],
                [(self._ideal_time[0] + 0.0001) * self.scaler, 'compression #yellow'],
                [sum(self._ideal_time[:2]) * self.scaler, '{-}'],
                [(sum(self._ideal_time[:2])+ 0.0001) * self.scaler, 'welding #yellow'],
                [(sum(self._ideal_time[:2]) + self.WeldTime)*self.scaler, '{-}'],
                [(sum(self._ideal_time[:2]) + 0.0001 + self.WeldTime) * self.scaler, 'opening #yellow'],
                [(sum(self._ideal_time[:3]) + self.WeldTime) * self.scaler, 'coming #yellow'],
                [(sum(self._ideal_time[:4]) + self.WeldTime) * self.scaler, '{-}'],
            ]

        client_data = [
            [0.0 * self.scaler, 'closure'],
            [0.165 * self.scaler, '{-}'],
            [0.166 * self.scaler, 'compression'],
            [0.176 * self.scaler, '{-}'],
            [0.180*self.scaler, 'welding'],
            [0.200*self.scaler, '{-}'],
            [0.210 * self.scaler, 'opening'],
            [0.300 * self.scaler, '{-}'],
        ]

        
        return real_data, client_data, ideal_data, self.bool_dict

    def _generate_svg(self, real_data, client_data, ideal_data, bool_data) -> None:
        
        self._request_generator.clear()
        self._request_generator.appendStr('scale 25 as 50 pixels')
        
        if not self.theor_mode:
            self._request_generator.addLineStyle('biba', 'red', 2)

            for i, [signal, changes] in enumerate(bool_data.items()):
                name = 'bool_' + str(i)
                times = []
                for f in changes:
                    times.append([str(float(f[0])*self.scaler), f[1]])
                self._request_generator.addBinary(name, str(signal), 'biba')
                self._request_generator.setTimestamps(name, times)

            self._request_generator.addConcise('RD', 'Real data')
            self._request_generator.setTimestamps('RD', real_data)
        else: self.name = self.path_to_save + '/Ideal'

        self._request_generator.addConcise('CD', 'Client data')
        self._request_generator.setTimestamps('CD', client_data)
        self._request_generator.addConcise('ID', 'Ideal data')
        self._request_generator.setTimestamps('ID', ideal_data)
        try:    
            self._request_generator.generateSVG(self.name)
        except Exception as e:
            print(f"SVG generate error: {e}")

    def update_uml(self, 
                 operator_config: dict,
                 system_config : dict,
                 ideal_time: list[float],
                 bool_dict: dict,
                 float_dict: dict,
                 timings_dict: dict,
                 mode: bool,
                 name:str):
        
        self._ideal_time = ideal_time
        self.bool_dict = bool_dict
        self.float_dict = float_dict
        self.timings_dict = timings_dict
        self.theor_mode = mode
        self.name = name
        self.scaler = int(system_config['UML_time_scaler'])
        self.WeldTime = operator_config['time_wielding']
        
        real, client, ideal, bool_ = self._build_data()
        self._generate_svg(real, client, ideal, bool_)
