import { Protocol } from "src/entities/WSProtocol";
import { NotifyMessage } from "./ClientConnection";
import EventBus, { EventNamesDefine } from "./EventBus";
import GlobalData from "./GlobalData";
import OptionsType from "./OptionsType";

export default class RemoteDataExangeProcesser {
  private flag = false;
  private options: OptionsType;

  private plan_notify: any = null;

  constructor(options: OptionsType) {
    this.options = options;

    EventBus.getInstance().on(EventNamesDefine.WebSocketClose, () => {
      if (this.plan_notify) {
        this.plan_notify(void 0);
        this.plan_notify = null;
      }
    });
  }

  enable() {
    if (!this.flag) {
      this.registeEvent();
    }
  }

  private registeEvent() {
    EventBus.getInstance().on(EventNamesDefine.NotifyMessage, (notify) =>
      this.onNotifyMessage(notify)
    );
  }

  private onNotifyMessage(notify: NotifyMessage) {
    const $store = this.options.$store;
    const $t = this.options.$t;
    const $q = this.options.$q;

    try {
      switch (notify.packet.command) {
        case Protocol.Commands.kSetApplicationConfig:
          {
            let temp = JSON.parse(
              notify.data
            ) as Protocol.ApplicationConfigChangeNotifyEntity;
            if (temp) {
              let global_data = GlobalData.getInstance();
              if (global_data && global_data.applicationConfig) {
                switch (temp.key) {
                  case "power_state":
                    $store.commit("setPowerState", temp.value == "on");
                    break;
                  case "registered":
                    {
                      global_data.applicationConfig.registered = JSON.parse(
                        temp.value
                      );
                    }
                    break;
                  case "ip_list":
                    global_data.applicationConfig.ip_list = JSON.parse(
                      temp.value
                    );
                    break;
                  default:
                    {
                      (<any>global_data.applicationConfig)[temp.key] =
                        temp.value;
                      $store.commit(
                        "setWallCol",
                        global_data.applicationConfig.wall_col
                      );
                      $store.commit(
                        "setWallRow",
                        global_data.applicationConfig.wall_row
                      );
                      $store.commit(
                        "setPowerOnPlan",
                        global_data.applicationConfig.power_on_plan
                      );
                    }
                    break;
                }
              }
            }
          }
          break;
        case Protocol.Commands.kCurrentRunningPlanStateChanged:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanRunningStateChangeNotifyEntity;
            if (temp && temp.plan) {
              if (temp.running) {
                $store.commit("setCurrentRunningPlan", temp.plan.uuid);
                if (this.plan_notify) {
                  this.plan_notify(void 0);
                  this.plan_notify = null;
                }

                this.plan_notify = $q.notify({
                  position: "center",
                  color: "positive",
                  timeout: 0, // we want to be in control when it gets dismissed
                  spinner: true,
                  message:
                    $t.t("plan") +
                    ":  " +
                    temp.plan.name +
                    "  " +
                    $t.t("running now") +
                    "!",
                });
              } else {
                $store.commit("setCurrentRunningPlan", "");
                if (this.plan_notify) {
                  this.plan_notify(void 0);
                  this.plan_notify = null;
                }
              }
            }
          }
          break;
        case Protocol.Commands.kRpcAddMode:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().modes.push(temp.mode);
              $store.commit("setArrayValue", {
                name: "modes",
                value: GlobalData.getInstance().modes,
              });
              $store.commit("addModeTreeItem", {
                parent: temp.mode.group_uuid,
                is_group: false,
                item_data: temp.mode,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeleteMode:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().modes.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().modes.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "modes",
                value: GlobalData.getInstance().modes,
              });
              $store.commit("deleteModeTreeItem", {
                is_group: false,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditMode:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().modes.findIndex(
                (element) => element && element.uuid == temp.mode.uuid
              );
              let refresh_flag = false;
              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().modes[pos].group_uuid !=
                    temp.mode.group_uuid ||
                  GlobalData.getInstance().modes[pos].joint_action_equipments !=
                    temp.mode.joint_action_equipments;
                GlobalData.getInstance().modes[pos] = temp.mode;
              }
              $store.commit("setArrayValue", {
                name: "modes",
                value: GlobalData.getInstance().modes,
              });

              if (refresh_flag) {
                $store.commit("buildModeTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    mode_groups: GlobalData.getInstance().mode_groups,
                    modes: GlobalData.getInstance().modes,
                  },
                });
              } else {
                $store.commit("setModeTreeItem", {
                  is_group: false,
                  item_data: temp.mode,
                });
              }
            }
          }
          break;
        case Protocol.Commands.kRpcAddModeGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeGroupAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().mode_groups.push(temp.mode_group);
              $store.commit("setArrayValue", {
                name: "mode_groups",
                value: GlobalData.getInstance().mode_groups,
              });

              $store.commit("addModeTreeItem", {
                parent: temp.mode_group.parent_uuid,
                is_group: true,
                item_data: temp.mode_group,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeleteModeGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeGroupDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().mode_groups.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().mode_groups.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "mode_groups",
                value: GlobalData.getInstance().mode_groups,
              });
              $store.commit("deleteModeTreeItem", {
                is_group: true,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditModeGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.ModeGroupEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().mode_groups.findIndex(
                (element) => element && element.uuid == temp.mode_group.uuid
              );

              let refresh_flag = false;
              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().mode_groups[pos].parent_uuid !=
                  temp.mode_group.parent_uuid;

                GlobalData.getInstance().mode_groups[pos] = temp.mode_group;
              }
              $store.commit("setArrayValue", {
                name: "mode_groups",
                value: GlobalData.getInstance().mode_groups,
              });
              if (refresh_flag) {
                $store.commit("buildModeTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    mode_groups: GlobalData.getInstance().mode_groups,
                    modes: GlobalData.getInstance().modes,
                  },
                });
              } else {
                $store.commit("setModeTreeItem", {
                  is_group: true,
                  item_data: temp.mode_group,
                });
              }
            }
          }
          break;
        case Protocol.Commands.kRpcAddPlan:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().plans.push(temp.plan);
              $store.commit("setArrayValue", {
                name: "plans",
                value: GlobalData.getInstance().plans,
              });
              $store.commit("addPlanTreeItem", {
                parent: temp.plan.group_uuid,
                is_group: false,
                item_data: temp.plan,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeletePlan:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().plans.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().plans.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "plans",
                value: GlobalData.getInstance().plans,
              });
              $store.commit("deletePlanTreeItem", {
                is_group: false,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditPlan:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().plans.findIndex(
                (element) => element && element.uuid == temp.plan.uuid
              );
              let refresh_flag = false;
              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().plans[pos].group_uuid !=
                  temp.plan.group_uuid;
                GlobalData.getInstance().plans[pos] = temp.plan;
              }
              $store.commit("setArrayValue", {
                name: "plans",
                value: GlobalData.getInstance().plans,
              });
              if (refresh_flag) {
                $store.commit("buildPlanTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    plan_groups: GlobalData.getInstance().plan_groups,
                    plans: GlobalData.getInstance().plans,
                  },
                });
              } else {
                $store.commit("setPlanTreeItem", {
                  is_group: false,
                  item_data: temp.plan,
                });
              }
            }
          }
          break;
        case Protocol.Commands.kRpcAddPlanGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanGroupAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().plan_groups.push(temp.plan_group);
              $store.commit("setArrayValue", {
                name: "plan_groups",
                value: GlobalData.getInstance().plan_groups,
              });
              $store.commit("addPlanTreeItem", {
                parent: temp.plan_group.parent_uuid,
                is_group: true,
                item_data: temp.plan_group,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeletePlanGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanGroupDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().plan_groups.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().plan_groups.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "plan_groups",
                value: GlobalData.getInstance().plan_groups,
              });
              $store.commit("deletePlanTreeItem", {
                is_group: true,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditPlanGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PlanGroupEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().plan_groups.findIndex(
                (element) => element && element.uuid == temp.plan_group.uuid
              );
              let refresh_flag = false;
              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().plan_groups[pos].parent_uuid !=
                  temp.plan_group.parent_uuid;
                GlobalData.getInstance().plan_groups[pos] = temp.plan_group;
              }
              $store.commit("setArrayValue", {
                name: "plan_groups",
                value: GlobalData.getInstance().plan_groups,
              });
              if (refresh_flag) {
                $store.commit("buildPlanTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    plan_groups: GlobalData.getInstance().plan_groups,
                    plans: GlobalData.getInstance().plans,
                  },
                });
              } else {
                $store.commit("setPlanTreeItem", {
                  is_group: true,
                  item_data: temp.plan_group,
                });
              }
            }
          }
          break;

        case Protocol.Commands.kRpcAddPolling:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().pollings.push(temp.polling);
              $store.commit("setArrayValue", {
                name: "pollings",
                value: GlobalData.getInstance().pollings,
              });
              $store.commit("addPollingTreeItem", {
                parent: temp.polling.group_uuid,
                is_group: false,
                item_data: temp.polling,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeletePolling:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().pollings.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().pollings.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "pollings",
                value: GlobalData.getInstance().pollings,
              });
              $store.commit("deletePollingTreeItem", {
                is_group: false,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditPolling:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().pollings.findIndex(
                (element) => element && element.uuid == temp.polling.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().pollings[pos] = temp.polling;
              }
              $store.commit("setArrayValue", {
                name: "pollings",
                value: GlobalData.getInstance().pollings,
              });
              $store.commit("setPollingTreeItem", {
                is_group: false,
                item_data: temp.polling,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcAddPollingGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingGroupAddNotifyEntity;
            if (temp) {
              $store.commit("addPollingTreeItem", {
                parent: temp.polling_group.parent_uuid,
                is_group: true,
                item_data: temp.polling_group,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeletePollingGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingGroupDeleteNotifyEntity;
            if (temp) {
              $store.commit("deletePollingTreeItem", {
                is_group: true,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditPollingGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.PollingGroupEditNotifyEntity;
            if (temp) {
              $store.commit("setPollingTreeItem", {
                is_group: true,
                item_data: temp.polling_group,
              });
            }
          }
          break;

        case Protocol.Commands.kRpcAddSignalSource:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().signal_source.push(temp.signal_source);
              $store.commit("setArrayValue", {
                name: "signal_sources",
                value: GlobalData.getInstance().signal_source,
              });
              $store.commit("addSignalSourceTreeItem", {
                parent: temp.signal_source.group_uuid,
                is_group: false,
                item_data: temp.signal_source,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeleteSignalSource:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().signal_source.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().signal_source.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "signal_sources",
                value: GlobalData.getInstance().signal_source,
              });
              $store.commit("deleteSignalSourceTreeItem", {
                is_group: false,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditSignalSource:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().signal_source.findIndex(
                (element) => element && element.uuid == temp.signal_source.uuid
              );

              let refresh_flag = false;
              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().signal_source[pos].group_uuid !=
                  temp.signal_source.group_uuid;
                GlobalData.getInstance().signal_source[pos] =
                  temp.signal_source;
              }
              $store.commit("setArrayValue", {
                name: "signal_sources",
                value: GlobalData.getInstance().signal_source,
              });
              if (refresh_flag) {
                $store.commit("buildSignalSourceTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    signal_source_groups:
                      GlobalData.getInstance().signal_source_groups,
                    signal_sources: GlobalData.getInstance().signal_source,
                  },
                });
              } else {
                $store.commit("setSignalSourceTreeItem", {
                  is_group: false,
                  item_data: temp.signal_source,
                });
              }
            }
          }
          break;
        case Protocol.Commands.kRpcAddSignalSourceGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceGroupAddNotifyEntity;
            if (temp) {
              GlobalData.getInstance().signal_source_groups.push(
                temp.signal_source_group
              );
              $store.commit("setArrayValue", {
                name: "signal_source_groups",
                value: GlobalData.getInstance().signal_source_groups,
              });
              $store.commit("addSignalSourceTreeItem", {
                parent: temp.signal_source_group.parent_uuid,
                is_group: true,
                item_data: temp.signal_source_group,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcDeleteSignalSourceGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceGroupDeleteNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().signal_source_groups.findIndex(
                (element) => element && element.uuid == temp.uuid
              );
              if (pos != -1) {
                GlobalData.getInstance().signal_source_groups.splice(pos, 1);
              }
              $store.commit("setArrayValue", {
                name: "signal_source_groups",
                value: GlobalData.getInstance().signal_source_groups,
              });
              $store.commit("deleteSignalSourceTreeItem", {
                is_group: true,
                uuid: temp.uuid,
              });
            }
          }
          break;
        case Protocol.Commands.kRpcEditSignalSourceGroup:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.SignalSourceGroupEditNotifyEntity;
            if (temp) {
              let pos = GlobalData.getInstance().signal_source_groups.findIndex(
                (element) =>
                  element && element.uuid == temp.signal_source_group.uuid
              );

              let refresh_flag = false;

              if (pos != -1) {
                refresh_flag =
                  GlobalData.getInstance().signal_source_groups[pos]
                    .parent_uuid != temp.signal_source_group.parent_uuid;
                GlobalData.getInstance().signal_source_groups[pos] =
                  temp.signal_source_group;
              }
              $store.commit("setArrayValue", {
                name: "signal_source_groups",
                value: GlobalData.getInstance().signal_source_groups,
              });
              if (refresh_flag) {
                $store.commit("buildSignalSourceTree", {
                  options: {
                    $t,
                    $store,
                    $q,
                  },
                  response: {
                    signal_source_groups:
                      GlobalData.getInstance().signal_source_groups,
                    signal_sources: GlobalData.getInstance().signal_source,
                  },
                });
              } else {
                $store.commit("setSignalSourceTreeItem", {
                  is_group: true,
                  item_data: temp.signal_source_group,
                });
              }
            }
          }
          break;
        case Protocol.Commands.kFanTemperature:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.FanTemperatureNotifyEntity;
            if (temp) {
              $store.commit("setFanTemp", temp.fan_temp);
            }
          }
          break;
        case Protocol.Commands.kDesktopResolutionChangedNotify:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.DesktopResolutionChangedNotifyEntity;
            if (temp) {
              $store.commit("setDeviceScreenConnectState", true);
              $store.commit("setDeviceScreenWidth", temp.width);
              $store.commit("setDeviceScreenHeight", temp.height);
              $store.commit("setDeviceScreenRefreshRate", temp.refresh_rate);
            }
          }
          break;
        case Protocol.Commands.kDesktopDisconnectNotify:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.DesktopDisconnectNotifyEntity;
            if (temp) {
              $store.commit("setDeviceScreenConnectState", false);
            }
          }
          break;
        case Protocol.Commands.kSetDeviceAttribute: {
          const temp = JSON.parse(
            notify.data
          ) as Protocol.SetDeviceAttributeNotifyEntity;
          if (temp) {
            $store.commit("setDeviceAttribute", temp.attribute);
          }
        }
        case Protocol.Commands.kWindowPropertyValueChanged:
          {
            const temp = JSON.parse(
              notify.data
            ) as Protocol.WindowPropertyValueChangeNotifyEntity;
            if (temp) {
              const window = $store.state.windows.find(
                (element) => element && element.window_id == temp.window_id
              );
              if (window) {
                if (temp.name == "polling_uuid") {
                  $store.commit("setWindowProperty", {
                    window,
                    property_name: temp.name,
                    value: temp.value,
                  });
                } else {
                  console.error(
                    "kWindowPropertyValueChanged: name:" +
                      temp.name +
                      " .not support, value:" +
                      temp.value
                  );
                }
              }
            }
          }
          break;
      }
    } catch {}
  }

  private unRegisteEvents() {
    EventBus.getInstance().off(
      EventNamesDefine.NotifyMessage,
      this.onNotifyMessage
    );
  }

  disable() {
    if (this.flag) {
      this.unRegisteEvents();
    }
  }
}
