<!--
  - 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>
  <v-container id="search" grid-list-xl fluid >
    <v-layout row wrap>
      <v-flex lg12>
        <v-card flat color="transparent">
          <v-card-text>
            <v-form>
              <v-layout row wrap>
                <v-combobox
                  id="serviceSearch"
                  :loading="searchLoading"
                  :items="typeAhead"
                  :search-input.sync="input"
                  v-model="filter"
                  flat
                  append-icon=""
                  hide-no-data
                  :suffix="queryBy"
                  :hint="hint"
                  :label="$t('searchDubboService')"
                  @keyup.enter="submit"
                ></v-combobox>
                <v-menu class="hidden-xs-only">
                  <v-btn slot="activator" large icon>
                    <v-icon>unfold_more</v-icon>
                  </v-btn>

                  <v-list>
                    <v-list-tile
                      v-for="(item, i) in items"
                      :key="i"
                      @click="selected = i">
                      <v-list-tile-title >{{ $t(item.title) }}</v-list-tile-title>
                    </v-list-tile>
                  </v-list>
                </v-menu>
                <v-btn @click="submit" color="primary" large>{{ $t('search') }}</v-btn>
              </v-layout>
            </v-form>
          </v-card-text>
        </v-card>
      </v-flex>
    </v-layout>

    <v-flex lg12>
      <v-card>
        <v-toolbar flat color="transparent" class="elevation-0">
          <v-toolbar-title><span class="headline">{{$t('searchResult')}}</span></v-toolbar-title>
          <v-spacer></v-spacer>
        </v-toolbar>

        <v-card-text class="pa-0">
          <template>
            <v-data-table
              class="elevation-0 table-striped"
              :pagination.sync="pagination"
              :total-items="totalItems"
              :headers="headers"
              :items="services"
              :loading="loadingServices"
            >
              <template slot="items" slot-scope="props">
                <td >{{props.item.service}}</td>
                <td>{{props.item.group}}</td>
                <td>{{props.item.version}}</td>
                <td>{{props.item.appName}}</td>
                <td>{{props.item.registrySource}}</td>
                <td class="text-xs-center px-0" nowrap>
                  <v-btn
                    class="tiny"
                    color='success'
                    :href='getHref(props.item.service, props.item.appName, props.item.group, props.item.version,props.item.registrySource)'
                  >
                   {{ $t('detail') }}
                  </v-btn>
                  <v-btn
                    small
                    class="tiny"
                    outline
                    :href='toTestService(props.item)'
                  >
                    {{$t('test')}}
                  </v-btn>
                  <v-menu
                  >
                    <v-btn
                      slot="activator"
                      class="tiny"
                      outline
                      small
                    >
                      {{ $t('more') }}
                      <v-icon class="tiny-icon" >arrow_drop_down</v-icon>
                    </v-btn>
                    <v-list>
                      <v-list-tile
                        v-for="(item, i) in options"
                        :key="i"
                        :href='governanceHref(item.value, props.item.service, props.item.appName, props.item.group, props.item.version,props.item.registrySource)'
                      >
                        <v-list-tile-title class="small-list">{{ $t(item.title) }}</v-list-tile-title>
                      </v-list-tile>
                    </v-list>
                  </v-menu>
                </td>
              </template>
            </v-data-table>
          </template>
          <v-divider></v-divider>
        </v-card-text>
      </v-card>
    </v-flex>
  </v-container>
