<template>
  <div class="airport-view">
    <div class="airport-header">
      <AirportForm :name="name" @form-data-change="formDataChangeHandler" />
      <div class="airport-count">
        <CountBox
          :count-number="airportCount.flightNum"
          label="今日计划航班数（班）"
          :length="3"
        />
        <CountBox
          :count-number="airportCount.finishFlightNum"
          label="已完成航班数（班）"
          :length="3"
        />
        <CountBox
          :count-number="airportCount.weight"
          :label="`已${isDeparture ? '装载' : '卸载'}重量（吨）`"
          :length="4"
        />
      </div>
      <div class="airport-settings">
        <div v-permission="getPermission('count')">
          <CommonSwitch v-model:flag="countFlag" label="显示件数" />
        </div>
        <!-- <div v-permission="getPermission('UTC')">
          <CommonSwitch v-model:flag="UTCFlag" label="开启UTC" />
        </div> -->
        <div v-permission="getPermission('columnSet')">
          <ColumnSet
            :table-columns="tableColumns"
            @checked-submit="columnChecked"
          />
        </div>
      </div>
    </div>
    <div class="airport-table">
      <SimpleTable
        ref="tableRef"
        :columns="tableColumns"
        :data="tableData"
        row-key="rowKey"
        sequence
        highlight-current-row
        scrollbar-always-on
        :stripe="false"
        show-summary
        :summary-method="summaryMethod"
        :cache-keys="cacheKeys"
        :filter-sort-options="filterSortOptions"
        :label-formatter="tableColumnFormatter"
        :row-class-name="rowClassName"
        :cell-class-name="cellClass"
        :column-props="{ formatter: tableDataFormatter }"
        @sort-rule-change="sortRuleChangeHandler"
        @cell-click="cellClickHandler"
      />
    </div>
  </div>
</template>
<script lang="tsx" setup>
import AirportForm from './AirportForm.vue'
import ColumnSet from '@/components/ColumnSet/index.vue'
import CountBox from '../../components/CountBox/index.vue'
import CommonSwitch from '../../components/CommonSwitch/index.vue'
import SimpleTable from '@/components/SimpleTable/index.vue'
import { useTableColumnSet } from '@/hooks/useTableColumnSet'
import { useAirportTable } from './useAirportTable'
import { useTableStyle } from '../../hooks/useTableStyle'
import { useTableCellClick } from '../../hooks/useTableCellClick'
import { useFormatter } from './useFormatter'
import { CommonData } from '~/common'
import { useLoop } from '@/hooks/useLoop'
import { useTableSettingsStore } from '@/store/tableSettings'
import { useFlightState } from './useFlightState'
import { Query } from '@/api/webApi'
import { ElMessage, SummaryMethod } from 'element-plus'

const props = defineProps({
  name: {
    type: String,
    required: true,
  },
})

// const isInternational = props.name.includes('International')
const isDeparture = props.name.includes('Departure')

const formData: CommonData = reactive({})
const formDataChangeHandler = (data: CommonData) => {
  Object.assign(formData, data)
}

const airportCount = reactive({
  flightNum: 0,
  finishFlightNum: 0,
  weight: 0,
})
const getAirportCount = async () => {
  try {
    const { startDate, endDate } = formData
    if (typeof startDate !== 'string' || typeof endDate !== 'string') {
      throw new Error('Type Error: date must be string')
    }
    const dataContent = [startDate.slice(0, 10), endDate.slice(0, 10)]
    const {
      code,
      returnData: { listValues },
      message,
    } = await Query({
      id:
        DATACONTENT_ID[
          `${props.name.slice(0, 1).toLowerCase() + props.name.slice(1)}Count`
        ],
      dataContent,
    })
    if (Number(code) !== 0) {
      throw new Error(message || '失败')
    }
    if (!listValues.length) {
      ElMessage.info('未查询到统计信息')
      airportCount.flightNum = airportCount.finishFlightNum = airportCount.weight = 0
      return
    }
    const { flightNum, finishFlightNum, weight } = listValues[0]
    airportCount.flightNum = flightNum ?? 0
    airportCount.finishFlightNum = finishFlightNum ?? 0
    if (typeof weight === 'number' && weight > 0) {
      if (weight <= 1000) {
        airportCount.weight = 1
      } else {
        airportCount.weight = Math.round(weight / 1000)
      }
    } else {
      airportCount.weight = 0
    }
  } catch (error) {
    console.error(error)
  }
}

const {
  tableColumns,
  tableColumnsCountIndexMap,
  tableData,
  getTableData,
} = useAirportTable(props.name, formData)

const finishedCount = ref(0)

const { warningNodesMap, getWarningNodes } = useFlightState(
  props.name,
  tableData,
  finishedCount,
  formData
)

useLoop([getAirportCount, getTableData, getWarningNodes], 'airport', [formData])

const countFlag = ref(false)
const { tableColumnFormatter, tableDataFormatter } = useFormatter(
  countFlag,
  tableColumnsCountIndexMap
)

// const UTCFlag = ref(true)

