<script setup lang="ts">
import { transportationMode } from '@/components/TransportationMode'
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'
import { useRouter } from 'vue-router'

const router = useRouter()
const props = defineProps({
  height: {
    type: Number,
    default: 440
  },
  tagsData: {
    type: Array,
    default: () => []
  }
})

// 表格展示列的原始字段
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
    }
    // 设置插槽
    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' }
      }
    }
    // 格式化
    if (item.formatter === 'date') {
      curColumn = {
        ...curColumn,
        sortBy: ({ row, column }: any) => {
          return dayjs(row[column.field]).unix()
        },
        formatter: ({ cellValue }: any) => dayjs(cellValue).format('MMM-YYYY-DD ') || '--'
      }
    } else if (item.formatter === 'dateTime') {
      curColumn = {
        ...curColumn,
        formatter: ({ cellValue }: any) => dayjs(cellValue).format('MMM-YYYY-DD HH:mm:ss') || '--'
      }
    }
    return curColumn
  })
  return newColumns
}

// 获取表格列
const getTableColumns = async (isInit: boolean) => {
  tableLoading.value = true
  await $api.getBookingTableColumns().then((res: any) => {
    if (res.code === 200) {
      bookingTable.value.columns = [
        { type: 'checkbox', width: 50, fixed: 'left' },
        ...handleColumns(res.data.BookingTableColumns)
      ]
      tableOriginColumnsField.value = res.data.BookingTableColumns
    }
  })
  nextTick(() => {
    !isInit && (tableLoading.value = false)
  })
}

const pageInfo = ref({ pageNo: 1, pageSize: 100, total: 0 })
const TransportListItem = ref()
const TagsList = ref()

// 获取表格数据
let filterdataobj: any = {}
const getTableData = async (isInit: boolean, isPageChange?: boolean) => {
  const rc = isPageChange ? pageInfo.value.total : -1
  tableLoading.value = true
  await $api
    .getBookingTableData({
      cp: pageInfo.value.pageNo,
      ps: pageInfo.value.pageSize,
      rc,
      other_filed: '',
      ...filterdataobj
    })
    .then((res: any) => {
      if (res.code === 200) {
        bookingTable.value.data = res.data.searchData
        pageInfo.value.total = Number(res.data.rc)
        TransportListItem.value = res.data.TransportList
        TagsList.value = res.data.tagsList

        // 拥有所有字段的表格
        setTimeout(() => {
          allTable.value.columns = handleColumns(res.data.allColums, 'all')
          allTable.value.data = res.data.searchData
          nextTick(() => {
            allTableRef.value && autoWidth(allTable.value, allTableRef.value)
          })
        }, 1000)
      }
    })
  nextTick(() => {
    !isInit && (tableLoading.value = false)
  })
}
// 查询列表数据
const searchTableData = (data: any) => {
  tableLoading.value = true
  filterdataobj = data
  $api
    .getBookingTableData({
      cp: pageInfo.value.pageNo,
      ps: pageInfo.value.pageSize,
      rc: -1,
      other_filed: '',
      ...data
    })
    .then((res: any) => {
      if (res.code === 200) {
        bookingTable.value.data = res.data.searchData
        pageInfo.value.total = Number(res.data.rc)
        tableLoading.value = false
      }
    })
}

