<!--
  ~ 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="18">
          <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="6">
          <a-flex style="justify-content: flex-end;">
            <slot name="customOperation"></slot>
            <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-flex>
        </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, useSlots } 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 customOperation = !!useSlots().customOperation;

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: 20px;
      }
    }
  }
}
</style>
<style lang="less"></style>
