<script setup lang="ts">
import { ref, nextTick, onMounted } from 'vue'
import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
import DownloadDialog from './components/DownloadDialog.vue'
import { autoWidth } from '@/utils/table'
import { useRowClickStyle } from '@/hooks/rowClickStyle'
import dayjs from 'dayjs'

const props = defineProps({
  height: {
    type: Number,
    default: 440
  }
})

const tableOriginColumnsField = ref()
const handleColumns = (columns: any, status?: string) => {
  const newColumns = columns.map((item: any) => {
    let curColumn: any = {
      title: item.title,
      field: item.field,
      sortable: true,
      minWidth: 120
    }
    // 设置插槽
    if (item.type === 'status' && status !== 'all') {
      curColumn = {
        ...curColumn,
        slots: { default: 'status' }
      }
    } else if (item.type === 'link' && status !== 'all') {
      curColumn = {
        ...curColumn,
        slots: { default: 'link' }
      }
    } else if (item.type === 'mode' && status !== 'all') {
      curColumn = {
        ...curColumn,
        slots: { default: 'mode' },
        formatter: ({ cellValue }: any) => {
          return cellValue
        }
      }
    }
    // 格式化
    if (item.formatter === 'date') {
      curColumn = {
        ...curColumn,
        formatter: ({ cellValue }: any) =>
          cellValue ? dayjs(cellValue).format('MMM-DD-YYYY ') : '--'
      }
    } else if (item.formatter === 'dateTime') {
      curColumn = {
        ...curColumn,
        formatter: ({ cellValue }: any) =>
          cellValue ? dayjs(cellValue).format('YYYY/MM/DD HH:mm:ss') : '--'
      }
    }
    return curColumn
  })
  return newColumns
}

// 获取表格列
const getTableColumns = async () => {
  tableLoadingColumn.value = true
  await $api.getOperationTableColumns().then((res: any) => {
    if (res.code === 200) {
      bookingTable.value.columns = [
        { type: 'checkbox', width: 50, fixed: 'left' },
        ...handleColumns(res.data.OperationTableColumns)
      ]
      tableOriginColumnsField.value = res.data.OperationTableColumns
    }
  })
  nextTick(() => {
    // tableRef.value && autoWidth(bookingTable.value, tableRef.value)
    tableLoadingColumn.value = false
    selectedNumber.value = 0
    selectedTableData.value = []
  })
}

const pageInfo = ref({ pageNo: 1, pageSize: 20, total: 0 })
const tempSearch = ref()
// 获得表格数据后赋值
const assignTableData = (data: any) => {
  bookingTable.value.data = data.searchData || []
  pageInfo.value.total = Number(data.rc) || 0
  tempSearch.value = data.tmp_search
  // 拥有所有字段的表格
  setTimeout(() => {
    allTable.value.columns = handleColumns(bookingTable.value.columns, 'all')
    allTable.value.data = data.searchData || []
    // 为了让导出的表格列宽度自适应
    nextTick(() => {
      // allTableRef.value && autoWidth(allTable.value, allTableRef.value)
    })
  }, 1000)
}

let searchdata: any = {}
// 获取表格数据
const getTableData = async (isPageChange?: boolean) => {
  const rc = isPageChange ? pageInfo.value.total : -1
  tableLoadingTableData.value = true
  await $api
    .SearchOperationLog({
      cp: pageInfo.value.pageNo,
      ps: pageInfo.value.pageSize,
      rc: -1,
      ...searchdata
    })
    .then((res: any) => {
      if (res.code === 200) {
        assignTableData(res.data)
      }
    })
    .finally(() => {
      selectedNumber.value = 0
      selectedTableData.value = []
      nextTick(() => {
        // tableRef.value && autoWidth(bookingTable.value, tableRef.value)
        tableLoadingTableData.value = false
      })
    })
}
const SearchOperationLog = (val: any) => {
  searchdata = val
  tableLoadingTableData.value = true
  $api
    .SearchOperationLog({
      cp: pageInfo.value.pageNo,
      ps: pageInfo.value.pageSize,
      rc: -1,
      ...val
    })
    .then((res: any) => {
      if (res.code === 200) {
        assignTableData(res.data)
      }
    })
    .finally(() => {
      selectedNumber.value = 0
      selectedTableData.value = []
      nextTick(() => {
        // tableRef.value && autoWidth(bookingTable.value, tableRef.value)
        tableLoadingTableData.value = false
      })
    })
}
onMounted(() => {
  Promise.all([getTableColumns(), getTableData()]).finally(() => {
    nextTick(() => {
      // tableRef.value && autoWidth(bookingTable.value, tableRef.value)
    })
  })
})