onMounted(() => {
  tableLoading.value = true
  Promise.all([getTableColumns(true), getTableData(true)]).finally(() => {
    tableLoading.value = false
    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 },
  scrollX: { enabled: true, gt: 20 },
  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(props.tagsData, curSelectedColumns)
}

// 导出表格
const exportTable = (status: number) => {
  if (status === 1) {
    tableRef.value?.exportData({
      type: 'xlsx',
      message: false,
      filename: `Booking List_${dayjs().format('YYYYMMDDHH[h]mm[m]ss[s]')}`,
      columnFilterMethod: ({ column }: any) => {
        // 排除复选框列
        return column.field
      }
    })
  } else {
    allTableRef.value?.exportData({
      type: 'xlsx',
      message: false,
      filename: `Booking List_${dayjs().format('YYYYMMDDHH[h]mm[m]ss[s]')}`
    })
  }
}

const tableLoading = ref(false)

const CustomizeColumnsRef = ref()
// 打开定制表格弹窗
const handleCustomizeColumns = () => {
  const params = {
    getData: {
      action: 'ocean_booking',
      operate: 'setting_display'
    },
    saveData: {
      action: 'ajax',
      operate: 'save_setting_display',
      model_name: 'Booking_Search'
    }
  }
  CustomizeColumnsRef.value.openDialog(params, -153)
}
// 定制表格
const customizeColumns = async () => {
  await getTableColumns(false)
  nextTick(() => {
    tableRef.value && autoWidth(bookingTable.value, tableRef.value)
  })
}

// 双击表格跳转详情页
const handleCellDblclick = ({ row }: any) => {
  router.push({
    path: '/booking/detail',
    query: { a: row.__serial_no, _schemas: row.__schemas }
  })
}
// 点击link字段是时
const handleLinkClick = (row: any, column: any) => {
  if (column.field === 'booking_no') {
    router.push({
      path: '/booking/detail',
      query: { a: row.__serial_no, _schemas: row.__schemas }
    })
  } else if (column.field === 'h_bol') {
    router.push({
      path: '/tracking/detail',
      query: { a: row.__serial_no, _schemas: row.__schemas }
    })
  }
}

const selectedNumber = ref(0)
// 复选框选中事件
const handleCheckboxChange = ({ records }: any) => {
  selectedNumber.value = records.length
}
const handleCheckAllChange = ({ records }: any) => {
  selectedNumber.value = records.length
}
defineExpose({
  searchTableData,
  TransportListItem,
  TagsList
})
</script>

<template>
  <div style="padding: 0px 20px" class="booking-table">
    <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>
        <el-button type="default" @click="handleCustomizeColumns">
          <span style="margin-right: 8px" class="font_family icon-icon_column_b"></span>
          Customize Columns
        </el-button>
      </div>
    </div>
    <vxe-grid
      ref="tableRef"
      v-vloading="tableLoading"
      :height="props.height"
      :style="{ border: 'none' }"
      v-bind="bookingTable"
      @cell-dblclick="handleCellDblclick"
      @checkbox-change="handleCheckboxChange"
      @checkbox-all="handleCheckAllChange"
    >
      <!-- 空数据时的插槽 -->
      <template #empty>
        <VEmpty>
          <template #default>
            <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>
      <!-- Transportation Mode字段的插槽 -->
      <template #mode="{ row, column }">
        <div>
          <span
            class="font_family"
            :class="[`icon-${transportationMode?.[row[column.field]]}`]"
            style="font-size: 24px"
          ></span>
        </div>
      </template>
      <!-- Status字段的插槽 -->
      <template #status="{ row, column }">
        <VTag :type="row[column.field]">{{ row[column.field] }}</VTag>
      </template>
      <!-- Booking No字段的插槽 -->
      <template #link="{ row, column }">
        <span
          style="color: var(--color-theme); cursor: pointer"
          @click="handleLinkClick(row, column)"
        >
          {{ row[column.field] }}
        </span>
      </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="[100, 200, 300, 400]"
          :pager-count="3"
          background
          layout="sizes, prev, pager, next"
          :total="pageInfo.total"
          @size-change="getTableData(false, true)"
          @current-change="getTableData(false, true)"
        />
      </div>
    </div>
    <DownloadDialog @export="exportTable" ref="downloadDialogRef" />
    <CustomizeColumns @customize="customizeColumns" ref="CustomizeColumnsRef" />
  </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;
    opacity: 0;
    visibility: hidden;
  }
}
</style>
