import { defineComponent } from 'vue'

import Cell from '../Cell'
import { useInjectTable } from '../context/TableContext'
import type {
  CellType,
  ColumnType,
  CustomizeComponent,
  DefaultRecordType,
  GetComponentProps,
  StickyOffsets,
} from '../interface'
import { getCellFixedInfo } from '../utils/fixUtil'
import { getColumnsKey } from '../utils/valueUtil'
import DragHandleVue from './DragHandle'

export interface RowProps<RecordType = DefaultRecordType> {
  cells: readonly CellType<RecordType>[]
  stickyOffsets: StickyOffsets
  flattenColumns: readonly ColumnType<RecordType>[]
  rowComponent: CustomizeComponent
  cellComponent: CustomizeComponent
  customHeaderRow: GetComponentProps<readonly ColumnType<RecordType>[]>
  index: number
}

export default defineComponent<RowProps>({
  name: 'HeaderRow',
  props: [
    'cells',
    'stickyOffsets',
    'flattenColumns',
    'rowComponent',
    'cellComponent',
    'index',
    'customHeaderRow',
  ] as any,
  setup(props: RowProps) {
    const tableContext = useInjectTable()
    return () => {
      const { prefixCls, direction } = tableContext
      const {
        cells,
        stickyOffsets,
        flattenColumns,
        rowComponent: RowComponent,
        cellComponent: CellComponent,
        customHeaderRow,
        index,
      } = props

      let rowProps
      if (customHeaderRow) {
        rowProps = customHeaderRow(
          cells.map((cell) => cell.column),
          index,
        )
      }

      const columnsKey = getColumnsKey(cells.map((cell) => cell.column))

      return (
        <RowComponent {...rowProps}>
          {cells.map((cell: CellType, cellIndex) => {
            const { column } = cell
            const fixedInfo = getCellFixedInfo(
              cell.colStart,
              cell.colEnd,
              flattenColumns,
              stickyOffsets,
              direction,
            )

            let additionalProps
            if (column && column.customHeaderCell) {
              additionalProps = cell.column.customHeaderCell(column)
            }
            const col: ColumnType<any> = column
            return (
              <Cell
                {...cell}
                cellType="header"
                ellipsis={column.ellipsis}
                align={column.align}
                component={CellComponent}
                prefixCls={prefixCls}
                key={columnsKey[cellIndex]}
                {...fixedInfo}
                additionalProps={additionalProps}
                rowType="header"
                column={column}
                v-slots={{
                  default: () => column.title,
                  dragHandle: () =>
                    col.resizable ? (
                      <DragHandleVue
                        prefixCls={prefixCls}
                        width={col.width as number}
                        minWidth={col.minWidth}
                        maxWidth={col.maxWidth}
                        column={col}
                      />
                    ) : null,
                }}
              />
            )
          })}
        </RowComponent>
      )
    }
  },
})
