<script lang="tsx">
import {
  defineComponent,
  ref,
  watch,
  type PropType,
  type Ref,
} from 'vue'
import { type paramsSerializationOptions } from '../../../composables/use-endless-scroll-api'
import type ApiInterface from '../../../types/api-interface'
import { type ComputedColumnInterface } from '../DefaultTableInterfaces'
import useResizableColumns from '../composables/useResizableColumns'
import { type FilterData } from '../filters/Filters'
import { isPeriodCalendarHeaderInterface } from './HeadersTableInterfaces'
import DefaultHeader from './DefaultHeader.vue'

export default defineComponent({
  props: {
    api: {
      type: Object as PropType<ApiInterface>,
    },
    canResizeColumns: {
      type: Boolean,
      default: true,
    },
    columns: {
      type: Object as PropType<Ref<ComputedColumnInterface[]>>,
      required: true,
    },
    horizontalEyesightMargins: {
      type: Array as PropType<number[]>,
      default: () => [],
    },
    setSort: {
      type: Function as PropType<(column: ComputedColumnInterface) => void>,
      required: true,
    },
    sortField: {
      type: String,
      required: true,
    },
    enableSorting: {
      type: Boolean,
    },
    sortOrder: {
      type: Boolean,
    },
    smartFilter: {
      type: Boolean,
      default: false,
    },
    params: {
      type: Array as PropType<FilterData[]>,
    },
    paramsSerialization: {
      type: String as PropType<paramsSerializationOptions>,
      default: 'default',
    },
    tableContainer: {
      type: [Object, null] as PropType<HTMLElement | null>,
      default: null,
    },
    resizerHeight: {
      type: Number,
      default: 0,
    },
  },
  setup(props) {
    const {
      startResize, stopResize, resizedColumn, visualOffset, isResizing,
    } = useResizableColumns(props.columns)
    const indexCalendars = ref<number[]>([])

    const updateColumns = () => {
      const columns = props.columns.value
      const newIndexes: number[] = []

      columns.forEach((column, i) => {
        if (isPeriodCalendarHeaderInterface(column.header)) {
          newIndexes.push(i)
        }
      })

      newIndexes.forEach((newIndex) => {
        if (newIndex >= columns.length - 3 && newIndex > 1) {
          if (!columns[newIndex].right) {
            columns[newIndex].right = true
          }
        } else if (columns[newIndex].right) {
          delete columns[newIndex].right
        }
      })

      indexCalendars.value.forEach((oldIndex) => {
        if (oldIndex >= columns.length || !isPeriodCalendarHeaderInterface(columns[oldIndex].header)) {
          return
        }

        if (!newIndexes.includes(oldIndex)) {
          if (columns[oldIndex].right) {
            delete columns[oldIndex].right
          }
        }
      })

      indexCalendars.value = newIndexes
    }

    const handleMouse = (item: ComputedColumnInterface, value = true) => {
      if (isResizing.value) return
      item.isResizing = value
    }

    watch(
      () => props.columns.value,
      () => {
        updateColumns()
      },
    )

    props.columns.value.forEach((column, i) => {
      if (isPeriodCalendarHeaderInterface(column.header)) {
        indexCalendars.value.push(i)
        if (i >= props.columns.value.length - 3 && i > 1) {
          column.right = true
        }
      }
    })

    return () => props.columns.value.map((item, index) => <DefaultHeader
      key={item.name}
      api={props.api}
      column={item}
      columnIndex={index}
      resizedColumn={resizedColumn.value}
      visualOffset={resizedColumn.value === item ? visualOffset.value : 0}
      setSort={props.setSort}
      sortField={props.sortField}
      canResizeColumns={props.canResizeColumns}
      enableSorting={props.enableSorting}
      horizontalEyesightMargins={props.horizontalEyesightMargins}
      params={props.params}
      paramsSerialization={props.paramsSerialization}
      smartFilter={props.smartFilter}
      sortOrder={props.sortOrder}
      isResizing={isResizing.value}
      tableContainer={props.tableContainer}
      resizerHeight={props.resizerHeight}

      onMouseEnter={() => handleMouse(item)}
      onMouseLeave={() => handleMouse(item, false)}
      onStartResize={(e: MouseEvent, cellElement: HTMLElement | null, tableContainer: HTMLElement | null) => startResize(item, 'right', e, cellElement, tableContainer)}
      onStopResize={stopResize}
    />)
  },
})
</script>
