<template>
  <q-dialog persistent v-model="show_dialog" @before-hide="resetData">
    <q-card class="overflow-hidden" style="overflow-y: scroll; max-width: 60vw">
      <q-card-section class="q-ma-none q-pa-sm">
        <div class="row">
          <div class="col-auto text-h6">
            {{ $t("system setting") }}
          </div>
          <q-space />
          <div>
            <q-btn
              :loading="loading"
              flat
              round
              icon="close"
              color="red"
              v-close-popup
            >
              <q-tooltip>
                {{ $t("close") }}
              </q-tooltip>
            </q-btn>
          </div>
        </div>
      </q-card-section>

      <q-separator />

      <q-card-section style="max-height: 75vh; width: 60vw" class="scroll">
        <q-tabs
          v-model="tab"
          dense
          active-color="primary"
          indicator-color="primary"
          align="justify"
          narrow-indicator
          class="bg-grey-2 text-teal"
        >
          <q-tab
            name="network"
            icon="language"
            :label="$t('network setting')"
            :disable="loading"
          />
          <q-tab
            name="graphics"
            icon="picture_in_picture_alt"
            :label="$t('graphics setting')"
            :disable="loading"
          />
          <q-tab
            name="other"
            icon="build"
            :label="$t('other setting')"
            :disable="loading"
          />
        </q-tabs>
        <q-separator />
        <q-tab-panels v-model="tab" animated>
          <q-tab-panel name="network" class="_panel">
            <q-card class="fit">
              <q-card-section>
                <q-form ref="network_form">
                  <q-list>
                    <q-item>
                      <q-item-section avatar class="width_5_1">{{
                        $t("auto ip") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-select
                          v-model="auto_ip"
                          :options="[$t('enable'), $t('disable')]"
                          :loading="loading"
                          :disable="loading"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="auto_ip != $t('enable')">
                      <q-item-section avatar class="width_5_1">{{
                        $t("ip address") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="ip_address"
                          :loading="loading"
                          :disable="loading"
                          maxlength="15"
                          :rules="[
                            (val) =>
                              (val && val.length > 0) ||
                              $t('Please type something'),
                            (val) =>
                              isIpAddress(val) ||
                              $t('Please input vaild ip address'),
                          ]"
                          lazy-rules
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="auto_ip != $t('enable')">
                      <q-item-section avatar class="width_5_1">{{
                        $t("gateway") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          :loading="loading"
                          :disable="loading"
                          v-model="gateway"
                          maxlength="15"
                          :rules="[
                            (val) =>
                              (val && val.length > 0) ||
                              $t('Please type something'),
                            (val) =>
                              isIpAddress(val) ||
                              $t('Please input vaild ip address'),
                          ]"
                          lazy-rules
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="auto_ip != $t('enable')">
                      <q-item-section avatar class="width_5_1">{{
                        $t("netmask") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          :loading="loading"
                          :disable="loading"
                          v-model="netmask"
                          maxlength="15"
                          :rules="[
                            (val) =>
                              (val && val.length > 0) ||
                              $t('Please type something'),
                            (val) =>
                              isIpAddress(val) ||
                              $t('Please input vaild ip address'),
                          ]"
                          lazy-rules
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_1">{{
                        $t("mac address") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="mac_address"
                          :loading="loading"
                          :disable="loading"
                          maxlength="17"
                          :rules="[
                            (val) =>
                              (val && val.length > 0) ||
                              $t('Please type something'),
                            (val) =>
                              isMacAddress(val) ||
                              $t('Please input vaild mac address') +
                                '  (XX:XX:XX:XX:XX:XX)',
                          ]"
                          lazy-rules
                        />
                      </q-item-section>
                    </q-item>
                  </q-list>
                </q-form>
              </q-card-section>
            </q-card>
          </q-tab-panel>

          <q-tab-panel name="graphics" class="_panel">
            <q-card class="fit">
              <q-card-section>
                <q-form ref="graphics_form">
                  <q-list>
                    <q-item>
                      <q-item-section avatar class="width_5_2">{{
                        $t("brightness") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="brightness"
                          :loading="loading"
                          :disable="loading"
                          type="number"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_2">{{
                        $t("contrast") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="contrast"
                          :loading="loading"
                          :disable="loading"
                          type="number"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_2">{{
                        $t("hue") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="hue"
                          :loading="loading"
                          :disable="loading"
                          type="number"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_2_2">{{
                        $t("device resolution") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-select
                          v-model="device_resolution"
                          :loading="loading"
                          :disable="loading"
                          :options="device_resolution_options"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_2_2">{{
                        $t("output board resolution") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-select
                          v-model="output_board_resolution"
                          :loading="loading"
                          :disable="loading"
                          :options="output_board_resolution_options"
                        />
                      </q-item-section>
                    </q-item>
                  </q-list>
                </q-form>
              </q-card-section>
            </q-card>
          </q-tab-panel>

          <q-tab-panel name="other" class="_panel">
            <q-card class="fit">
              <q-card-section>
                <q-form ref="other_form">
                  <q-list>
                    <q-item>
                      <q-item-section avatar class="width_5_3">{{
                        $t("use ntp") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-select
                          v-model="use_ntp"
                          :loading="loading"
                          :disable="loading"
                          :options="[$t('enable'), $t('disable')]"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="use_ntp == $t('enable')">
                      <q-item-section avatar class="width_5_3">{{
                        $t("ntp server") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="ntp_server"
                          :loading="loading"
                          :disable="loading"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="use_ntp == $t('enable')">
                      <q-item-section avatar class="width_5_3">{{
                        $t("ntp sync delay(S)") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="ntp_sync_delay"
                          :loading="loading"
                          :disable="loading"
                          type="number"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item v-if="use_ntp == $t('disable')">
                      <q-item-section avatar class="width_5_3">{{
                        $t("current datetime") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="current_date"
                          :loading="loading"
                          :disable="loading"
                          type="date"
                        />
                      </q-item-section>
                      <q-item-section>
                        <q-input
                          v-model="current_time"
                          :loading="loading"
                          :disable="loading"
                          type="time"
                        />
                      </q-item-section>
                    </q-item>
                    <q-item>
                      <q-item-section avatar class="width_5_3">{{
                        $t("time zone") + ":"
                      }}</q-item-section>
                      <q-item-section>
                        <q-select
                          v-model="time_zone"
                          :loading="loading"
                          :disable="loading"
                          :options="time_zone_options"
                        />
                      </q-item-section>
                    </q-item>
                  </q-list>
                </q-form>
              </q-card-section>
            </q-card>
          </q-tab-panel>
        </q-tab-panels>
      </q-card-section>
      <q-separator />
      <q-card-actions align="right">
        <q-btn
          :loading="loading"
          flat
          :label="$t('revert and exit')"
          color="primary"
          v-close-popup
        />
        <q-btn
          :loading="loading"
          flat
          :label="$t('revert')"
          color="primary"
          @click="refresh_all"
        />
        <q-btn
          :loading="loading"
          flat
          :label="$t('apply')"
          color="primary"
          @click="apply"
        />
        <q-btn
          :loading="loading"
          flat
          :label="$t('apply and exit')"
          color="primary"
          @click="applyAndExit"
        />
      </q-card-actions>
    </q-card>
  </q-dialog>
</template>

<style scoped>
.width_5_1 {
  width: 20%;
}

.width_5_2 {
  width: 10%;
}

.width_5_2_2 {
  width: 18%;
}

.width_5_3 {
  width: 20%;
}

._panel {
  padding: 3px;
  height: 60vh;
}
</style>

<script lang="ts">
import { defineComponent, ref, Ref, watch, computed } from "vue";
import { useStore } from "src/store";
import { useQuasar, SessionStorage } from "quasar";
import { useI18n } from "vue-i18n";
import GlobalData from "src/common/GlobalData";
import { HttpProtocol } from "src/entities/HttpProtocol";
import { date } from "quasar";
import { Protocol } from "src/entities/WSProtocol";

const _time_zones = [
  "UTC-12(Central Pacific)",
  "UTC-11(Central Pacific)",
  "UTC-10(Honolulu of USA)",
  "UTC-9(Alaska of USA)",
  "UTC-8(California of USA)",
  "UTC-7(Phoenix of USA, Arizona of USA)",
  "UTC-6(Chicago of USA, Mexico)",
  "UTC-5(New York of USA)",
  "UTC-4(Republic of Chile)",
  "UTC-3(Brazil, Argentina)",
  "UTC-2(Mid Atlantic)",
  "UTC-1(West African continent)",
  "UTC(England, Portugal)",
  "UTC+1(Spain, France, Germany, ...)",
  "UTC+2(Turkey, South Africa, Rome, Egypt, ...)",
  "UTC+3(Moscow of Russia, Iran)",
  "UTC+4(The united Arab emirates)",
  "UTC+5(Pakistan, India)",
  "UTC+6(Bangladesh, Myanmar, Xinjiang Autonomous Region of China)",
  "UTC+7(Thailand, Malaysia, Singapore)",
  "UTC+8(Beijing of China, Philippines)",
  "UTC+9(Japan)",
  "UTC+10(Vladivostok of Russia, Guam, Australia)",
  "UTC+11(Solomon Islands)",
  "UTC+12(New Zealand)",
];

export default defineComponent({
  name: "SystemSettingDialog",

  setup() {
    let $store = useStore();
    let $q = useQuasar();
    let $t = useI18n();

    let show_dialog = ref(false);
    let loading = ref(false);

    let tab = ref("network");

    let auto_ip = ref($t.t("enable"));
    let ip_address = ref("127.0.0.1");
    let gateway = ref("127.0.0.1");
    let netmask = ref("127.0.0.1");
    let mac_address = ref("11:22:33:44:55:66");

    let brightness = ref(0);
    let contrast = ref(0);
    let hue = ref(0);

    let device_resolution = ref("");
    let device_resolution_options = ref(["11", "22", "33"]);
    let output_board_resolution = ref("");
    let output_board_resolution_options = ref(["1", "2", "3"]);

    let use_ntp = ref($t.t("enable"));
    let ntp_server = ref("");
    let ntp_sync_delay = ref(180);
    let current_date = ref("");
    let current_time = ref("");
    let time_zone = ref("");
    let time_zone_options: Ref<string[]> = ref([]);
    for (const item of _time_zones) {
      time_zone_options.value.push($t.t(item));
    }

    let network_form: Ref<any> = ref(null);
    let other_form: Ref<any> = ref(null);
    let graphics_form: Ref<any> = ref(null);

    const refresh_all = () => {
      const config = GlobalData.getInstance()?.applicationConfig;
      if (config) {
        setTimeout(async () => {
          const support_resolutions = await GlobalData.getInstance()
            .getCurrentClient()
            ?.getSupportResolutions();
          if (support_resolutions) {
            output_board_resolution_options.value = [];
            for (const item of Object.keys(
              support_resolutions.output_board_support_resolutions
            ).sort()) {
              output_board_resolution_options.value.push(
                (support_resolutions.output_board_support_resolutions as any)[
                  item
                ]
              );
            }
            device_resolution_options.value = [];
            for (const item of Object.keys(
              support_resolutions.device_support_resolutions
            )) {
              device_resolution_options.value.push(item);
            }

            {
              const val = output_board_resolution_options.value.find(
                (element) =>
                  element &&
                  element == support_resolutions.current_output_board_resolution
              );
              output_board_resolution.value =
                val ?? output_board_resolution_options.value[0];
            }

            {
              const val = device_resolution_options.value.find(
                (element) =>
                  element &&
                  element == support_resolutions.current_device_resolution
              );
              device_resolution.value =
                val ?? device_resolution_options.value[0];
            }
          }
        }, 1);
        auto_ip.value =
          config.auto_ip_address != "0" ? $t.t("enable") : $t.t("disable");
        gateway.value = config.gateway;
        netmask.value = config.subnet_mask;
        mac_address.value = config.mac_address;
        ip_address.value = $store.state.device_ip_address;

        brightness.value = config.graphics_brightness;
        contrast.value = config.graphics_contrast;
        hue.value = config.graphics_hue;

        use_ntp.value =
          config.use_ntp != "0" ? $t.t("enable") : $t.t("disable");
        ntp_server.value = config.ntp_server;
        ntp_sync_delay.value = parseInt(config.ntp_sync_delay);
        if (isNaN(ntp_sync_delay.value)) {
          ntp_sync_delay.value = 180;
        }
        try {
          time_zone.value = time_zone_options.value[config.time_zone];
        } catch (e) {
          time_zone.value = time_zone_options.value[0];
        }

        const timeStamp = Date.now();
        current_date.value = date.formatDate(timeStamp, "YYYY-MM-DD");
        current_time.value = date.formatDate(timeStamp, "HH:mm:ss");
      }
    };

    const applyNetwork = async () => {
      const ret = await network_form.value.validate();
      if (ret) {
        let request = new Protocol.SetSystemNetworkRequestEntity();
        request.auto_ip = auto_ip.value == $t.t("enable");
        request.ip_address = ip_address.value;
        request.gtateway = gateway.value;
        request.net_mask = netmask.value;
        request.mac_address = mac_address.value;

        let success = false;
        try {
          setTimeout(() => {
            if (request.ip_address != $store.state.device_ip_address) {
              setTimeout(() => {
                SessionStorage.clear();
                if (
                  window.location.hostname.toLowerCase() == "192.168.1.1" ||
                  window.location.hostname.toLowerCase() == "localhost"
                ) {
                  window.location.reload();
                } else {
                  window.location.hostname = request.ip_address;
                }
              }, 1500);
            }
          }, 1000 * 10);
          /*await*/ GlobalData.getInstance()
            .getCurrentClient()
            ?.setSystemNetwork(request);
          success = true;
        } catch {}
        $q.notify({
          color: success ? "positive" : "negative",
          icon: success ? "done" : "warning",
          message:
            $t.t("set system network") +
            (success ? $t.t("success") : $t.t("fail")) +
            "!",
          position: "top",
          timeout: 1000,
        });
      }
    };
    const applyGraphics = async () => {
      const ret = await graphics_form.value.validate();
      if (ret) {
        let request = new Protocol.SetSystemGraphicsRequestEntity();
        request.brightness = brightness.value;
        request.contrast = contrast.value;
        request.hue = hue.value;
        request.output_board_resolution = output_board_resolution.value;
        request.device_resolution = device_resolution.value;

        let success = false;
        try {
          await GlobalData.getInstance()
            .getCurrentClient()
            ?.setSystemGraphics(request);
          success = true;
        } catch {}
        $q.notify({
          color: success ? "positive" : "negative",
          icon: success ? "done" : "warning",
          message:
            $t.t("set system graphics") +
            (success ? $t.t("success") : $t.t("fail")) +
            "!",
          position: "top",
          timeout: 1000,
        });
      }
    };
    const applyOther = async () => {
      const ret = await other_form.value.validate();
      if (ret) {
        let request = new Protocol.SetSystemOtherRequestEntity();
        request.use_ntp = use_ntp.value == $t.t("enable");
        request.ntp_sync_delay = ntp_sync_delay.value;
        request.ntp_server = ntp_server.value;
        request.time_zone = time_zone_options.value.findIndex(
          (element) => element && element == time_zone.value
        );
        if (request.time_zone < 0) {
          request.time_zone =
            GlobalData.getInstance().applicationConfig?.time_zone ?? 21;
        }
        request.datetime = current_date.value + " " + current_time.value;

        let success = false;
        try {
          await GlobalData.getInstance()
            .getCurrentClient()
            ?.setSystemOther(request);
          success = true;
        } catch {}
        $q.notify({
          color: success ? "positive" : "negative",
          icon: success ? "done" : "warning",
          message:
            $t.t("set system other") +
            (success ? $t.t("success") : $t.t("fail")) +
            "!",
          position: "top",
          timeout: 1000,
        });
      }
    };

    const apply = async () => {
      loading.value = true;
      try {
        switch (tab.value) {
          case "network":
            await applyNetwork();
            break;
          case "graphics":
            await applyGraphics();
            break;
          case "other":
            await applyOther();
            break;
        }
      } catch (e) {
        console.log(e);
      }
      loading.value = false;
    };

    return {
      show_dialog,
      loading,
      tab,
      auto_ip,
      ip_address,
      gateway,
      netmask,
      mac_address,
      brightness,
      contrast,
      hue,
      device_resolution,
      device_resolution_options,
      output_board_resolution,
      output_board_resolution_options,
      use_ntp,
      ntp_server,
      ntp_sync_delay,
      current_date,
      current_time,
      time_zone,
      time_zone_options,
      network_form,
      other_form,
      graphics_form,
      refresh_all,
      apply,
      loga(a: any) {
        console.log(a);
      },
      showDialog() {
        show_dialog.value = true;

        refresh_all();
      },
      resetData() {
        loading.value = false;
        tab.value = "network";
      },
      async applyAndExit() {
        await apply();
        show_dialog.value = false;
      },
      isIpAddress(str: string) {
        return (
          str == "localhost" ||
          /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/.test(
            str
          )
        );
      },
      isMacAddress(str: string) {
        return /([A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}/.test(str);
      },
    };
  },
});
</script>
