<template>
  <div class="pa-4 login-root fill-height">
    <div class="chat-header">
      <v-container fluid>
        <v-row no-gutters>
          <v-col>
            <v-img
              :src="logotype"
              width="32"
              height="32"
              contain
              xclass="d-inline-block header-button-left"
            />
          </v-col>
          <v-col>
            <div class="room-name no-upper">{{ $t("login.title") }}</div>
          </v-col>
          <v-col class="text-end">
            <v-btn id="btn-close" text v-if="showCloseButton" @click.stop="$navigation.pop">
              <v-icon>close</v-icon>
            </v-btn>
          </v-col>
        </v-row>
      </v-container>
    </div>

    <div color="rgba(255,255,255,0.1)" class="text-center">
      <v-form v-model="isValid">
        <v-text-field
          prepend-inner-icon="$vuetify.icons.user"
          v-model="user.user_id"
          :label="$t('login.username')"
          color="black"
          background-color="white"
          solo
          :rules="[(v) => !!v || $t('login.username_required')]"
          :error="userErrorMessage != null"
          :error-messages="userErrorMessage"
          required
          v-on:keyup.enter="onUsernameEnter"
          v-on:keydown="hasError=false"
          v-on:blur="onUsernameBlur"
        ></v-text-field>

        <div class="error--text" v-if="loadingLoginFlows">Loading login flows...</div>

        <v-text-field
          v-show="showPasswordField"
          prepend-inner-icon="$vuetify.icons.password"
          ref="password"
          v-model="user.password"
          :label="$t('login.password')"
          color="black"
          background-color="#f5f5f5"
          filled
          type="password"
          :rules="[(v) => !!v || $t('login.password_required')]"
          :error="passErrorMessage != null"
          :error-messages="passErrorMessage"
          required
          v-on:keydown="hasError=false"
          v-on:keyup.enter="
            () => {
              if (isValid && !loading) {
                handleLogin();
              }
            }
          "
        ></v-text-field>
        <div class="error--text" v-if="hasError">{{ this.message }}</div>
        <v-checkbox
          id="chk-remember-me"
          class="mt-0"
          v-model="rememberMe"
          @change="onRememberMe"
          :label="$t('join.remember_me')"
        />
        <v-btn
          id="btn-login"
          :disabled="!isValid || loading || loadingLoginFlows"
          color="black"
          depressed
          block
          @click.stop="handleLogin"
          :loading="loading"
          class="filled-button mt-4"
          >{{ $t("login.login") }}</v-btn
        >
        <div class="mt-2 overline" v-if="showCreateRoom">{{ $t("login.or") }}</div>
        <v-btn
          id="btn-create-room"
          color="primary"
          depressed
          block
          @click.stop="handleCreateRoom"
          class="filled-button mt-2"
          v-if="showCreateRoom"
          >{{ $t("login.create_room") }}</v-btn
        >
      </v-form>
    </div>
  </div>
</template>

<script>
import User from "../models/user";
import util from "../plugins/utils";
import rememberMeMixin from "./rememberMeMixin";
import * as sdk from "matrix-js-sdk";
import logoMixin from "./logoMixin";

export default {
  name: "Login",
  mixins:[rememberMeMixin, logoMixin],
  props: {
    showCreateRoomOption: {
      type: Boolean,
      default: function () {
        return true;
      },
    },
    redirect: {
      type: String,
      default: function() {
        return null;
      },
    }
  },
  data() {
    return {
      user: new User("", ""),
      isValid: true,
      loading: false,
      message: "",
      userErrorMessage: null,
      passErrorMessage: null,
      hasError: false,
      currentLoginServer: "",
      loadingLoginFlows: false,
      loginFlows: null,
      showPasswordField: false,
    };
  },
  computed: {
    loggedIn() {
      return this.$store.state.auth.status.loggedIn;
    },
    currentUser() {
      return this.$store.state.auth.user;
    },
    showCloseButton() {
      return this.$navigation && this.$navigation.canPop();
    },
    showCreateRoom() {
      return this.showCreateRoomOption && !this.$config.hide_add_room_on_home;
    }
  },
  created() {
    if (this.loggedIn) {
      this.$navigation.push(
        {
          name: "Chat",
          params: { roomId: util.sanitizeRoomId(this.$matrix.currentRoomId) },
        },
        -1
      );
    }
  },
  watch: {
    user: {
      handler() {
        // Reset manual errors
        this.userErrorMessage = null;
        this.passErrorMessage = null;
      },
      deep: true,
    }
  },
  methods: {
    handleLogin() {
      if (this.user.user_id && this.user.password) {
        // Reset errors
        this.message = null;

        // Is it a full matrix user id? Modify a copy, so that the UI will still show the full ID.
        var user = Object.assign({}, this.user);

        this.loading = true;
        this.$store.dispatch("login", { user }).then(
          () => {
            if (this.redirect) {
              this.$navigation.push({ name: this.redirect }, -1);
            }
            else if (this.$matrix.currentRoomId) {
              this.$navigation.push(
                {
                  name: "Chat",
                  params: {
                    roomId: util.sanitizeRoomId(this.$matrix.currentRoomId),
                  },
                },
                -1
              );
            } else {
              this.$navigation.push({ name: "Home" }, -1);
            }
          },
          (error) => {
            console.error(error);
            this.loading = false;
            this.message =
              (error.data && error.data.error) ||
              error.message ||
              error.toString();
            if(error.data && error.data.errcode ==='M_FORBIDDEN') {
              this.message = this.$i18n.messages[this.$i18n.locale].login.invalid_message;
              this.hasError = true;
            }
            console.log("Message set to ", this.message);
          }
        );
      }
    },
    handleCreateRoom() {
      this.$navigation.push({ name: "CreateRoom" });
    },
    onUsernameEnter() {
      this.$refs.password.focus();
      this.onUsernameBlur();
    },
    onUsernameBlur() {
      var user = Object.assign({}, this.user);
      util.getMatrixBaseUrl(user, this.$config)
        .then((baseUrl) => {
          if (baseUrl !== this.currentLoginServer) {

            this.showPasswordField = false;

            this.currentLoginServer = baseUrl;
            this.loadingLoginFlows = true;

            const matrixClient = sdk.createClient({ baseUrl: baseUrl });
            matrixClient.loginFlows().then((response) => {
              console.log("FLOWS", response.flows);
              this.loginFlows = response.flows.filter(this.supportedLoginFlow);
              this.loadingLoginFlows = false;
              if (this.loginFlows.length == 0) {
                this.message = this.$t('login.no_supported_flow')
                this.hasError = true;
              } else {
                this.message = "";
                this.hasError = false;
                this.showPasswordField = this.loginFlows.some(f => f.type == "m.login.password");
                if (this.showPasswordField) {
                  this.$nextTick(() => {
                    this.$refs.password.focus();
                  });
                }
              }
            });
          }
        });
    },
    supportedLoginFlow(flow) {
      return ["m.login.password"].includes(flow.type);
    }
  },
};
</script>

<style lang="scss">
@import "@/assets/css/login.scss";
</style>