import { Protocol } from "src/entities/WSProtocol";
import GlobalData from "src/common/GlobalData";
import { Common } from "./Common";
import EventBus, { EventNamesDefine } from "./EventBus";
import OptionsType from "./OptionsType";
import { Cookies } from "quasar";
import { EDeviceAttribute } from "src/entities/EDeviceAttribute";

export default class Initializer {
  private options: OptionsType;
  constructor(options: OptionsType) {
    this.options = options;
  }

  private async getSignalSources() {
    const global_data = GlobalData.getInstance();
    return (await global_data
      .getCurrentClient()
      ?.getSignalSources()) as Protocol.GetSignalSourcesResponse;
  }

  private async getModes() {
    const global_data = GlobalData.getInstance();
    return (await global_data
      .getCurrentClient()
      ?.getModes()) as Protocol.GetModesResponseEntity;
  }

  private async getPlans() {
    const global_data = GlobalData.getInstance();
    return (await global_data
      .getCurrentClient()
      ?.getPlans()) as Protocol.GetPlansResponseEntity;
  }

  private async getPollings() {
    const global_data = GlobalData.getInstance();
    return (await global_data
      .getCurrentClient()
      ?.getPollings()) as Protocol.GetPollingsResponseEntity;
  }

  private async initSignalSourceTree() {
    const options = this.options;
    const $store = options?.$store;
    if ($store) {
      try {
        let response = await this.getSignalSources();
        if (response) {
          $store.commit("buildSignalSourceTree", { options, response });
          $store.commit("setArrayValue", {
            name: "signal_sources",
            value: response.signal_sources,
          });
          GlobalData.getInstance().signal_source = response.signal_sources;
          GlobalData.getInstance().signal_source_groups =
            response.signal_source_groups;
        }
      } catch (e) {
        console.error(e);
      }
    }
  }

  private async initModeTree() {
    const options = this.options;
    const $store = options.$store;

    if ($store) {
      try {
        let response = await this.getModes();
        if (response) {
          $store.commit("buildModeTree", { options, response });
          $store.commit("setArrayValue", {
            name: "modes",
            value: response.modes,
          });

          GlobalData.getInstance().modes = response.modes;
          GlobalData.getInstance().mode_groups = response.mode_groups;
        }
      } catch (e) {
        console.error(e);
      }
    }
  }

  private async initPlanTree() {
    const options = this.options;
    const $store = options.$store;
    if ($store) {
      try {
        let response = await this.getPlans();
        if (response) {
          $store.commit("buildPlanTree", { options, response });
          $store.commit("setArrayValue", {
            name: "plans",
            value: response.plans,
          });
          GlobalData.getInstance().plans = response.plans;
          GlobalData.getInstance().plan_groups = response.plan_groups;
        }
      } catch (e) {
        console.error(e);
      }
    }
  }

  private async initPollingTree() {
    const options = this.options;
    const $store = options.$store;
    if ($store) {
      try {
        let response = await this.getPollings();
        if (response) {
          $store.commit("buildPollingTree", { options, response });
          $store.commit("setArrayValue", {
            name: "pollings",
            value: response.pollings,
          });
          GlobalData.getInstance().pollings = response.pollings;
        }
      } catch (e) {
        console.error(e);
      }
    }
  }

  private async getApplicationConfig() {
    const global_data = GlobalData.getInstance();
    global_data.applicationConfig = (
      await global_data.getCurrentClient()?.getApplicationSettins()
    )?.config;

    const options = this.options;
    let $store = options.$store;
    if (global_data.applicationConfig && $store) {
      $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
      );
    }
  }

  private async getWindows() {
    const options = this.options;
    const global_data = GlobalData.getInstance();
    let windows = (await global_data.getCurrentClient()?.getWindows())?.windows;
    let $store = options.$store;
    if (windows && $store) {
      $store.commit("clearWindows");
      setTimeout(() => {
        $store.commit("setWindows", []);
        setTimeout(() => {
          $store.commit("setWindows", windows);
        }, 300);
      }, 300);
    }
  }

  private async getCurrentRunningPlan() {
    const plan_response = await GlobalData.getInstance()
      .getCurrentClient()
      ?.getCurrentRunningPlan();
    if (plan_response && plan_response.running && plan_response.plan) {
      const packet = new Protocol.PacketEntity();
      packet.flag = Protocol.PacketEntity.FLAG_NOTIFY;
      packet.command = Protocol.Commands.kCurrentRunningPlanStateChanged;
      EventBus.getInstance().emit(EventNamesDefine.NotifyMessage, {
        packet,
        data: JSON.stringify(plan_response),
      });
    }
  }

  async initialize() {
    const options = this.options;
    const $store = options.$store;
    const global_data = GlobalData.getInstance();
    let client = global_data.getCurrentClient();
    if (client) {
      while (!client.is_login) {
        await Common.waitFor(100);
      }

      await this.getApplicationConfig();

      // get device attribute
      {
        GlobalData.getInstance()
          .getCurrentClient()
          ?.getDeviceAttribute()
          .then((response) => {
            if (response && typeof response.attribute != "undefined") {
              $store.commit("setDeviceAttribute", response.attribute);
              if (response.attribute & EDeviceAttribute.CustomISV) {
                let language = Cookies.get("language");
                if (!language) {
                  language = "zh-CN";
                }

                if (language != "en-US") {
                  Cookies.set("language", "en-US", {
                    expires: 365,
                  });
                  window.location.reload();
                }
              }
            }
          });
      }

      // get power state
      {
        GlobalData.getInstance()
          .getCurrentClient()
          ?.getPowerState()
          .then((response) => {
            if (response) {
              $store.commit("setPowerState", response.is_power_on);
            }
          });
      }

      this.initSignalSourceTree();
      this.initModeTree();
      this.initPlanTree();
      this.initPollingTree();
      this.getCurrentRunningPlan();
      this.getWindows();

      const support_resolutions = await GlobalData.getInstance()
        .getCurrentClient()
        ?.getSupportResolutions();
      if (support_resolutions) {
        this.options.$store.commit(
          "setDeviceScreenWidth",
          support_resolutions.screen_width
        );
        this.options.$store.commit(
          "setDeviceScreenHeight",
          support_resolutions.screen_height
        );
        this.options.$store.commit(
          "setDeviceScreenRefreshRate",
          support_resolutions.screen_refresh_rate
        );
      }
    }
  }
}
