<template>
  <div class="cpSeatMapRow">
    <template v-if="hasExit">
      <div
        v-for="exit in activeExits"
        :key="exit.direction"
        class="cpSeatMapRow__exit"
        :class="getExitDynamicClass(exit.direction)"
      >
        exit
      </div>
    </template>
    <template v-if="hasTopFacilities">
      <cp-seat-map-row-facility
        v-for="(facility, index) in formattedTopFacilities"
        :key="index"
        :columns-count="columnsCount"
        :config="config"
        is-top
        :position="facility.position"
        :seat-block-size="seatBlockSize"
        :type="facility.type"
      />
    </template>
    <slot />
    <template v-if="hasBottomFacilities">
      <cp-seat-map-row-facility
        v-for="(facility, index) in formattedBottomFacilities"
        :key="index"
        :columns-count="columnsCount"
        :config="config"
        :position="facility.position"
        :seat-block-size="seatBlockSize"
        :type="facility.type"
      />
    </template>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

import type { CpSeatMapConfig } from '@/constants/seatMap/CpSeatMapConfig'
import type { SeatRow } from '@/constants/seatMap/SeatRow'
import type { SeatRowFacilityFlags } from '@/constants/seatMap/SeatRowFacilityFlags'

import { DEFAULT_CP_SEAT_MAP_CONFIG } from '@/constants/seatMap/CpSeatMapConfig'
import { SeatRowFacilities, SeatRowFacilityPosition } from '@/constants/seatMap/SeatRowFacilities'
import { capitalizeFirstLetter } from '@/helpers'
import CpSeatMapRowFacility from './CpSeatMapRowFacility.vue'

interface Props {
  config?: CpSeatMapConfig
  row: SeatRow
  seatBlockSize: number
}

const props = withDefaults(defineProps<Props>(), {
  config: () => DEFAULT_CP_SEAT_MAP_CONFIG,
})

enum ExitDirections {
  FRONT = 'front',
  BACK = 'back',
  LEFT = 'left',
  RIGHT = 'right',
}

interface Exit {
  active: boolean
  direction: ExitDirections
}

interface FormattedFacility {
  position: SeatRowFacilityPosition
  type: SeatRowFacilities
}

const allExits = computed<Exit[]>(() => [
  { active: props.row.has_exit_back, direction: ExitDirections.BACK },
  { active: props.row.has_exit_front, direction: ExitDirections.FRONT },
  { active: props.row.has_exit_left, direction: ExitDirections.LEFT },
  { active: props.row.has_exit_right, direction: ExitDirections.RIGHT },
])

const activeExits = computed(() => allExits.value.filter(({ active }) => active))

const columnsCount = computed(() => Object.keys(props.row.seats).length + 1) // +1 for the hallway

const hasExit = computed(() => !!allExits.value.length)

const getFacilityType = (facility: SeatRowFacilityFlags, position: SeatRowFacilityPosition) => {
  if (position === SeatRowFacilityPosition.LEFT) {
    if (facility.lavatory_left) return SeatRowFacilities.LAVATORY
    if (facility.galley_left) return SeatRowFacilities.GALLEY
  }

  if (position === SeatRowFacilityPosition.RIGHT) {
    if (facility.lavatory_right) return SeatRowFacilities.LAVATORY
    if (facility.galley_right) return SeatRowFacilities.GALLEY
  }

  return null
}

const getFormattedFacilities = (facility: SeatRowFacilityFlags): FormattedFacility[] => {
  const positions = [
    { position: SeatRowFacilityPosition.LEFT, hasFacility: facility.lavatory_left || facility.galley_left },
    { position: SeatRowFacilityPosition.RIGHT, hasFacility: facility.lavatory_right || facility.galley_right },
  ]

  return positions.reduce<FormattedFacility[]>((facilities, { position, hasFacility }) => {
    if (!hasFacility) return facilities

    const type = getFacilityType(facility, position)
    if (!type) return facilities

    return [...facilities, { position, type }]
  }, [])
}

const formattedTopFacilities = computed<FormattedFacility[]>(() => {
  if (!props.row.top) return []
  return getFormattedFacilities(props.row.top)
})

const formattedBottomFacilities = computed<FormattedFacility[]>(() => {
  if (!props.row.bottom) return []
  return getFormattedFacilities(props.row.bottom)
})

const hasTopFacilities = computed(() => !!formattedTopFacilities.value.length)
const hasBottomFacilities = computed(() => !!formattedBottomFacilities.value.length)

const getExitDynamicClass = (direction: ExitDirections) => [
  `cpSeatMapRow__exit--is${capitalizeFirstLetter(direction)}`,
]
</script>

<style lang="scss">
.cpSeatMapRow {
  position: relative;
  display: grid;
  gap: var(--cp-spacing-md);
  place-items: center center;

  &__exit {
    position: absolute;
    z-index: 1;
    color: var(--cp-text-error-primary);
    font-size: fn.px-to-em(12);
    font-weight: 700;
    letter-spacing: fn.px-to-rem(2);
    line-height: fn.px-to-rem(24);
    place-self: start;
    text-transform: uppercase;

    &--isLeft,
    &--isFront,
    &--isBack {
      left: fn.px-to-rem(-80);
      text-orientation: sideways;
      writing-mode: sideways-lr;
    }

    &--isRight {
      right: fn.px-to-rem(-80);
      text-orientation: sideways;
      writing-mode: sideways-rl;
    }
  }
}

@include mx.media-query-max(551px) {
  .cpSeatMapRow {
    gap: var(--cp-spacing-sm);

    &__exit {
      display: none;
    }
  }
}
</style>
