// 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.
<!--
  InfiniteScrollSelect.vue

  A reusable select component that supports:
  - Infinite scrolling with paginated API
  - Dynamic search filtering. Needs minimum
  - Deduplicated option loading
  - Auto-fetching of preselected value if not present in the initial result

  Usage Example:

  <infinite-scroll-select
    v-model:value="form.account"
    api="listAccounts"
    :apiParams="accountsApiParams"
    resourceType="account"
    optionValueKey="name"
    optionLabelKey="name"
    @change-option-value="handleAccountNameChange" />

  Props:
  - api (String, required): API command name (e.g., 'listAccounts')
  - apiParams (Object, optional): Additional parameters passed to the API
  - resourceType (String, required): The key in the API response containing the resource array (e.g., 'account')
  - optionValueKey (String, optional): Property to use as the value for options (e.g., 'name'). Default is 'id'
  - optionLabelKey (String, optional): Property to use as the label for options (e.g., 'name'). Default is 'name'
  - defaultOption (Object, optional): Preselected object to include initially
  - showIcon (Boolean, optional): Whether to show icon for the options. Default is true
  - defaultIcon (String, optional): Icon to be shown when there is no resource icon for the option. Default is 'cloud-outlined'

  Events:
  - @change-option-value (Function): Emits the selected option value(s) when value(s) changes. Do not use @change as it will give warnings and may not work
  - @change-option (Function): Emits the selected option object when value changes. Works only when mode is not multiple

  Features:
  - Debounced remote filtering
  - Custom dropdown footer/header (e.g., clear search button)
  - Handles preselection and fetches missing option automatically
-->
<template>
  <a-select
    :filter-option="false"
    :loading="loading"
    show-search
    placeholder="Select"
    @search="onSearchTimed"
    @popupScroll="onScroll"
    @change="onChange"
  >
    <template #dropdownRender="{ menuNode: menu }">
      <v-nodes :vnodes="menu" />
      <div v-if="!!searchQuery">
        <a-divider style="margin: 4px 0" />
        <div class="select-list-footer">
          <span>{{ formattedSearchFooterMessage }}</span>
          <close-outlined
            @mousedown="e => e.preventDefault()"
            @click="onSearch()" />
        </div>
      </div>
    </template>
    <a-select-option v-for="option in options" :key="option.id" :value="option[optionValueKey]">
      <span>
        <span v-if="showIcon">
          <resource-icon v-if="option.icon && option.icon.base64image" :image="option.icon.base64image" size="1x" style="margin-right: 5px"/>
          <render-icon v-else :icon="defaultIcon" style="margin-right: 5px" />
        </span>
        <span>{{ option[optionLabelKey] }}</span>
      </span>
    </a-select-option>
  </a-select>
</template>

<script>
import { api } from '@/api'
import ResourceIcon from '@/components/view/ResourceIcon'

