<template>
  <div>
    <PageFilters ref="pageFilters" :filter-conditions="props.filterConditions" @on-filter="confirmFilter" />
    <div class="mx-[14px] mt-[12px] p-[16px] bg-white">
      <div class="flex justify-between items-center" v-if="showTableHeader">
        <div class="header-left">
          <slot name="header-left"></slot>
        </div>
        <div class="header-right">
          <div class="flex items-center justify-end gap-2">
            <t-button v-if="props.showSetting" variant="outline" @click="columnControllerVisible = true">
              <template #icon><SettingIcon /></template>列配置
            </t-button>
            <slot name="header-right"></slot>
          </div>
        </div>
      </div>
      <!-- table -->
      <div class="mt-[16px]">
        <slot name="table"></slot>
        <div v-if="showTable">
          <t-table
            v-bind="tableProps"
            v-model:column-controller-visible="columnControllerVisible"
            :row-key="rowKey"
            :data="tableData"
            :columns="columns"
            :column-controller="columnControllerConfig"
            :loading="loading"
            :loading-props="loadingProps"
            max-height="585"
            @filter-change="onFilterChange"
            @sort-change="onSortChange"
          >
            <!-- 为每一列创建动态插槽 -->
            <template v-for="col in columns" #[col.colKey]="{ row }" :key="col.colKey">
              <!-- <component :is="col.render" v-bind="row" v-if="col.render" /> -->
              <template v-if="col.colKey != 'operation'">
                <t-tooltip
                  :content="String(row[col.colKey])"
                  placement="top"
                  theme="light"
                  overlay-class-name="custom-tooltip"
                >
                  <div class="cell-content">{{ row[col.colKey] }}</div>
                </t-tooltip>
              </template>
            </template>

            <!-- 保留自定义列插槽 -->
            <template v-for="(_, name) in $slots" #[name]="scope">
              <slot :name="name" v-bind="scope" />
            </template>
          </t-table>
        </div>
      </div>
      <!-- 分页 -->
      <div v-if="showPagination" class="mt-[32px]">
        <t-pagination
          v-model="pageInfo.page"
          v-model:page-size="pageInfo.limit"
          :total="pageInfo.total"
          show-sizer
          show-jumper
          :page-size-options="pageSizeOptions"
          @change="onChange"
          class="reset-pagination"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { AxiosRequestConfig } from 'axios'
import { PaginationProps, TableProps, PrimaryTableCol, LoadingProps } from 'tdesign-vue-next'
import { filterItemProp } from '@/components/PageFilters/interface/index'
import { ResultData } from '@/api/interface'
import { isFunction } from '@/utils/is/index'

defineOptions({
  name: 'PageContainer'
})

onMounted(() => {
  getData()
})
type Slots = Record<'table' | 'header-left' | 'header-right', () => VNode> & Record<string, () => VNode>
const slots = defineSlots<Slots>()
const showTableHeader = computed(() => isFunction(slots['header-left']) || isFunction(slots['header-right']))
const showTable = computed(() => !isFunction(slots.table))
const pageFilters = ref()
interface Pageable {
  page: number
  limit: number
  total: number
}
interface PageFiltersProps {
  filterConditions: filterItemProp[]
  showPagination?: boolean
  rowKey?: string
  showSetting?: boolean // 是否显示列配置按钮
  requestApi: (params: any, config?: AxiosRequestConfig) => Promise<ResultData>
  tableProps?: Partial<TableProps> // t-table 原生属性
  columns?: PrimaryTableCol[] // 表格列配置
}
const props = withDefaults(defineProps<PageFiltersProps>(), {
  filterConditions: () => [],
  showSetting: false,
  showPagination: true,
  rowKey: 'id',
  tableProps: () => ({ hover: true, resizable: true }),
  columns: () => []
})
// 组件事件
const emit = defineEmits<{
  'filter-change': [filters: Record<string, any>]
  'search-change': [params: Record<string, any>]
  'sort-change': [sort: Record<string, any>]
}>()
const columnControllerVisible = ref(false)
const columnControllerConfig = computed<TableProps['columnController']>(() => ({
  hideTriggerButton: true,
  placement: 'top-right',
  dialogProps: { preventScrollThrough: true },
  fields: props.columns.map(item => item.colKey) as string[],
  ...props.tableProps?.columnController
}))

const tableData = ref<any>([])
// 搜索后查询数据
const confirmFilter = () => {
  pageInfo.page = 1
  getData()
}
const loading = ref(false)
const loadingProps = ref<LoadingProps>({
  text: '加载中',
  size: '24px'
})
const getData = async () => {
  const params = pageFilters.value.resetFilterConditions()
  loading.value = true
  tableData.value = Array(5)
    .fill(0)
    .map((_, index) => {
      // 生成随机手机号
      const parentMenuName = `139${Math.floor(Math.random() * 100000000)
        .toString()
        .padStart(8, '0')}`
      return {
        id: index + 1,
        menuName: `用户${Math.floor(Math.random() * 1000 + 1)}`,
        parentMenuName,
        sortNumber: Math.random() > 0.5 ? 1 : 2,
        inputTime: '2024-03-21 12:00:00',
        onlyid: '这里是钉钉这里是'
      }
    })
  try {
    const res = await props.requestApi({ ...pageInfo, ...params })
    console.log(res)
    pageInfo.total = res.recordsFiltered ?? 0
    tableData.value = res.data ?? []
  } finally {
    loading.value = false
  }
}

// 分页切换
const pageInfo: Pageable = reactive({
  page: 1,
  limit: 10,
  total: 0
})
const pageSizeOptions: PaginationProps['pageSizeOptions'] = [
  {
    label: '每页 10 条',
    value: 10
  },
  {
    label: '每页 15 条',
    value: 15
  },
  {
    label: '每页 30 条',
    value: 30
  },
  {
    label: '每页 100 条',
    value: 100
  }
]
const onChange: PaginationProps['onChange'] = async ({ pageSize, current }) => {
  pageInfo.page = current
  pageInfo.limit = pageSize
  getData()
}
// 处理表格列筛选变化
const onFilterChange = (filters: any) => {
  emit('filter-change', filters)
}
// 处理排序变化
const onSortChange: TableProps['onSortChange'] = val => {
  emit('sort-change', val)
}

defineExpose({
  getData,
  tableData
})
</script>

<style lang="less" scoped>
:deep(.reset-pagination) {
  .t-pagination__jump {
    background-color: var(--white);
    color: var(--td-font-gray-1);

    .t-input-adornment__text {
      color: var(--td-font-gray-1);
    }
  }

  .t-pagination__total {
    margin-right: 20px;
    text-align: right;
  }
}

:deep(.t-table__header--fixed) {
  &:not(.t-table__header--multiple) > tr > th {
    background-color: var(--white);
  }
}
</style>