const summaryMethod: SummaryMethod<CommonData> = ({ columns, data }) => {
  const sums: string[] = []
  columns.forEach((column, index) => {
    const countColumn = tableColumns.value.find(
      col => column.property === col.columnName && col.needCount
    )
    if (countColumn) {
      if (countColumn.countMode === 'split') {
        let sumArr = data.reduce(
          (prev: number[], curr: CommonData) => {
            const cellData = curr[column.property]
            if (typeof cellData === 'string') {
              const splitData = cellData.split('/')
              splitData.forEach((str, i) => {
                const num = Number(str)
                if (!Number.isNaN(num)) {
                  if (prev[i]) {
                    prev[i] += num
                  } else {
                    prev[i] = num
                  }
                }
              })
            }
            return prev
          },
          [0]
        )
        // const matched = column.label.match(/(?<=\()\S+(?=\))/)
        // if (matched && !countFlag.value) {
        //   const machedStr = matched[0]
        //   const countIndex = machedStr.split('/').findIndex(str => str === '件')
        //   if (countIndex > -1) {
        //     sumArr.splice(countIndex, 1)
        //   }
        // }
        if (!countFlag.value) {
          const countIndex = tableColumnsCountIndexMap[column.property]
          if (countIndex) {
            sumArr.splice(countIndex, 1)
          }
        }
        sums[index] = sumArr.join('/')
      } else {
        const sumNumber = data.reduce((prev: number, curr: CommonData) => {
          const cellData = curr[column.property]
          if (countColumn.countMode === 'all') {
            return prev + 1
          }
          if (countColumn.countMode === 'notNull') {
            return cellData ? prev + 1 : prev
          }
          const value = Number(cellData)
          if (!Number.isNaN(value)) {
            prev += value
          }
          return prev
        }, 0)
        sums[index] = sumNumber.toString()
      }
    }
  })
  sums[0] = '合计：' + (sums[0] ?? '')
  return sums
}

/* 离港视图默认的排序方式：
 * 0.国内离港-有收运核单的排在前
 * 1.已起飞排在前
 * 2.未起飞中已装机在前
 * 3.已起飞和未起飞分类中各自按照预计起飞时间排序
 */
const defaultDepartureSortFunction = (a: CommonData, b: CommonData) => {
  const departureTimeCompare = (a: CommonData, b: CommonData) => {
    if (a.planDepartureTime) {
      if (b.planDepartureTime) {
        if (a.planDepartureTime > b.planDepartureTime) {
          return 1
        } else if (a.planDepartureTime < b.planDepartureTime) {
          return -1
        } else {
          return 0
        }
      } else {
        return -1
      }
    } else if (b.planDepartureTime) {
      return 1
    } else {
      return 0
    }
  }

  const loadCompare = (a: CommonData, b: CommonData) => {
    if (a.loadPlaneSureTime) {
      if (b.loadPlaneSureTime) {
        return departureTimeCompare(a, b)
      } else {
        return -1
      }
    } else if (b.loadPlaneSureTime) {
      return 1
    } else {
      return departureTimeCompare(a, b)
    }
  }

  const takeOffCompare = (a: CommonData, b: CommonData) => {
    if (a.hasTakenOff === 'Y') {
      if (b.hasTakenOff === 'Y') {
        return departureTimeCompare(a, b)
      } else {
        return -1
      }
    } else if (b.hasTakenOff === 'Y') {
      return 1
    } else {
      return loadCompare(a, b)
    }
  }

  const receiveCompare = (a: CommonData, b: CommonData) => {
    if (a.receiveSure) {
      if (b.receiveSure) {
        return takeOffCompare(a, b)
      } else {
        return -1
      }
    } else if (b.receiveSure) {
      return 1
    } else {
      return takeOffCompare(a, b)
    }
  }

  const receiveSureCompare = (a: CommonData, b: CommonData) => {
    if (a.receiveSure1) {
      if (b.receiveSure1) {
        return takeOffCompare(a, b)
      } else {
        return -1
      }
    } else if (b.receiveSure1) {
      return 1
    } else {
      return takeOffCompare(a, b)
    }
  }

  const enterCompare = (a: CommonData, b: CommonData) => {
    if (a.enterPark) {
      if (b.enterPark) {
        return receiveSureCompare(a, b)
      } else {
        return -1
      }
    } else if (b.enterPark) {
      return 1
    } else {
      return receiveSureCompare(a, b)
    }
  }

  // return isInternational ? enterCompare(a, b) : receiveCompare(a, b)
  return takeOffCompare(a, b)
}