export default {
  name: 'InfiniteScrollSelect',
  components: {
    ResourceIcon,
    VNodes: (_, { attrs }) => {
      return attrs.vnodes
    }
  },
  props: {
    api: {
      type: String,
      required: true
    },
    apiParams: {
      type: Object,
      required: null
    },
    resourceType: {
      type: String,
      required: true
    },
    optionValueKey: {
      type: String,
      default: 'id'
    },
    optionLabelKey: {
      type: String,
      default: 'name'
    },
    defaultOption: {
      type: Object,
      default: null
    },
    showIcon: {
      type: Boolean,
      default: true
    },
    defaultIcon: {
      type: String,
      default: 'cloud-outlined'
    },
    pageSize: {
      type: Number,
      default: null
    }
  },
  data () {
    return {
      options: [],
      page: 1,
      totalCount: null,
      loading: false,
      searchQuery: '',
      searchTimer: null,
      scrollHandlerAttached: false,
      preselectedOptionValue: null,
      successiveFetches: 0
    }
  },
  created () {
    this.addDefaultOptionIfNeeded(true)
  },
  mounted () {
    this.preselectedOptionValue = this.$attrs.value
    this.fetchItems()
  },
  computed: {
    maxSuccessiveFetches () {
      return 10
    },
    computedPageSize () {
      return this.pageSize || this.$store.getters.defaultListViewPageSize
    },
    formattedSearchFooterMessage () {
      return `${this.$t('label.showing.results.for').replace('%x', this.searchQuery)}`
    }
  },
  watch: {
    apiParams () {
      this.onSearch()
    }
  },
  emits: ['change-option-value', 'change-option'],
  methods: {
    async fetchItems () {
      if (this.successiveFetches === 0 && this.loading) return
      this.loading = true
      const params = {
        page: this.page,
        pagesize: this.computedPageSize
      }
      if (this.searchQuery && this.searchQuery.length > 0) {
        params.keyword = this.searchQuery
      }
      if (this.apiParams) {
        Object.assign(params, this.apiParams)
      }
      if (this.showIcon) {
        params.showicon = true
      }
      api(this.api, params).then(json => {
        const response = json[this.api.toLowerCase() + 'response'] || {}
        if (this.totalCount === null) {
          this.totalCount = response.count || 0
        }
        const newOpts = response[this.resourceType] || []
        const existingOptions = new Set(this.options.map(o => o[this.optionValueKey]))
        newOpts.forEach(opt => {
          if (!existingOptions.has(opt[this.optionValueKey])) {
            this.options.push(opt)
          }
        })
        this.page++
        this.checkAndFetchPreselectedOption()
      }).catch(error => {
        this.$notifyError(error)
      }).finally(() => {
        if (this.successiveFetches === 0) {
          this.loading = false
        }
      })
    },
    checkAndFetchPreselectedOption () {
      if (!this.preselectedOptionValue ||
        (Array.isArray(this.preselectedOptionValue) && this.preselectedOptionValue.length === 0) ||
        this.successiveFetches >= this.maxSuccessiveFetches) {
        this.resetPreselectedOptionValue()
        return
      }
      const matchValue = Array.isArray(this.preselectedOptionValue) ? this.preselectedOptionValue[0] : this.preselectedOptionValue
      const match = this.options.find(entry => entry[this.optionValueKey] === matchValue)
      if (!match) {
        this.successiveFetches++
        if (this.options.length < this.totalCount) {
          this.fetchItems()
        } else {
          this.resetPreselectedOptionValue()
        }
        return
      }
      if (Array.isArray(this.preselectedOptionValue) && this.preselectedOptionValue.length > 1) {
        this.preselectedOptionValue = this.preselectedOptionValue.filter(o => o !== match)
      } else {
        this.resetPreselectedOptionValue()
      }
    },
    addDefaultOptionIfNeeded () {
      if (this.defaultOption) {
        this.options.push(this.defaultOption)
      }
    },
    resetPreselectedOptionValue () {
      this.preselectedOptionValue = null
      this.successiveFetches = 0
    },
    onSearchTimed (value) {
      clearTimeout(this.searchTimer)
      this.searchTimer = setTimeout(() => {
        this.onSearch(value)
      }, 500)
    },
    onSearch (value) {
      this.searchQuery = value
      this.page = 1
      this.totalCount = null
      this.options = []
      if (!this.searchQuery) {
        this.addDefaultOptionIfNeeded()
      }
      this.fetchItems()
    },
    onScroll (e) {
      const nearBottom = e.target.scrollTop + e.target.clientHeight >= e.target.scrollHeight - 10
      const hasMore = this.options.length < this.totalCount
      if (nearBottom && hasMore && !this.loading) {
        this.fetchItems()
      }
    },
    onChange (value) {
      this.resetPreselectedOptionValue()
      this.$emit('change-option-value', value)
      if (Array.isArray(value)) {
        return
      }
      if (value === undefined || value == null) {
        this.$emit('change-option', undefined)
        return
      }
      const match = this.options.find(entry => entry[this.optionValueKey] === value)
      if (match) {
        this.$emit('change-option', match)
      }
    }
  }
}
</script>

<style lang="less" scoped>
  .select-list-footer {
    margin: 4px 10px;
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
</style>
