import { datetimeToTime } from '@/utils/validate'
import { CSSProperties } from 'vue'
import { CommonData, MaybeRef } from '~/common'

interface TrackNode {
  name: string
  nodeCode: string
  flag: boolean
  labelWidth?: number
  descriptions: string[]
}
interface TrackAirport {
  airport: string
  isDeparture: boolean
  trackSteps: TrackNode[]
}
interface TrackAirline {
  flightNO: string
  flightDate: string
  airports: TrackAirport[]
}

const trackNodesMap = {
  departure: [
    {
      name: '收运核单',
      nodeCode: 'DEH',
    },
    // {
    //   name: '收运核查',
    //   nodeCode: 'ACC_CHECK',
    // },
    {
      name: '安检',
      nodeCode: '安检', // 暂无
    },
    {
      name: '加货',
      nodeCode: 'ACC_BUP',
    },
    {
      name: '预配载',
      nodeCode: 'LS_CARGO',
    },
    // {
    //   name: '待运区',
    //   nodeCode: 'WAT_LOC',
    // },
    // {
    //   name: '货站交接',
    //   nodeCode: 'CARGOS_HANDOVER_STATUS_02',
    // },
    {
      name: '交接复核',
      nodeCode: 'CARGOS_HANDOVER_STATUS_03',
      // labelWidth: 70,
    },
    {
      name: '机下交接',
      nodeCode: '出港货邮',
    },
    {
      name: '装机',
      nodeCode: '装载完成',
    },
    {
      name: '关闭舱门',
      nodeCode: '关闭舱门',
    },
    {
      name: '拉下登记',
      nodeCode: 'CARGOS_OFFLOAD',
    },
    {
      name: '拉回确认',
      nodeCode: 'OFFLOAD_CONFIRM',
    },
    // {
    //   name: '起飞',
    //   nodeCode: 'TAKEOFF', // 待定
    // },
    {
      name: '退运',
      nodeCode: 'BILL_RETURN',
    },
  ],
  arrival: [
    {
      name: '卸机',
      nodeCode: 'CARGOS_ARR_HANDOVER',
    },
    {
      name: '库区到达',
      nodeCode: 'CARGOS_HANDOVER_STATUS_01',
    },
    {
      name: '货站交接',
      nodeCode: 'CARGOS_HANDOVER_STATUS_99',
    },
    {
      name: '理货',
      nodeCode: 'IMP_TALLY',
    },
    {
      name: '出库',
      nodeCode: 'FSUDLV',
    },
  ],
  internationalDeparture: [
    {
      name: '入园',
      nodeCode: 'EPORTREL',
    },
    {
      name: '海关',
      nodeCode: 'MTREL_out',
    },
    {
      name: '运抵',
      nodeCode: 'FOH',
    },
    {
      name: '安检',
      nodeCode: 'REH',
    },
    {
      name: '收运核单',
      nodeCode: 'RCS',
    },
    {
      name: '理货',
      nodeCode: 'ACC_BUP',
    },
    // {
    //   name: '待运区',
    //   nodeCode: 'WAT_LOC',
    // },
    // {
    //   name: '货站交接',
    //   nodeCode: 'CARGOS_HANDOVER_STATUS_02',
    // },
    {
      name: '交接复核',
      nodeCode: 'CARGOS_HANDOVER_STATUS_03',
    },
    {
      name: '机下交接',
      nodeCode: '出港货邮',
    },
    {
      name: '装机',
      nodeCode: '装载完成',
    },
    {
      name: '拉下',
      nodeCode: 'CARGOS_OFFLOAD',
    },
    // {
    //   name: '实配',
    //   nodeCode: 'LS_CARGO',
    // },
    // {
    //   name: '退运',
    //   nodeCode: '',
    // },
  ],
  internationalArrival: [
    {
      name: '卸机',
      nodeCode: 'FFM',
    },
    {
      name: '机下交接',
      nodeCode: 'CARGOS_HANDOVER_STATUS_01',
    },
    {
      name: '货站交接',
      nodeCode: 'CARGOS_HANDOVER_STATUS_99',
    },
    {
      name: '理货',
      nodeCode: 'RCF报',
    },
    // {
    //   name: '快件运抵',
    //   nodeCode: '',
    // },
    {
      name: '海关放行',
      nodeCode: 'MTREL_in',
    },
    {
      name: '出库',
      nodeCode: 'DLV报',
    },
  ],
}