const tableRef = ref<VxeGridInstance>()
const bookingTable = ref<VxeGridProps<any>>({
  border: true,
  round: true,
  columns: [],
  data: [],
  scrollY: { enabled: true, oSize: 20, gt: 30 },
  stripe: true,
  emptyText: ' ',
  showHeaderOverflow: true,
  showOverflow: true,
  headerRowStyle: {
    backgroundColor: 'var(--color-table-header-bg)'
  },
  sortConfig: {
    sortMethod: (params) => {
      const { data, sortList } = params

      // 如果没有排序条件，直接返回原数据
      if (sortList.length === 0) return data

      // 对数据进行多重排序
      const sortedData = [...data].sort((a, b) => {
        for (const { field, order } of sortList) {
          const curColumn = tableOriginColumnsField.value.find((item: any) => item.field === field)
          if (!curColumn) continue

          const typeName = curColumn.type
          const aValue = a[field]
          const bValue = b[field]

          const compareResult = (aValue: any, bValue: any) => {
            // 如果 aValue 或 bValue 是 null 或 undefined，优先处理这些值
            if (aValue == null && bValue == null) {
              return 0 // 如果两个值都为 null 或 undefined，视为相等
            } else if (aValue == null) {
              return -1 // 如果 aValue 是 null，bValue 不是，则将 aValue 视为较小值
            } else if (bValue == null) {
              return 1 // 如果 bValue 是 null，aValue 不是，则将 bValue 视为较小值
            }

            if (typeName === 'datetime' || typeName === 'date' || typeName === 'time') {
              return dayjs(aValue).unix() - dayjs(bValue).unix()
            } else if (isNaN(Number(aValue)) || isNaN(Number(bValue))) {
              return aValue.localeCompare(bValue)
            } else {
              return Number(aValue) - Number(bValue)
            }
          }

          const result = compareResult(aValue, bValue)
          if (result !== 0) {
            return order === 'asc' ? result : -result
          }
        }

        return 0 // 如果所有字段都相等
      })

      return sortedData
    }
  },
  columnConfig: { resizable: true, useKey: true },
  rowConfig: { isHover: true },
  exportConfig: {
    types: ['csv', 'html', 'txt', 'xlsx'],
    modes: ['current', 'selected', 'all']
  }
})
const allTableRef = ref<VxeGridInstance>()
const allTable = ref<VxeGridProps<any>>({
  columns: [],
  data: [],
  showHeaderOverflow: true,
  showOverflow: true,
  scrollY: { enabled: true, oSize: 5, gt: 2 },
  scrollX: { enabled: true, gt: 2 },
  exportConfig: {
    types: ['csv', 'html', 'txt', 'xlsx'],
    modes: ['current', 'selected', 'all']
  }
})

// 实现行点击样式
useRowClickStyle(tableRef)

const downloadDialogRef = ref()
const handleDownload = () => {
  const curSelectedColumns: string[] = []
  tableRef.value?.columns?.forEach((item: any) => {
    if (item.field) {
      curSelectedColumns.push(item.title)
    }
  })
  downloadDialogRef.value.openDialog(
    curSelectedColumns,
    selectedNumber.value || pageInfo.value.total
  )
}

const exportLoading = ref(false)
// 获取导出表格数据
const getExportTableData = (status: number) => {
  // 如果有选中表格行数据，那么只到处选中的数据
  if (selectedNumber.value > 0) {
    exportTable(status)
    return
  }
  exportLoading.value = true
  const buildColumnString = (columns: any[]): string => {
    return columns
      .filter((item) => item.field)
      .map((item) => item.title)
      .join(',')
  }

  let column = ''
  if (status === 1) {
    column = buildColumnString(bookingTable.value.columns)
  } else {
    column = buildColumnString(allTable.value.columns)
  }
  $api
    .OperationLogDownload({
      selected_fields: column,
      tmp_search: tempSearch.value
    })
    .then((res: any) => {
      if (res.code === 200) {
        allTable.value.data = res.data.Data || []
        nextTick(() => {
          exportLoading.value = false
          // 导出数据
          exportTable(status)
        })
      }
    })
    .finally(() => {
      exportLoading.value = false
    })
}
// 导出表格 status: 1 导出当前表格 2 导出所有字段表格
const exportTable = (status: number) => {
  const exportConfig: any = {
    type: 'xlsx',
    message: false,
    filename: `Opeartion Log_${dayjs().format('YYYYMMDDHH[h]mm[m]ss[s]')}`
  }
  if (status === 1) {
    exportConfig.columnFilterMethod = ({ column }: any) => {
      const index = bookingTable.value.columns.findIndex((item: any) => item.field === column.field)
      // 排除复选框列
      return column.field && index !== -1
    }
    exportConfig.columns = bookingTable.value.columns
  }
  if (selectedNumber.value > 0) {
    exportConfig.dataFilterMethod = ({ row }: any) => {
      const index = selectedTableData.value.findIndex(
        (item: any) => item._X_ROW_KEY === row._X_ROW_KEY
      )
      return index !== -1
    }
  }
  allTableRef.value?.exportData(exportConfig)
}

