// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <a-form
    id="formForgotPassword"
    class="user-layout-forgot-password"
    :ref="formRef"
    :model="form"
    :rules="rules"
    @finish="handleSubmit"
    v-ctrl-enter="handleSubmit"
  >
        <a-form-item v-if="$config.multipleServer" name="server" ref="server">
          <a-select
            size="large"
            :placeholder="$t('server')"
            v-model:value="form.server"
            @change="onChangeServer"
            showSearch
            optionFilterProp="label"
            :filterOption="(input, option) => {
              return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
            }">
            <a-select-option v-for="item in $config.servers" :key="(item.apiHost || '') + item.apiBase" :label="item.name">
              <template #prefix>
                <database-outlined />
              </template>
              {{ item.name }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item ref="username" name="username">
          <a-input
            size="large"
            type="text"
            v-focus="true"
            :placeholder="$t('label.username')"
            v-model:value="form.username"
          >
            <template #prefix>
              <user-outlined />
            </template>
          </a-input>
        </a-form-item>
        <a-form-item ref="domain" name="domain">
          <a-input
            size="large"
            type="text"
            :placeholder="$t('label.domain')"
            v-model:value="form.domain"
          >
            <template #prefix>
              <block-outlined />
            </template>
          </a-input>
        </a-form-item>

    <a-form-item>
      <a-button
        size="large"
        type="primary"
        html-type="submit"
        class="submit-button"
        :loading="submitBtn"
        :disabled="submitBtn"
        ref="submit"
        @click="handleSubmit"
      >{{ $t('label.submit') }}</a-button>
    </a-form-item>
    <a-row justify="space-between">
      <a-col>
      <translation-menu/>
      </a-col>
      <a-col>
        <router-link :to="{ name: 'login' }">
          {{ $t('label.back.login') }}
        </router-link>

      </a-col>
    </a-row>
  </a-form>
</template>

<script>
import { ref, reactive, toRaw } from 'vue'
import { postAPI } from '@/api'
import store from '@/store'
import { SERVER_MANAGER } from '@/store/mutation-types'
import TranslationMenu from '@/components/header/TranslationMenu'

export default {
  components: {
    TranslationMenu
  },
  data () {
    return {
      idps: [],
      customActiveKey: 'cs',
      customActiveKeyOauth: false,
      submitBtn: false,
      email: '',
      secretcode: '',
      oauthexclude: '',
      server: ''
    }
  },
  created () {
    if (this.$config.multipleServer) {
      this.server = this.$localStorage.get(SERVER_MANAGER) || this.$config.servers[0]
    }
    this.initForm()
  },
  methods: {
    initForm () {
      this.formRef = ref()
      this.form = reactive({
        server: (this.server.apiHost || '') + this.server.apiBase,
        username: this.$route.query?.username || '',
        domain: this.$route.query?.domain || ''
      })
      this.rules = {
        username: [{
          required: true,
          message: this.$t('message.error.username'),
          trigger: 'change'
        }]
      }
    },
    handleSubmit (e) {
      e.preventDefault()
      if (this.submitBtn) return
      this.formRef.value.validate().then(() => {
        this.submitBtn = true

        const values = toRaw(this.form)
        if (this.$config.multipleServer) {
          this.axios.defaults.baseURL = (this.server.apiHost || '') + this.server.apiBase
          store.dispatch('SetServer', this.server)
        }
        const loginParams = { ...values }
        delete loginParams.username
        loginParams.username = values.username
        loginParams.domain = values.domain
        if (!loginParams.domain) {
          loginParams.domain = '/'
        }
        postAPI('forgotPassword', loginParams)
          .finally(() => {
            this.$message.success(this.$t('message.forgot.password.success'))
            this.$router.replace({ path: '/user/login' })
          })
      }).catch(error => {
        this.formRef.value.scrollToField(error.errorFields[0].name)
      })
    },
    requestFailed (err) {
      if (err && err.response && err.response.data && err.response.data.forgotpasswordresponse) {
        const error = err.response.data.forgotpasswordresponse.errorcode + ': ' + err.response.data.forgotpasswordresponse.errortext
        this.$message.error(`${this.$t('label.error')} ${error}`)
      } else {
        this.$message.error(this.$t('message.password.reset.failed'))
      }
    },
    onChangeServer (server) {
      const servers = this.$config.servers || []
      const serverFilter = servers.filter(ser => (ser.apiHost || '') + ser.apiBase === server)
      this.server = serverFilter[0] || {}
    }
  }
}
</script>

<style lang="less" scoped>
.user-layout-forgot-password {
  min-width: 260px;
  width: 368px;
  margin: 0 auto;

  .mobile & {
    max-width: 368px;
    width: 98%;
  }

  label {
    font-size: 14px;
  }

  button.submit-button {
    margin-top: 8px;
    padding: 0 15px;
    font-size: 16px;
    height: 40px;
    width: 100%;
  }

  .user-login-other {
    text-align: left;
    margin-top: 24px;
    line-height: 22px;

    .item-icon {
      font-size: 24px;
      color: rgba(0, 0, 0, 0.2);
      margin-left: 16px;
      vertical-align: middle;
      cursor: pointer;
      transition: color 0.3s;

      &:hover {
        color: #1890ff;
      }
    }

    .register {
      float: right;
    }

    .g-btn-wrapper {
      background-color: rgb(221, 75, 57);
      height: 40px;
      width: 80px;
    }
  }
    .center {
     display: flex;
     flex-direction: column;
     justify-content: center;
     align-items: center;
     height: 100px;
    }

    .content {
      margin: 10px auto;
      width: 300px;
    }

    .or {
      text-align: center;
      font-size: 16px;
      background:
        linear-gradient(#CCC 0 0) left,
        linear-gradient(#CCC 0 0) right;
      background-size: 40% 1px;
      background-repeat: no-repeat;
    }
}
</style>
