<!--
  ~ 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>
  <div class="__container_search_table">
    <div class="search-query-container">
      <a-row>
        <a-col :span="20">
          <a-form>
            <a-flex wrap="wrap" gap="large">
              <template v-for="q in searchDomain.params">
                <a-form-item :label="$t(q.label)">
                  <template v-if="q.dict && q.dict.length > 0">
                    <a-radio-group
                      button-style="solid"
                      v-model:value="searchDomain.queryForm[q.param]"
                      v-if="q.dictType === 'BUTTON'"
                    >
                      <a-radio-button v-for="item in q.dict" :value="item.value">
                        {{ $t(item.label) }}
                      </a-radio-button>
                    </a-radio-group>
                    <a-select
                      v-else
                      class="select-type"
                      :style="q.style"
                      v-model:value="searchDomain.queryForm[q.param]"
                    >
                      <a-select-option
                        :value="item.value"
                        v-for="item in [...q.dict, { label: 'none', value: '' }]"
                      >
                        {{ $t(item.label) }}
                      </a-select-option>
                    </a-select>
                  </template>

                  <a-input
                    v-else
                    :style="q.style"
                    :placeholder="$t('placeholder.' + (q.placeholder || `typeDefault`))"
                    v-model:value="searchDomain.queryForm[q.param]"
                  ></a-input>
                </a-form-item>
              </template>
              <a-form-item :label="''">
                <a-button type="primary" @click="searchDomain.onSearch()">
                  <Icon
                    style="margin-bottom: -2px; font-size: 1.3rem"
                    icon="ic:outline-manage-search"
                  ></Icon>
                </a-button>
              </a-form-item>
            </a-flex>
          </a-form>
        </a-col>
        <a-col :span="4">
          <div class="common-tool">
            <a-dropdown placement="bottom" :trigger="['click']">
              <div class="custom-column button">
                <Icon icon="material-symbols-light:format-list-bulleted-rounded"></Icon>
              </div>

              <template #overlay>
                <a-card title="Custom Column">
                  <a-menu>
                    <a-menu-item>
                      <Icon
                        style="margin-bottom: -3px; font-size: 1rem"
                        icon="material-symbols-light:format-list-bulleted-rounded"
                      ></Icon>
                      3
                    </a-menu-item>
                  </a-menu>
                </a-card>
              </template>
            </a-dropdown>
          </div>
        </a-col>
      </a-row>
    </div>

    <div class="search-table-container">
      <a-table
        :loading="searchDomain.table.loading"
        :pagination="pagination"
        :scroll="{
          scrollToFirstRowOnChange: true,
          y: searchDomain.tableStyle?.scrollY || '',
          x: searchDomain.tableStyle?.scrollX || ''
        }"
        :columns="searchDomain?.table.columns"
        :data-source="searchDomain?.result"
        @change="handleTableChange"
      >
        <template #bodyCell="{ text, record, index, column }">
          <span v-if="column.key === 'idx'">{{ index + 1 }}</span>
          <slot
            name="bodyCell"
            :text="text"
            :record="record"
            :index="index"
            :column="column"
            v-else
          >
          </slot>
        </template>
      </a-table>
    </div>
  </div>
</template>

<script setup lang="ts">
import type { ComponentInternalInstance } from 'vue'
import { computed, getCurrentInstance, inject, reactive } from 'vue'

import { PROVIDE_INJECT_KEY } from '@/base/enums/ProvideInject'
import type { SearchDomain } from '@/utils/SearchUtil'
import { Icon } from '@iconify/vue'
import { PRIMARY_COLOR } from '@/base/constants'

const commonTool = reactive({
  customColumns: false
})
let __ = PRIMARY_COLOR

const {
  appContext: {
    config: { globalProperties }
  }
} = <ComponentInternalInstance>getCurrentInstance()

const searchDomain: SearchDomain | any = inject(PROVIDE_INJECT_KEY.SEARCH_DOMAIN)
searchDomain.table.columns.forEach((column: any) => {
  if (column.title) {
    const tmp = column.title
    column.title = computed(() => globalProperties.$t(tmp))
  }
})
const pagination = computed(() => {
  console.log(pagination)
  return {
    pageSize: searchDomain.paged.pageSize,
    current: searchDomain.paged.curPage,
    showTotal: (v: any) =>
      globalProperties.$t('searchDomain.total') +
      ': ' +
      v +
      ' ' +
      globalProperties.$t('searchDomain.unit')
  }
})

const handleTableChange = (
  pag: { pageSize: number; current: number },
  filters: any,
  sorter: any
) => {
  searchDomain.paged.pageSize = pag.pageSize
  searchDomain.paged.curPage = pag.current
  searchDomain.onSearch()
  return
}
</script>
<style lang="less" scoped>
.__container_search_table {
  .search-query-container {
    border-radius: 10px 10px 0 0;
    border-bottom: 1px solid rgba(220, 219, 219, 0.29);
    background: #fafafa;
    padding: 20px 20px 0 20px;
    //margin-bottom: 20px;
  }

  .select-type {
    width: 200px;
  }

  :deep(.ant-pagination) {
    padding: 0 10px 20px 0;
  }

  :deep(.ant-spin-container) {
    background: #fafafa;
  }

  :deep(.ant-popover-arrow) {
    display: none;
  }

  .common-tool {
    margin-top: 5px;

    .button {
      vertical-align: center;
      line-height: 24px;
      font-size: 24px;
      float: right;

      &:hover {
        color: v-bind('PRIMARY_COLOR');
      }

      svg {
        margin-left: 10px;
      }
    }
  }
}
</style>
<style lang="less"></style>
