<template>
  <q-dialog
    persistent
    v-model="show_dialog"
    @before-hide="resetData"
    @keydown="
      (evt) => {
        if (!loading && evt.keyCode == 27) {
          show_dialog = false;
        } else if (
          evt.keyCode == 85 &&
          evt.ctrlKey &&
          evt.altKey &&
          evt.shiftKey
        ) {
          ext_flag = !ext_flag;
          if (!ext_flag) {
            register_type = 'offline';
          }
        }
      }
    "
  >
    <q-file
      ref="select_file_dialog"
      v-show="false"
      v-model="licence_file"
      label="Standard"
      accept=".MSFusion"
      @update:model-value="onFileUpdate"
    />
    <q-card class="overflow-hidden" style="max-width: 70vw">
      <q-form @submit="onSubmit">
        <q-card-section class="q-ma-none q-pa-sm">
          <div class="row">
            <div class="col-auto text-h6">
              {{ $t("register dialog") }}
              <span :class="register_flag ? 'text-green' : 'text-red'">
                (
                <span v-if="!register_flag">{{ $t("not registered") }}</span>
                <span v-else>{{ $t("registered") }}</span>
                <span v-if="register_flag && trial_days"
                  >,{{ $t("trial days") }}:{{ trial_days }}{{ $t("day") }}</span
                >
                <span v-if="register_flag && trial_days"
                  >,{{ $t("last days") }}:{{ last_days }}{{ $t("day") }}</span
                >
                <span v-if="register_flag"
                  >,{{ $t("register date") }}: {{ register_date }}</span
                >
                )
              </span>
            </div>
            <q-space />
            <div>
              <q-btn
                :loading="loading"
                :disable="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 class="scroll" style="width: 70vw">
          <q-list>
            <q-item v-if="ext_flag">
              <q-item-section avatar class="header_label">
                {{ $t("register type") }}
              </q-item-section>
              <q-item-section>
                <div class="row q-gutter-sm">
                  <q-radio
                    v-model="register_type"
                    checked-icon="task_alt"
                    unchecked-icon="panorama_fish_eye"
                    val="offline"
                    :label="$t('offline register')"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-radio
                    v-model="register_type"
                    checked-icon="task_alt"
                    unchecked-icon="panorama_fish_eye"
                    val="online"
                    :label="$t('online register')"
                    class="col"
                    :loading="loading"
                    :disable="loading"
                  />
                </div>
              </q-item-section>
            </q-item>
            <q-item v-if="register_type == 'offline'">
              <q-item-section avatar class="header_label">
                {{ $t("register code") }}
              </q-item-section>
              <q-item-section>
                <div style="word-break: break-all">
                  {{ register_code }}
                </div>
              </q-item-section>
              <q-item-section avatar>
                <qrcode-vue
                  :value="register_code"
                  level="H"
                  render-as="svg"
                  :size="195"
                />
              </q-item-section>
              <q-item-section avatar>
                <q-btn
                  round
                  flat
                  icon="content_copy"
                  color="green"
                  :loading="loading"
                  :disable="loading"
                  @click="
                    copyToClipboard(register_code).then(() =>
                      $q.notify({
                        color: 'positive',
                        icon: 'done',
                        message: $t('copy') + $t('success'),
                        position: 'top',
                        timeout: 1500,
                      })
                    )
                  "
                >
                  <q-tooltip>
                    {{ $t("copy") }}{{ $t("register code") }}
                  </q-tooltip>
                </q-btn>
              </q-item-section>
            </q-item>
            <q-item v-if="register_type == 'offline'">
              <q-item-section avatar class="header_label">
                {{ $t("active code") }}
              </q-item-section>
              <q-item-section>
                <q-input
                  type="textarea"
                  v-model="active_code"
                  lazy-rules
                  autofocus
                  :loading="loading"
                  :disable="loading"
                  :rules="[
                    (val) =>
                      (val && val.length > 0) || $t('Please type something'),
                  ]"
                />
              </q-item-section>
              <q-item-section avatar>
                <q-btn
                  icon="attach_file"
                  round
                  flat
                  :loading="loading"
                  :disable="loading"
                  class="rotate-90"
                  color="green"
                  @click="$refs.select_file_dialog.pickFiles($event)"
                >
                  <q-tooltip>
                    {{ $t("open file") }}
                  </q-tooltip>
                </q-btn>
              </q-item-section>
            </q-item>
            <q-item v-if="false && register_type == 'offline'">
              <q-item-section avatar class="header_label">
                {{ $t("secret key") }}
              </q-item-section>
              <q-item-section>
                <q-input v-model="secret_key"> </q-input>
              </q-item-section>
              <q-item-section avatar> ({{ $t("optional") }}) </q-item-section>
            </q-item>
            <q-item v-if="register_type == 'online'">
              <q-item-section avatar class="header_label">
                {{ $t("server ipaddress") }}
              </q-item-section>
              <q-item-section>
                <q-input
                  v-model="server_address"
                  autofocus
                  :loading="loading"
                  :disable="loading"
                  lazy-rules
                  :rules="[
                    (val) =>
                      isIpAddress(val) || $t('Please input vaild ip address'),
                  ]"
                />
              </q-item-section>
            </q-item>
            <q-item v-if="register_type == 'online'">
              <q-item-section avatar class="header_label">
                {{ $t("active type") }}
              </q-item-section>
              <q-item-section>
                <div class="row q-gutter-sm">
                  <q-radio
                    v-model="active_type"
                    checked-icon="task_alt"
                    unchecked-icon="panorama_fish_eye"
                    val="forever"
                    :label="$t('forever active')"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-radio
                    v-model="active_type"
                    checked-icon="task_alt"
                    unchecked-icon="panorama_fish_eye"
                    val="limit"
                    :label="$t('time limit active')"
                    class="col"
                    :loading="loading"
                    :disable="loading"
                  />
                </div>
              </q-item-section>
            </q-item>
            <q-item v-if="active_type == 'limit'">
              <q-item-section avatar class="header_label">
                {{ $t("active time") }}
              </q-item-section>
              <q-item-section>
                <q-input
                  v-model="active_hour"
                  type="number"
                  min="1"
                  max="120"
                  :loading="loading"
                  :disable="loading"
                >
                  <template v-slot:append>
                    {{ $t("day") }}
                  </template>
                </q-input>
              </q-item-section>
            </q-item>

            <q-item>
              <q-item-section avatar class="header_label">
                {{ $t("function") }}
              </q-item-section>
              <q-item-section>
                <div class="row q-gutter-sm">
                  <q-checkbox
                    v-model="function_output_board"
                    :label="$t('output board')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-checkbox
                    v-model="function_center_control"
                    :label="$t('center control')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-checkbox
                    v-model="function_mirroring_output"
                    :label="$t('mirroring output')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                </div>
              </q-item-section>
            </q-item>

            <q-item>
              <q-item-section avatar class="header_label"> </q-item-section>
              <q-item-section>
                <div class="row q-gutter-sm">
                  <q-checkbox
                    v-model="function_custom_ISV"
                    :label="$t('Custom ISV')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-checkbox
                    v-model="function_magic_wall"
                    @update:model-value="changeMagic()"
                    :label="$t('magic wall')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                  <q-checkbox
                    v-model="function_fusion"
                    @update:model-value="changeFusion()"
                    :label="$t('fusion')"
                    color="cyan"
                    class="offset-md-1 col"
                    :loading="loading"
                    :disable="loading"
                  />
                </div>
              </q-item-section>
            </q-item>

            <q-item>
              <q-item-section avatar class="header_label">
                {{ $t("language") }}
              </q-item-section>
              <q-item-section>
                <div class="row q-gutter-sm">
                  <q-radio
                    color="cyan"
                    :loading="loading"
                    :disable="loading"
                    class="offset-md-1 col"
                    v-model="target_language"
                    val="zh-CN"
                    :label="$t('chinese')"
                  />
                  <q-radio
                    color="cyan"
                    :loading="loading"
                    :disable="loading"
                    class="offset-md-1 col"
                    v-model="target_language"
                    val="en-US"
                    :label="$t('english')"
                  />
                </div>
              </q-item-section>
            </q-item>
          </q-list>
        </q-card-section>

        <q-separator />

        <q-card-actions align="right">
          <q-btn
            :loading="loading"
            :disable="loading"
            flat
            :label="$t('Cancel')"
            no-caps
            color="primary"
            v-close-popup
          />
          <q-btn
            ref="accept"
            flat
            no-caps
            :label="$t('register')"
            :loading="loading"
            :disable="loading"
            type="submit"
            color="primary"
          />
        </q-card-actions>
      </q-form>
    </q-card>
  </q-dialog>
