<template>
  <q-layout view="hHh lpR fFf">
    <q-page-container>
      <q-page class="row items-center justify-evenly">
        <q-card :style="{ width: (landspace ? 30 : 70) + 'vw' }">
          <q-card-section class="text-center text-h6">
            {{ $t("login") }}
          </q-card-section>
          <q-separator />
          <q-card-section class="fit">
            <q-form
              ref="login_form"
              @submit="onSubmit"
              @reset="onReset"
              class="q-gutter-md"
            >
              <q-input
                :loading="data.loading"
                :disable="data.loading"
                filled
                v-model="data.ip_address"
                :label="$t('server ip address')"
                :hint="$t('please input server ip address')"
                lazy-rules
                :rules="[
                  (val) =>
                    (val && val.length > 0) || $t('Please type something'),
                  (val) =>
                    val == '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(
                      val
                    ) ||
                    $t('Please input vaild ip address'),
                ]"
                @keydown="
                  (evt) => {
                    if (evt.keyCode == 13) {
                      $refs?.password_input?.focus();
                    }
                  }
                "
              >
                <template v-if="data.ip_address" v-slot:append>
                  <q-icon
                    name="cancel"
                    @click.stop="data.ip_address = null"
                    class="cursor-pointer"
                  />
                </template>
              </q-input>

              <q-input
                autofocus
                ref="user_name"
                :loading="data.loading"
                :disable="data.loading"
                filled
                v-model="data.user_name"
                :label="$t('user name')"
                :hint="$t('please input user name')"
                lazy-rules
                :rules="[
                  (val) =>
                    (val && val.length > 0) || $t('Please type something'),
                ]"
                @keydown="
                  (evt) => {
                    if (evt.keyCode == 13) {
                      $refs?.password_input?.focus();
                    }
                  }
                "
              >
                <template v-if="data.user_name" v-slot:append>
                  <q-icon
                    name="cancel"
                    @click.stop="data.user_name = null"
                    class="cursor-pointer"
                  />
                </template>
              </q-input>

              <q-input
                ref="password_input"
                :loading="data.loading"
                :disable="data.loading"
                filled
                :type="data.show_password ? '' : 'password'"
                v-model="data.password"
                :label="$t('password')"
                :hint="$t('please input password')"
                lazy-rules
                :rules="[
                  (val) =>
                    (val && val.length > 0) || $t('Please type something'),
                ]"
                @keydown="
                  (evt) => {
                    if (evt.keyCode == 13) {
                      $refs?.login_button?.click();
                    }
                  }
                "
              >
                <template v-if="data.password" v-slot:append>
                  <q-icon
                    :name="data.show_password ? 'visibility' : 'visibility_off'"
                    class="cursor-pointer"
                    @click="data.show_password = !data.show_password"
                  />
                  <q-icon
                    name="cancel"
                    @click.stop="data.password = null"
                    class="cursor-pointer"
                  />
                </template>
              </q-input>
            </q-form>
          </q-card-section>
          <q-card-actions>
            <q-btn
              ref="login_button"
              class="full-width"
              :loading="data.loading"
              :label="$t('login')"
              color="primary"
              @click="$refs?.login_form?.submit()"
            />
          </q-card-actions>
        </q-card>
      </q-page>
    </q-page-container>
  </q-layout>
</template>

<script lang="ts">
import { defineComponent, reactive, ref } from "vue";

import GlobalData from "src/common/GlobalData";
import { LocalStorage, SessionStorage, useQuasar } from "quasar";
import ClientConnection from "src/common/ClientConnection";
import PermissionLevel from "src/entities/PermissionLevel";
import { useI18n } from "vue-i18n";
import { useRouter } from "vue-router";
import EventBus, { EventNamesDefine } from "src/common/EventBus";
import { useStore } from "src/store";

class _Data {
  user_name: string | null = null;
  password: string | null = null;
  loading = false;
  ip_address = window.location.hostname;
  show_password = false;

  constructor() {
    let temp = LocalStorage.getItem("default_ip_address");
    if (temp) {
      this.ip_address = temp.toString();
    } else {
      this.ip_address = window.location.hostname;
    }

    temp = LocalStorage.getItem("default_user_name");
    if (temp) {
      this.user_name = temp.toString();
    }

    temp = LocalStorage.getItem("default_password");
    if (temp) {
      this.password = temp.toString();
    }
  }
}

export default defineComponent({
  name: "PageLogin",

  components: {},

  setup() {
    const $q = useQuasar();
    const $t = useI18n();
    const $route = useRouter();
    const $store = useStore();
    const data = reactive(new _Data());
    let web_socket: ClientConnection | null = null;
    let is_pwa = ["fullscreen", "standalone", "minimal-ui"].some(
      (displayMode) =>
        window.matchMedia("(display-mode: " + displayMode + ")").matches
    );

    const landspace = ref(window.innerHeight < window.innerWidth);

    EventBus.getInstance().on(EventNamesDefine.WindowResize, () => {
      landspace.value = window.innerHeight < window.innerWidth;
    });

    return {
      data,
      landspace,
      is_pwa,
      async onSubmit() {
        return new Promise((resolve) => {
          data.loading = true;
          try {
            let global_data = GlobalData.getInstance();
            const url =
              "ws://" +
              data.ip_address +
              ":" +
              GlobalData.kDefaultWebsocektPort.toString() +
              GlobalData.kWebsocketResource;
            web_socket = new ClientConnection(
              url,
              data.user_name,
              data.password
            );
            let timer = setTimeout(() => {
              web_socket?.destory();
              web_socket = null;
              $q.notify({
                color: "negative",
                icon: "warning",
                message:
                  $t.t("login fail!") +
                  $t.t("connect time out!") +
                  $t.t(
                    "please check server state, or check server ip address!"
                  ),
                position: "center",
                timeout: 1500,
              });
              SessionStorage.set("auth", PermissionLevel.None);
              resolve(false);
              data.loading = false;
            }, 5000);
            web_socket.login_callback = (is_login) => {
              clearTimeout(timer);
              if (is_login && web_socket) {
                global_data.addClient(data.ip_address, web_socket);
                global_data.setCurrentClientName(data.ip_address);
                SessionStorage.set("auth", PermissionLevel.Root);
                SessionStorage.set("url", url);
                SessionStorage.set("name", data.ip_address);
                SessionStorage.set("user_name", data.user_name);
                SessionStorage.set("password", data.password);

                $store.commit("setDeviceIpAddress", data.ip_address);

                $route.push("/");
              } else {
                $q.notify({
                  color: "negative",
                  icon: "warning",
                  message:
                    $t.t("login fail!") + $t.t("user or password error!"),
                  position: "center",
                  timeout: 1500,
                });
                SessionStorage.set("auth", PermissionLevel.None);
              }
              resolve(true);
              data.loading = false;
            };
          } catch {
            resolve(true);
            data.loading = false;
          }
        });
      },
      onReset() {
        data.user_name = null;
        data.password = null;
      },
    };
  },
});
</script>