const tableLoadingColumn = ref(false)
const tableLoadingTableData = ref(false)

const selectedNumber = ref(0)
const selectedTableData = ref([])
// 复选框选中事件
const handleCheckboxChange = ({ records }: any) => {
  selectedNumber.value = records.length
  selectedTableData.value = records
}
const handleCheckAllChange = ({ records }: any) => {
  selectedNumber.value = records.length
  selectedTableData.value = records
}
defineExpose({
  SearchOperationLog
})
</script>

<template>
  <div
    style="padding: 0px 20px"
    class="booking-table"
    v-loading.fullscreen.lock="exportLoading"
    element-loading-background="rgb(43, 47, 54, 0.7)"
  >
    <div class="table-tools">
      <div class="left-total-records">{{ selectedNumber }} Selected</div>
      <div class="right-tools-btn">
        <el-button class="el-button--main" @click="handleDownload">
          <span style="margin-right: 8px" class="font_family icon-icon_download_b"></span>
          Download
        </el-button>
      </div>
    </div>
    <vxe-grid
      ref="tableRef"
      v-vloading="tableLoadingTableData || tableLoadingColumn"
      :height="props.height"
      :style="{ border: 'none' }"
      v-bind="bookingTable"
      @checkbox-change="handleCheckboxChange"
      @checkbox-all="handleCheckAllChange"
    >
      <!-- 空数据时的插槽 -->
      <template #empty v-if="!tableLoadingTableData && bookingTable.data.length === 0">
        <VEmpty>
          <template #suggestion>
            <p style="color: var(--color-neutral-3)">
              We support the following references number to find booking:
            </p>
            <p style="color: var(--color-neutral-3)">
              · Booking No./HAWB No./MAWB No./PO No./Carrier Booking No./Contract No./File No./Quote
              No.
            </p>
          </template>
        </VEmpty>
      </template>
    </vxe-grid>
    <vxe-grid :height="10" ref="allTableRef" class="all-table" v-bind="allTable"> </vxe-grid>
    <div class="bottom-pagination">
      <div class="left-total-records">Total {{ pageInfo.total }}</div>
      <div class="right-pagination">
        <el-pagination
          v-model:current-page="pageInfo.pageNo"
          v-model:page-size="pageInfo.pageSize"
          :page-sizes="[20, 50, 100, 150]"
          :pager-count="3"
          background
          layout="sizes, prev, pager, next"
          :total="pageInfo.total"
          @size-change="getTableData(true)"
          @current-change="getTableData(true)"
        />
      </div>
    </div>
    <DownloadDialog @export="getExportTableData" ref="downloadDialogRef" />
  </div>
</template>

<style lang="scss" scoped>
.table-tools {
  position: relative;
  display: flex;
  justify-content: space-between;
  height: 48px;
  padding: 8px 0;

  .left-total-records {
    font-size: 16px;
    font-weight: 700;
    line-height: 32px;
  }
}

.bottom-pagination {
  display: flex;
  justify-content: space-between;
  height: 40px;
  margin-top: -1px;
  padding: 4px 8px;
  border: 1px solid var(--color-border);
  border-radius: 0 0 12px 12px;

  .left-total-records {
    line-height: 32px;
  }

  .right-pagination {
    display: flex;
    align-items: center;
  }
}
.booking-table {
  position: relative;
  overflow: hidden;

  .all-table {
    position: absolute;
    top: -100000px;
    width: 20px;
  }
}
</style>