</template>

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

<script lang="ts">
import {
  defineComponent,
  ref,
  Ref,
  watch,
  computed,
  onMounted,
  onBeforeUnmount,
  nextTick,
} from "vue";
import { useStore } from "src/store";
import { useQuasar, copyToClipboard } from "quasar";
import { useI18n } from "vue-i18n";
import GlobalData from "src/common/GlobalData";
import QrcodeVue from "qrcode.vue";
import { Protocol } from "src/entities/WSProtocol";
import { EDeviceAttribute } from "src/entities/EDeviceAttribute";
import ValidationUtil from "src/common/ValidationUtil";

export default defineComponent({
  name: "ComponentRegisterDialog",
  components: { QrcodeVue },
  setup() {
    let $store = useStore();
    let $q = useQuasar();
    let $t = useI18n();

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

    const select_file_dialog: Ref<any> = ref(null);

    const target_language = ref("zh-CN");

    const licence_file: Ref<any> = ref(null);
    const register_type = ref("offline");
    const register_code: Ref<string> = ref("");
    const active_code: Ref<string> = ref("");
    const active_type = ref("forever");
    const secret_key = ref("");
    const active_hour = ref(1);
    const ext_flag = ref(false);
    const server_address = ref("");

    const function_center_control = ref(false);
    const function_output_board = ref(false);
    const function_mirroring_output = ref(false);
    const function_custom_ISV = ref(false);
    const function_magic_wall = ref(false);
    const function_fusion = ref(false);

    const trial_days = ref(0);
    const last_days = ref(0);
    const register_date = ref("");
    const register_flag = ref(false);

    const resetData = () => {
      ext_flag.value = false;
      register_type.value = "offline";
      secret_key.value = "";
      active_type.value = "forever";
      loading.value = false;
      active_code.value = "";
      register_code.value = "";
      trial_days.value = 0;
      register_date.value = "";
      last_days.value = 0;

      function_center_control.value = false;
      function_output_board.value = false;
      function_mirroring_output.value = false;
      function_custom_ISV.value = false;
      function_magic_wall.value = false;
      function_fusion.value = false;
    };

    const showDialog = async () => {
      resetData();

      show_dialog.value = true;

      try {
        let response = await GlobalData.getInstance()
          .getCurrentClient()
          ?.getRegisterInfo();
        if (response) {
          register_code.value = response.register_code;
          trial_days.value = response.trial_days;
          last_days.value = response.last_days;
          register_date.value = response.register_date;
          register_flag.value = response.registered;
        }
        loading.value = false;
      } catch (e) {
        console.log(e);
        show_dialog.value = false;
      }

      function_custom_ISV.value = $store.state.custom_defines.is_custom_isv;
      function_center_control.value =
        $store.state.custom_defines.function_center_control;
      function_output_board.value =
        $store.state.custom_defines.function_output_board;
      function_mirroring_output.value =
        $store.state.custom_defines.function_mirroring_output;
      function_magic_wall.value =
        $store.state.custom_defines.function_magic_wall;
      function_magic_wall.value = $store.state.custom_defines.function_fusion;
    };

    return {
      show_dialog,
      loading,
      register_code,
      active_code,
      register_type,
      active_type,
      active_hour,
      ext_flag,
      secret_key,
      trial_days,
      last_days,
      register_date,
      register_flag,
      licence_file,
      select_file_dialog,
      server_address,
      function_output_board,
      function_custom_ISV,
      function_magic_wall,
      function_fusion,
      function_center_control,
      function_mirroring_output,
      target_language,
      copyToClipboard,
      isShow() {
        return show_dialog.value;
      },
      showDialog,
      resetData,

      async onSubmit() {
        loading.value = true;
        if (active_hour.value > 30 * 2) {
          active_hour.value = 30 * 2;
        }
        if (active_hour.value < 1) {
          active_hour.value = 1;
        }

        try {
          if (register_type.value == "online") {
            let licence_str = "";
            const requested = await new Promise((resolve) => {
              const timeout_handler = setTimeout(() => {
                resolve(false);
              }, 1000 * 5);
              try {
                let ws = new WebSocket(
                  "ws://" + server_address.value + ":37631"
                );
                ws.onmessage = (data) => {
                  interface IResult {
                    id: 1;
                    action: "license";
                    result: {
                      err?: "";
                      update_key: "";
                      lic: "";
                    };
                  }
                  try {
                    const result = JSON.parse(data.data) as IResult;
                    if (result && !result.result.err) {
                      licence_str = result.result.lic;
                    }
                    clearTimeout(timeout_handler);
                    resolve(true);
                  } catch {
                    clearTimeout(timeout_handler);
                    resolve(false);
                  }
                };
                ws.onerror = () => {
                  clearTimeout(timeout_handler);
                  resolve(false);
                };
                ws.onclose = ws.onerror;
                ws.onopen = () => {
                  ws.send(
                    JSON.stringify({
                      id: 1,
                      action: "license",
                      params: {
                        name: "MSFusion",
                        days:
                          active_type.value == "forever"
                            ? 0
                            : parseInt(active_hour.value.toString()),
                        minutes: 0,
                        key: register_code.value,
                      },
                    })
                  );
                };
              } catch (e) {
                console.error(e);
                clearTimeout(timeout_handler);
                resolve(false);
              }
            });
            // console.log(licence_str);
            if (requested && licence_str) {
              active_code.value = licence_str;
              // console.log(licence_str);
            } else {
              $q.notify({
                color: "negative",
                icon: "warning",
                message: $t.t("register device") + $t.t("fail") + "!",
                position: "top",
                timeout: 1500,
              });

              loading.value = false;
              return;
            }
          }

          let success = false;
          const response = await GlobalData.getInstance()
            .getCurrentClient()
            ?.registerDevice(
              register_code.value,
              active_code.value,
              register_type.value == "online",
              active_type.value == "forever",
              secret_key.value,
              parseInt(active_hour.value.toString())
            );
          if (response) {
            success = response.success;
          }

          if (success) {
            let attribute = EDeviceAttribute.None;
            if (function_center_control.value) {
              attribute |= EDeviceAttribute.CenterControl;
            }
            if (function_output_board.value) {
              attribute |= EDeviceAttribute.OutputBoard;
            }
            if (function_mirroring_output.value) {
              attribute |= EDeviceAttribute.MirroringOutput;
            }

            if (function_custom_ISV.value) {
              attribute |= EDeviceAttribute.CustomISV;
            }
            if (function_magic_wall.value) {
              attribute |= EDeviceAttribute.ProductMagicWall;
            }
            if (function_fusion.value) {
              attribute |= EDeviceAttribute.ProductFusion;
            }

            GlobalData.getInstance()
              .getCurrentClient()
              ?.setDeviceAttribute(attribute);

            GlobalData.getInstance()
              .getCurrentClient()
              ?.setServerLanguage(target_language.value);
          }

          $q.notify({
            color: success ? "positive" : "negative",
            icon: success ? "done" : "warning",
            message:
              $t.t("register device") +
              (success ? $t.t("success") : $t.t("fail")) +
              "!",
            position: "top",
            timeout: 1500,
          });
          show_dialog.value = false;
        } catch {}
        loading.value = false;
      },
      onFileUpdate(file: File) {
        var reader = new FileReader();
        reader.readAsText(file);
        reader.onload = function () {
          if (this.result) {
            active_code.value = this.result.toString();
          }
        };
        if (file) {
          licence_file.value = new File([], "");
        }
      },
      isIpAddress(str: string) {
        return ValidationUtil.isIpAddress(str);
      },
      changeMagic() {
        if (function_magic_wall.value) {
          function_fusion.value = false;
        }
      },
      changeFusion() {
        if (function_fusion.value) {
          function_magic_wall.value = false;
        }
      },
    };
  },
});
</script>