</template>
<script>
export default {
  data: () => ({
    items: [
      { id: 0, title: 'serviceName', value: 'service' },
      { id: 1, title: 'ip', value: 'ip' },
      { id: 2, title: 'app', value: 'application' }
    ],
    options: [
      {
        title: 'routingRule',
        value: 'routingRule'
      },
      {
        title: 'tagRule',
        value: 'tagRule'
      },
      {
        title: 'dynamicConfig',
        value: 'config'
      },
      {
        title: 'accessControl',
        value: 'access'
      },
      {
        title: 'weightAdjust',
        value: 'weight'
      },
      {
        title: 'loadBalance',
        value: 'loadbalance'
      }
    ],
    timerID: null,
    searchLoading: false,
    selected: 0,
    input: null,
    typeAhead: [],
    resultPage: {},
    filter: '',
    headers: [],
    pagination: {
      page: 1,
      rowsPerPage: 10 // -1 for All
    },
    totalItems: 0,
    loadingServices: false
  }),
  computed: {
    queryBy () {
      return this.$t('by') + this.$t(this.items[this.selected].title)
    },
    // eslint-disable-next-line vue/return-in-computed-property
    hint () {
      if (this.selected === 0) {
        return this.$t('serviceSearchHint')
      } else if (this.selected === 1) {
        return this.$t('ipSearchHint')
      } else if (this.selected === 2) {
        return this.$t('appSearchHint')
      }
    },
    area () {
      return this.$i18n.locale
    },
    services () {
      if (!this.resultPage || !this.resultPage.content) {
        return []
      }
      const instanceRegistry = this.$t('instanceRegistry')
      const interfaceRegistry = this.$t('interfaceRegistry')
      return this.resultPage.content.filter(function (item) {
        if (item.registrySource === 'INSTANCE') {
          item.registrySource = instanceRegistry
        }
        if (item.registrySource === 'INTERFACE') {
          item.registrySource = interfaceRegistry
        }
        return item
      })
    }
  },
  watch: {
    input (val) {
      this.querySelections(val)
    },
    area () {
      this.setHeaders()
    },
    pagination: {
      handler (newVal, oldVal) {
        if (newVal.page === oldVal.page && newVal.rowsPerPage === oldVal.rowsPerPage) {
          return
        }
        const filter = this.$route.query.filter || '*'
        const pattern = this.$route.query.pattern || 'service'
        this.search(filter, pattern, false)
      },
      deep: true
    }
  },
  methods: {
    setHeaders: function () {
      this.headers = [
        {
          text: this.$t('serviceName'),
          value: 'service',
          align: 'left'
        },
        {
          text: this.$t('group'),
          value: 'group',
          align: 'left'
        },
        {
          text: this.$t('version'),
          value: 'version',
          align: 'left'
        },
        {
          text: this.$t('app'),
          value: 'application',
          align: 'left'
        },
        {
          text: this.$t('registrySource'),
          value: 'registry',
          align: 'left'
        },
        {
          text: this.$t('operation'),
          value: 'operation',
          sortable: false,
          width: '110px'
        }
      ]
    },
    querySelections (v) {
      if (this.timerID) {
        clearTimeout(this.timerID)
      }
      // Simulated ajax query
      this.timerID = setTimeout(() => {
        if (v && v.length >= 4) {
          this.searchLoading = true
          if (this.selected === 0) {
            this.typeAhead = this.$store.getters.getServiceItems(v)
          } else if (this.selected === 2) {
            this.typeAhead = this.$store.getters.getAppItems(v)
          }
          this.searchLoading = false
          this.timerID = null
        } else {
          this.typeAhead = []
        }
      }, 500)
    },
    getHref: function (service, app, group, version) {
      let query = 'service=' + service + '&app=' + app
      if (group !== null) {
        query = query + '&group=' + group
      }
      if (version != null) {
        query = query + '&version=' + version
      }
      return '#/serviceDetail?' + query
    },
    governanceHref: function (type, service, appName, group, version) {
      const base = '#/governance/' + type
      let query = service
      if (type === 'tagRule') {
        query = appName
      }
      if (group !== null) {
        query = query + '&serviceGroup=' + group
      }
      if (version !== null) {
        query = query + '&serviceVersion=' + version
      }
      if (type === 'tagRule') {
        return base + '?application=' + query
      }
      return base + '?service=' + query
    },
    submit () {
      this.filter = document.querySelector('#serviceSearch').value.trim()
      if (this.filter) {
        const pattern = this.items[this.selected].value
        this.search(this.filter, pattern, true)
      } else {
        return false
      }
    },
    search: function (filter, pattern, rewrite) {
      const page = this.pagination.page - 1
      const size = this.pagination.rowsPerPage === -1 ? this.totalItems : this.pagination.rowsPerPage
      this.loadingServices = true
      this.$axios.get('/service', {
        params: {
          pattern,
          filter,
          page,
          size
        }
      }).then(response => {
        this.resultPage = response.data
        this.totalItems = this.resultPage.totalElements
        if (rewrite) {
          this.$router.push({ path: 'service', query: { filter: filter, pattern: pattern } })
        }
      }).finally(() => {
        this.loadingServices = false
      })
    },
    toTestService (item) {
      const base = '#/test'
      let query = '?service=' + item.service
      if (item.group) {
        query = query + '&group=' + item.group
      }
      if (item.version) {
        query = query + '&version=' + item.version
      }
      return base + query
    }
  },
  mounted: function () {
    this.setHeaders()
    this.$store.dispatch('loadServiceItems')
    this.$store.dispatch('loadAppItems')
    const query = this.$route.query
    let filter = null
    let pattern = null
    Object.keys(query).forEach(function (key) {
      if (key === 'filter') {
        filter = query[key]
      }
      if (key === 'pattern') {
        pattern = query[key]
      }
    })
    if (filter != null && pattern != null) {
      this.filter = filter
      if (pattern === 'service') {
        this.selected = 0
      } else if (pattern === 'application') {
        this.selected = 2
      } else if (pattern === 'ip') {
        this.selected = 1
      }
      this.search(filter, pattern, false)
    } else {
      // display all existing services by default
      this.filter = '*'
      this.selected = 0
      pattern = 'service'
      this.search(this.filter, pattern, true)
    }
  }

}
</script>

<style scoped>
  table.v-table tbody td {
    word-break: break-all;
  }

  .tiny {
    min-width: 30px;
    height: 20px;
    font-size: 8px;
  }

  .tiny-icon {
    font-size: 18px;
  }

  .small-list {
    font-size: 10px;
  }

</style>