const defaultArrivalSortFunction = (a: CommonData, b: CommonData) => {
  const landingTimeCompare = (a: CommonData, b: CommonData) => {
    if (a.planLandingTime) {
      if (b.planLandingTime) {
        if (a.planLandingTime > b.planLandingTime) {
          return 1
        } else if (a.planLandingTime < b.planLandingTime) {
          return -1
        } else {
          return 0
        }
      } else {
        return -1
      }
    } else if (b.planLandingTime) {
      return 1
    } else {
      return 0
    }
  }

  const tallyCompare = (a: CommonData, b: CommonData) => {
    if (a.tally) {
      if (b.tally) {
        return landingTimeCompare(a, b)
      } else {
        return -1
      }
    } else if (b.tally) {
      return 1
    } else {
      return landingTimeCompare(a, b)
    }
  }

  const unloadCompare = (a: CommonData, b: CommonData) => {
    if (a.unLoad) {
      if (b.unLoad) {
        return tallyCompare(a, b)
      } else {
        return -1
      }
    } else if (b.unLoad) {
      return 1
    } else {
      return tallyCompare(a, b)
    }
  }

  return unloadCompare(a, b)
}

const filterSortOptions = computed(() => ({
  defaultFilterValueMap,
  extraFilterValueMap: flightStateFilter,
  defaultSortFunction: isDeparture ? defaultDepartureSortFunction : undefined,
  defaultSortRuleMap: isDeparture
    ? undefined
    : {
        planLandingTime: 'ascending',
      },
}))

const sortRuleMap = ref({})
const sortRuleChangeHandler = map => {
  sortRuleMap.value = map
}

const { columnChecked } = useTableColumnSet(tableColumns)
const { rowClass, cellClass } = useTableStyle(props.name, warningNodesMap)

const rowClassName = params => {
  const { row, rowIndex } = params
  const classes: string[] = []
  if (
    (row.hasTakenOff === 'Y' || row.hasLanded === 'Y') &&
    (['planDepartureTime', 'planLandingTime'].some(
      key => sortRuleMap.value[key] === 'ascending'
    ) ||
      Object.keys(sortRuleMap.value).length === 0) &&
    finishedCount.value < tableData.value.length &&
    rowIndex === finishedCount.value - 1
  ) {
    classes.push('underline-red')
  }

  return `${rowClass(params)} ${classes.join(' ')}`
}

const { cellClickHandler } = useTableCellClick(props.name)

const route = useRoute()
const tableSettingsStore = useTableSettingsStore()
const { savedTableFilterValueMap } = storeToRefs(tableSettingsStore)
const defaultFilterValueMap = savedTableFilterValueMap.value[route.path]
const flightStateFilter = computed<{} | { [x: string]: string[] }>(() => {
  switch (formData.flightState) {
    case 'hasTakenOff':
      return { hasTakenOff: ['Y'] }
    case 'hasNotTakenOff':
      return { hasTakenOff: ['N'] }
    case 'hasLanded':
      return { hasLanded: ['Y'] }
    case 'hasNotLanded':
      return { hasLanded: ['N'] }
    case 'canceled':
      return { flightState: ['CAN'] }
    case 'groundService':
      return { groundService: ['Y'] }
    case 'groundServiceSZ':
      return { groundServiceSZ: ['Y'] }
    default:
      return {}
  }
})

const cacheKeys = ['IATACode']

const permissionMap = {
  DepartureAirport: {
    count:
      'number_of_pieces_displayed_in_domestic_departure_terminal_view_button',
    UTC: 'turn_on_utc_in_view_of_domestic_departure_terminal_button',
    columnSet: 'domestic_departure_terminal_view_column_setting_button',
  },
  ArrivalAirport: {
    count:
      'number_of_pieces_displayed_in_domestic_inbound_terminal_view_button',
    UTC: 'turn_on_utc_in_view_of_domestic_inbound_terminal_button',
    columnSet: 'domestic_inbound_terminal_view_column_setting_button',
  },
  InternationalDepartureAirport: {
    count:
      'number_of_pieces_displayed_in_international_departure_terminal_view_button',
    UTC: 'international_departure_terminal_view_opens_utc_button',
    columnSet: 'international_departure_terminal_view_column_setting_button',
  },
  InternationalArrivalAirport: {
    count:
      'number_of_display_pieces_of_international_inbound_terminal_view_button',
    UTC: 'the_view_of_international_inbound_terminal_opens_utc_button',
    columnSet: 'view_column_setting_of_international_inbound_terminal_button',
  },
  InternationalDepartureTransferAirport: {
    count:
      'number_of_pieces_displayed_in_international_transfer_terminal_view_button',
    UTC: 'international_transfer_terminal_view_opens_utc_button',
    columnSet: 'international_transfer_terminal_view_column_setting_button',
  },
}
const getPermission = (type?: string) => {
  return [permissionMap[props.name][type]]
}

const tableRef = ref<InstanceType<typeof SimpleTable> | null>(null)
const hasSetTableScroll = ref(false)
watch(
  [() => formData.startDate, () => formData.endDate],
  ([startDate, endDate], [preStartDate, preEndDate]) => {
    if (startDate !== preStartDate || endDate !== preEndDate) {
      hasSetTableScroll.value = false
    }
  }
)
watch(tableData, async () => {
  await nextTick()
  if (hasSetTableScroll.value || !finishedCount.value) {
    return
  }
  if (tableRef.value?.table) {
    tableRef.value?.table?.setScrollTop((finishedCount.value - 1) * 50)
  }
  hasSetTableScroll.value = true
})
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>