export function useTrackData(name: string, trackData: MaybeRef<CommonData[]>) {
  const isInternational = name.includes('International')

  const trackAirlines = ref<TrackAirline[]>([])
  const getTrackAirlines = () => {
    const airlines = unref(trackData).reduce(
      (
        airlines,
        {
          flightNO,
          flightDate,
          departureAirport,
          arriveAirport,
          nodeCode,
          execPosition,
          ConsignmentItemPackagingQuantityQuantity,
          execResult,
          execTime,
        }
      ) => {
        const isDeparture =
          trackNodesMap.departure
            .concat(trackNodesMap.internationalDeparture)
            .some(node => node.nodeCode === nodeCode) ||
          (name.includes('Departure') &&
            typeof nodeCode === 'string' &&
            ['MTEXDEC', 'NEW'].includes(nodeCode))
        const airport = isDeparture
          ? String(departureAirport ?? '')
          : String(arriveAirport ?? '')
        const trackNode = {
          flag: Boolean(
            execPosition ||
              ConsignmentItemPackagingQuantityQuantity ||
              execResult ||
              execTime
          ),
          descriptions: [
            String(execPosition ?? ''),
            String(ConsignmentItemPackagingQuantityQuantity ?? ''),
            execResult ? '通过' : '未通过',
            datetimeToTime(execTime, flightDate),
          ],
        }
        const nodeList = trackNodesMap[
          isDeparture
            ? isInternational
              ? 'internationalDeparture'
              : 'departure'
            : isInternational
            ? 'internationalArrival'
            : 'arrival'
        ].map(node => {
          if (node.nodeCode === nodeCode) {
            return {
              ...node,
              ...trackNode,
            }
          } else {
            return {
              ...node,
              flag: false,
              descriptions: [],
            }
          }
        })
        const airline = airlines.find(
          airline =>
            airline.flightNO === flightNO &&
            airline.flightDate === airline.flightDate
        )
        if (airline) {
          const trackAirport = airline.airports.find(
            trackAirport => trackAirport.airport === airport
          )
          if (trackAirport) {
            trackAirport.trackSteps = trackAirport.trackSteps.map(node => {
              if (node.nodeCode === nodeCode) {
                node = {
                  ...node,
                  ...trackNode,
                }
              }
              return node
            })
          } else {
            airline.airports.push({
              airport,
              isDeparture,
              trackSteps: nodeList,
            })
          }
        } else {
          airlines.push({
            flightNO: String(flightNO ?? ''),
            flightDate: String(flightDate ?? ''),
            airports: [
              {
                airport,
                isDeparture,
                trackSteps: nodeList,
              },
            ],
          })
        }
        return airlines
      },
      [] as TrackAirline[]
    )
    trackAirlines.value = airlines.map(airline => {
      const dealedAirports = airline.airports.map((airport, index) => ({
        ...airport,
        trackSteps: airport.trackSteps.filter(
          node =>
            node.flag ||
            (index > 0
              ? ['IMP_TALLY', 'FSUDLV'].includes(node.nodeCode)
              : !['CARGOS_OFFLOAD', 'OFFLOAD_CONFIRM', 'BILL_RETURN'].includes(
                  node.nodeCode
                ))
        ),
      }))
      const sortedAirports =
        name.includes('Departure') === airline.airports[0].isDeparture
          ? dealedAirports
          : dealedAirports.reverse()
      return {
        ...airline,
        airports: sortedAirports,
      }
    })
  }

  watch(trackData, () => {
    getTrackAirlines()
  })

  const trackBoxStyle = computed(
    () => (airports: TrackAirport[], index: number) => {
      const style: CSSProperties = {}
      const totalLength = airports.reduce((pre, current) => {
        return pre + current.trackSteps.length - 1
      }, 0)
      style.width = totalLength
        ? `calc((100% - ${airports.length - 1} * 8px) * ${
            (airports[index].trackSteps.length - 1) / totalLength
          })`
        : '100%'
      style.minWidth = '300px'
      return style
    }
  )
  return {
    trackAirlines,
    trackBoxStyle,
  }
}
