import { useState, useEffect } from 'react'
import arrayMove from 'array-move'
import BlockInputs from './BlockInputs'
import { SortableList } from '../../sortable'
import { TextInput } from '../../form'
import { TBlockInstance } from '../types'

const BlockInstanceInputs = ({
  value = [],
  name,
  onChange
}: {
  value?: TBlockInstance[]
  name: string
  onChange: GenericEventHandler
}) => {
  const [state, setState] = useState(value.map(item => item.id))

  function updateOrderProperty<T extends { id: U }, U>(
    values: T[],
    orderList: U[]
  ) {
    const orderedValues = values.map(value => {
      const order = orderList.findIndex(orderedId => orderedId === value.id)
      return { ...value, order }
    })
    onChange({ target: { type: 'custom', name, value: orderedValues } })
  }

  function onSortEnd({
    oldIndex,
    newIndex
  }: {
    oldIndex: number
    newIndex: number
  }) {
    const newOrder = arrayMove(state, oldIndex, newIndex)
    setState(newOrder)
    updateOrderProperty(value, newOrder)
  }

  useEffect(() => {
    const missingIds = value
      .filter(item => !state.includes(item.id))
      .filter(item => !item.id.startsWith('--'))
      .map(item => item.id)
    const stateWithoutRemovedItems = state.filter(stateId =>
      value.find(item => stateId === item.id)
    )
    setState([...stateWithoutRemovedItems, ...missingIds])
  }, [value])

  const items = state
    .map(stateId => {
      const itemIndex = value.findIndex(item => item.id === stateId)
      if (itemIndex < 0) return null
      const item = value[itemIndex]
      return (
        <div key={item.id}>
          <p>{item.id}</p>
          <TextInput
            name={`${name}.${itemIndex}.order`}
            label='Order'
            value={item.order}
            type='number'
            onChange={onChange}
          />
          <TextInput
            name={`${name}.${itemIndex}.rounds`}
            label='Rounds'
            value={item.rounds}
            type='number'
            onChange={onChange}
          />
          <TextInput
            name={`${name}.${itemIndex}.variation`}
            label='Variation'
            value={item.variation}
            onChange={onChange}
          />
          {item.block && (
            <BlockInputs
              name={`${name}.${itemIndex}.block`}
              value={item.block}
              onChange={onChange}
            />
          )}
          <button
            type='button'
            onClick={ev => {
              const newOrder = state.filter(orderedId => item.id !== orderedId)
              setState(newOrder)
              const newValues = item.id?.startsWith('++')
                ? [...value.slice(0, itemIndex), ...value.slice(itemIndex + 1)]
                : [
                    ...value.slice(0, itemIndex),
                    { ...item, id: `--${item.id}` },
                    ...value.slice(itemIndex + 1)
                  ]
              updateOrderProperty(newValues, newOrder)
            }}
          >
            Delete block
          </button>
        </div>
      )
    })
    .filter(block => block !== null)

  return (
    <SortableList
      items={items}
      onSortEnd={onSortEnd}
      useDragHandle
      lockAxis={'y'}
    />
  )
}

export default BlockInstanceInputs
