/* eslint-disable react/no-array-index-key */
/* eslint-disable no-unused-vars */
import {
  HiChevronDoubleDown,
  HiChevronDoubleLeft,
  HiChevronDoubleRight,
  HiChevronDoubleUp,
  HiChevronDown,
  HiChevronLeft,
  HiChevronRight,
  HiChevronUp,
} from 'react-icons/hi'
import { ReactElement, useState } from 'react'
import { useTranslation } from 'react-i18next'

export interface ITransferListItem {
  [key: string]: string | number
}

export interface ITransferListProps {
  sourceItems: ITransferListItem[]
  destinationItems: ITransferListItem[]
  setSourceItems: (items: ITransferListItem[]) => void
  setDestinationItems: (items: ITransferListItem[]) => void
  sourceLabel?: string
  destinationLabel?: string
  labelStyle?: string
  itemStyle?: string
  translationGroup?: string
  isSubCategory?: boolean
  errorMessage?: string
  disableTranslation?: boolean
}

export const TransferList = (props: ITransferListProps) => {
  const {
    sourceItems,
    destinationItems,
    setSourceItems,
    setDestinationItems,
    sourceLabel,
    destinationLabel,
    labelStyle,
    itemStyle,
    translationGroup,
    isSubCategory,
    errorMessage,
    disableTranslation = false,
  } = props

  const { t } = useTranslation()

  const [selected, setSelected] = useState<ITransferListItem[]>([])
  const [selectedSide, setSelectedSide] = useState<'SOURCE' | 'DESTINATION'>(
    'SOURCE',
  )
  const [dragItemIndex, setDragItemIndex] = useState<number>()

  const defaultDestinationFilterItem = destinationItems.filter(
    (item) => !selected.find((selectedItem) => item.id === selectedItem.id),
  )
  const filterDestinationItemForSubCategory = destinationItems.filter(
    (item) =>
      !selected.find(
        (selectedItem) =>
          item.label.toString().toLowerCase() ===
          selectedItem.label.toString().toLowerCase(),
      ),
  )

  const defaultSourceFilterItem = sourceItems.filter(
    (item) => !selected.find((selectedItem) => item.id === selectedItem.id),
  )
  const filterSourceItemForSubCategory = sourceItems.filter(
    (item) =>
      !selected.find(
        (selectedItem) =>
          item.label.toString().toLowerCase() ===
          selectedItem.label.toString().toLowerCase(),
      ),
  )

  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  const moveItem = (array: ITransferListItem[], to: number, from: number) => {
    const item = array[from]
    array.splice(from, 1)
    array.splice(to, 0, item)
    return array
  }

  const handleSendToSource = () => {
    if (selectedSide === 'SOURCE') {
      return null
    }
    const tempDestinationItem: ITransferListItem[] = isSubCategory
      ? filterDestinationItemForSubCategory
      : defaultDestinationFilterItem
    setDestinationItems([...tempDestinationItem])
    setSourceItems([...sourceItems, ...selected])
    setSelected([])
    return true
  }

  const handleSendAllToSource = () => {
    setSourceItems([...sourceItems, ...destinationItems])
    setDestinationItems([])
    setSelected([])
  }

  const handleSendToDestination = () => {
    if (selectedSide === 'DESTINATION') {
      return null
    }
    const tempSourceItems = isSubCategory
      ? filterSourceItemForSubCategory
      : defaultSourceFilterItem
    setSourceItems([...tempSourceItems])
    setDestinationItems([...destinationItems, ...selected])
    setSelected([])
    return true
  }

  const handleSendAllToDestination = () => {
    setDestinationItems([...destinationItems, ...sourceItems])
    setSourceItems([])
    setSelected([])
  }

  const handleDragStart = (index: number) => {
    setDragItemIndex(index)
  }

  const handleDragEnter = (index: number) => {
    if (dragItemIndex !== undefined) {
      const tempDestinationItem: ITransferListItem[] = isSubCategory
        ? filterDestinationItemForSubCategory
        : defaultDestinationFilterItem
      const item = tempDestinationItem[dragItemIndex]
      tempDestinationItem.splice(dragItemIndex, 1)
      tempDestinationItem.splice(index, 0, item)
      setDragItemIndex(index)
      setDestinationItems(tempDestinationItem)
    }
  }

  const handleItemSelected = (
    item: ITransferListItem,
    direction: 'SOURCE' | 'DESTINATION',
  ) => {
    let tempSelected = selected
    if (direction === 'SOURCE') {
      if (selectedSide === 'DESTINATION') {
        tempSelected = []
        tempSelected.push(item)
        setSelectedSide('SOURCE')
      } else if (selected.includes(item)) {
        const actualIndex = selected.indexOf(item)
        tempSelected.splice(actualIndex, 1)
      } else {
        tempSelected.push(item)
      }
    } else if (selectedSide === 'SOURCE') {
      tempSelected = []
      setSelectedSide('DESTINATION')
      tempSelected.push(item)
    } else if (selected.includes(item)) {
      const actualIndex = selected.indexOf(item)
      tempSelected.splice(actualIndex, 1)
    } else {
      tempSelected.push(item)
    }
    setSelected([...tempSelected])
  }

  return (
    <div className="flex flex-col items-end">
      <div className="w-full flex flex-col md:flex-row gap-4 rounded-md">
        <div className="flex-1 border border-gray-400 rounded-md flex flex-col min-h-[14rem] h-[26rem] shadow-sm ">
          <p
            className={`w-full text-center text-lg font-bold p-2 bg-primary rounded-tl rwhiteounded-tr ${
              labelStyle || ''
            }`}
          >
            {sourceLabel || 'Source'}
          </p>
          <ul className="flex-1 flex flex-col overflow-auto">
            {sourceItems.map((item: any, index) => (
              <li
                role="presentation"
                key={index}
                className={`flex gap-4 p-2 pl-5 w-full hover:bg-primary hover:text-white border-b border-gray-400 ${
                  selected.includes(item) && selectedSide === 'SOURCE'
                    ? 'bg-secondary text-white'
                    : ''
                } cursor-pointer ${itemStyle || ''}`}
                onClick={() => handleItemSelected(item, 'SOURCE')}
              >
                {typeof item.label === 'object' ? (
                  item.label
                ) : (
                  <p className="w-full">
                    {translationGroup
                      ? t(`${translationGroup}.${item.label}`)
                      : t(`fields.${item.label}`) === `fields.${item.label}`
                      ? String(item.label).replaceAll('_', ' ')
                      : t(`fields.${item.label}`)}
                  </p>
                )}
              </li>
            ))}
          </ul>
        </div>
        <div className="flex gap-2 justify-center items-center md:flex-col">
          <button
            type="button"
            className="btn btn-primary btn-sm  text-2xl shadow-sm"
            onClick={handleSendToDestination}
            title={
              t('api.move_selected_to_destination', {
                sourceLabel: sourceLabel || t('api.source'),
                destinationLabel: destinationLabel || t('api.destination'),
              }) || ''
            }
          >
            <HiChevronRight className="text-xl hidden md:block" />
            <HiChevronDown className="text-xl md:hidden block" />
          </button>
          <button
            type="button"
            className="btn btn-primary btn-sm  text-2xl shadow-sm"
            onClick={handleSendAllToDestination}
            title={
              t('api.move_all_to_destination', {
                sourceLabel: sourceLabel || t('api.source'),
                destinationLabel: destinationLabel || t('api.destination'),
              }) || ''
            }
          >
            <HiChevronDoubleRight className="text-xl hidden md:block" />
            <HiChevronDoubleDown className="text-xl md:hidden block" />
          </button>
          <button
            type="button"
            className="btn btn-primary btn-sm  text-2xl shadow-sm"
            onClick={handleSendToSource}
            title={
              t('api.move_selected_to_source', {
                sourceLabel: sourceLabel || t('api.source'),
                destinationLabel: destinationLabel || t('api.destination'),
              }) || ''
            }
          >
            <HiChevronLeft className="text-xl hidden md:block" />
            <HiChevronUp className="text-xl md:hidden block" />
          </button>
          <button
            type="button"
            className="btn btn-primary btn-sm  text-2xl shadow-sm"
            onClick={handleSendAllToSource}
            title={String(
              t('api.move_all_to_source', {
                sourceLabel: sourceLabel || t('api.source'),
                destinationLabel: destinationLabel || t('api.destination'),
              }),
            )}
          >
            <HiChevronDoubleLeft className="text-xl hidden md:block" />
            <HiChevronDoubleUp className="text-xl md:hidden block" />
          </button>
        </div>
        <div className="flex-1 border border-gray-400 rounded-md flex flex-col h-[26rem] shadow-sm min-h-[14rem]">
          <p
            className={`w-full text-center text-lg font-bold p-2 bg-primary rounded-tl rounded-tr border-bottom border-gray-400 ${
              labelStyle || ''
            }`}
          >
            {destinationLabel || 'Destination'}
          </p>
          <ul className="flex-1 flex flex-col overflow-auto">
            {destinationItems.map((item, index) => (
              <li
                role="presentation"
                key={index}
                draggable
                className={`flex gap-4 p-2 w-full hover:bg-primary hover:text-white border-b border-gray-400  ${
                  selected.includes(item) && selectedSide === 'DESTINATION'
                    ? 'bg-secondary text-white'
                    : ''
                } cursor-pointer ${itemStyle || ''}`}
                onDragStart={() => handleDragStart(index)}
                onDragEnter={() => handleDragEnter(index)}
                onDragOver={(e) => {
                  e.preventDefault()
                }}
                onClick={() => handleItemSelected(item, 'DESTINATION')}
              >
                <p className="w-full">
                  {disableTranslation
                    ? item.label
                    : translationGroup
                    ? t(`${translationGroup}.${item.label}`)
                    : t(`fields.${item.label}`) === `fields.${item.label}`
                    ? String(item.label).replaceAll('_', ' ')
                    : t(`fields.${item.label}`)}
                </p>
              </li>
            ))}
          </ul>
        </div>
      </div>
      {errorMessage && <p className="text-sm text-error">{t(errorMessage)}</p>}
    </div>
  )
}
