// 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>
  <span class="header-notice-opener" v-if="showSwitcher">
    <a-select
      class="domain-select"
      :loading="loading"
      :defaultValue="currentAccount"
      :value="currentAccount"
      showSearch
      optionFilterProp="label"
      :filterOption="(input, option) => {
        return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
      }"
      @change="changeAccount"
      @focus="fetchData" >

      <template #suffixIcon>
        <a-tooltip placement="bottom">
          <template #title>
            <span>{{ $t('label.domain') }}</span>
          </template>
          <span class="custom-suffix-icon">
            <BlockOutlined v-if="!loading" class="ant-select-suffix" />
            <LoadingOutlined v-else />
          </span>
        </a-tooltip>
      </template>

      <a-select-option v-for="(account, index) in samlAccounts" :key="index" :label="`${account.accountName} (${account.domainName})`">
        {{ `${account.accountName} (${account.domainName})` }}
      </a-select-option>
    </a-select>
  </span>
</template>

<script>
import store from '@/store'
import { postAPI } from '@/api'
import _ from 'lodash'

export default {
  name: 'SamlDomainSwitcher',
  data () {
    return {
      showSwitcher: false,
      samlAccounts: [],
      currentAccount: '',
      loading: false
    }
  },
  created () {
    this.fetchData()
  },
  methods: {
    fetchData () {
      var page = 1
      const samlAccounts = []
      const getNextPage = () => {
        this.loading = true
        postAPI('listAndSwitchSamlAccount', { details: 'min', page: page, pageSize: 500 }).then(json => {
          if (json && json.listandswitchsamlaccountresponse && json.listandswitchsamlaccountresponse.samluseraccount) {
            samlAccounts.push(...json.listandswitchsamlaccountresponse.samluseraccount)
          }
          if (samlAccounts.length < json.listandswitchsamlaccountresponse.count) {
            page++
            getNextPage()
          }
        }).catch(error => {
          console.log(error)
        }).finally(() => {
          if (samlAccounts.length < 2) {
            this.showSwitcher = false
            return
          }
          this.samlAccounts = samlAccounts
          this.samlAccounts = _.orderBy(samlAccounts, ['domainPath'], ['asc'])
          const currentAccount = this.samlAccounts.filter(x => {
            return x.userId === store.getters.userInfo.id
          })[0]
          this.currentAccount = `${currentAccount.accountName} (${currentAccount.domainName})`
          this.loading = false
          this.showSwitcher = true
        })
      }
      getNextPage()
    },
    changeAccount (index) {
      const account = this.samlAccounts[index]
      postAPI('listAndSwitchSamlAccount', {
        userid: account.userId,
        domainid: account.domainId
      }).then(response => {
        store.dispatch('GetInfo', true).then(() => {
          this.$message.success(`Switched to "${account.accountName} (${account.domainPath})"`)
          this.$router.go()
        })
      }).else(error => {
        console.log('error refreshing with new user context: ' + error)
      })
    }
  }
}
</script>

<style lang="less" scoped>
.domain {
  &-select {
    width: 20vw;
  }

  &-icon {
    font-size: 20px;
    line-height: 1;
    padding-top: 5px;
    padding-right: 5px;
  }
}

.custom-suffix-icon {
  font-size: 20px;
  position: absolute;
  top: 0;
  right: 0;
  margin-top: -8px;
}
</style>
