<script lang="tsx">
import {
  defineComponent, type PropType, ref, type Ref, Teleport,
} from 'vue'
import { type NodeItemExtended } from '../../../lib'
import { type DraggableItem } from '../default-table/types'
import { type DragAndDropSortingSettings } from './DragAndDropItemInterfaces'

const showHelperInLocalStorage = localStorage.getItem('helperShown')
const showHelper = ref(typeof showHelperInLocalStorage === 'object')

export default defineComponent({
  props: {
    computedItems: {
      type: Object as PropType<DraggableItem[]>,
    },
    dragAndDropSorting: {
      type: Object as PropType<DragAndDropSortingSettings>,
    },
    draggedItem: {
      type: Object as () => Ref<NodeItemExtended | DraggableItem | undefined>,
      required: true,
    },
    item: {
      type: Object as PropType<NodeItemExtended | DraggableItem>,
      required: true,
    },
    itemList: {
      type: Object as PropType<Ref<HTMLElement | null>>,
      required: true,
    },
  },

  setup(props) {
    const items: Ref<NodeItemExtended[]> = ref([])
    const localDraggedItem = ref(props.draggedItem)
    const iconRef = ref()
    const topPosition = ref(0)
    const leftPosition = ref(0)
    const isHoverIcon = ref(false)
    const isHoverHelper = ref(false)

    const onDrag = (e: DragEvent) => {
      const itemList = props.itemList.value as HTMLDivElement

      if (e.pageY > (itemList.getBoundingClientRect().bottom - 30)) {
        itemList.scrollTop += 1
      } else if (e.pageY < (itemList.getBoundingClientRect().top + 30)) {
        itemList.scrollTop -= 1
      }
    }

    const onStartDrag = (item: NodeItemExtended | DraggableItem) => {
      localDraggedItem.value = item
      if ('parent' in localDraggedItem.value) {
        (localDraggedItem.value.parent?.children || items.value).forEach((item) => {
          item.isExpanded = false
        })
      }
    }

    const onStopDrag = () => {
      if (!localDraggedItem.value) return

      if ('parent' in localDraggedItem.value) {
        (localDraggedItem.value.parent?.children || items.value).forEach((item) => {
          props.dragAndDropSorting?.setSort(item, item.draftOrder)
        })
        props.dragAndDropSorting?.onSort(localDraggedItem.value.parent?.children || items.value)
      } else if (props.computedItems) {
        props.computedItems.forEach((item) => {
          props.dragAndDropSorting?.setSort(item.item, item.draftOrder)
        })
        props.dragAndDropSorting?.onSort(items.value)
      }

      localDraggedItem.value = undefined
    }

    const onMouseOver = (item: NodeItemExtended | DraggableItem) => {
      if (!localDraggedItem.value) return

      if ('parent' in localDraggedItem.value && 'parent' in item) {
        if (localDraggedItem.value.parent?.id !== item.parent?.id) return
      }

      const order = item.draftOrder
      item.draftOrder = localDraggedItem.value.draftOrder
      localDraggedItem.value.draftOrder = order
    }

    const onDragover = (e: DragEvent, item: any) => {
      e.preventDefault()
      onMouseOver(item)
    }

    const checkPosition = () => {
      const { top, left } = iconRef.value.getBoundingClientRect()
      topPosition.value = Math.round(top) - 155
      leftPosition.value = Math.round(left) - 55
      isHoverIcon.value = true
    }

    return () => (
      <div
        class="ark-ui-table-body-cell ark-ui-table-checkbox-cell"
        onMousedown={() => onStartDrag(props.item)}
        onDrag={onDrag}
        onDragover={(e: DragEvent) => onDragover(e, props.item)}
        onMouseover={() => onMouseOver(props.item)}
        onMouseup={onStopDrag}
        onDragend={onStopDrag}
        draggable={true}
      >
        <div
          class="ark-ui-table-body-item-icon"
          ref={iconRef}
          onMouseover={() => checkPosition()}
          onMouseleave={() => { isHoverIcon.value = false }}
        />

        <Teleport to="body">
          <div class="ark-ui-helper"
            style={`
                ${showHelper.value && (isHoverIcon.value || isHoverHelper.value) ? 'display: flex;' : 'display: none;'}
                left: ${leftPosition.value}px;
                top: ${topPosition.value}px;
              `}
            onMouseover={() => { isHoverHelper.value = true }}
            onMouseleave={() => { isHoverHelper.value = false }}
          >
            <p class="ark-ui-helper-text">Для перемещения строки зажмите элемент и перетащите его вверх или вниз в таблице</p>
            <button
              class="ark-ui-helper-button"
              onClick={(event) => {
                event.stopPropagation()
                localStorage.setItem('helperShown', 'false')
                showHelper.value = false
              }}
            >
                Понятно
            </button>
          </div>
        </Teleport>
      </div>
    )
  },
})
</script>

<style lang="scss" scoped>
@import '../../../styles/variables';

.ark-ui-table-checkbox-cell {
  .ark-ui-table-body-item-icon {
    cursor: grab;
    width: 6px;
    height: 10px;
    background-image: url('./../assets/drag-and-drop-dots.svg');
    background-repeat: no-repeat;
  }
}

.ark-ui-helper {
  position: absolute;
  flex-direction: column;
  display: none;
  width: 276px;
  height: 140px;
  box-sizing: border-box;
  background: #585B69;
  border-radius: 8px;
  transition: .4s;
  padding: 16px;
  z-index: $tooltip;

  .ark-ui-helper-text {
    font-size: 14px;
    line-height: 20px;
    font-weight: 400;
    color: #FFF;
    margin: 0;
  }

  .ark-ui-helper-button {
    background: #FFF;
    font-size: 12px;
    line-height: 16px;
    font-weight: 500;
    border: 1px solid #D3D5E5;
    border-radius: 4px;
    margin: 16px 0 0 auto;
    padding: 8px 10px;
  }

  &::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 17.2%;
    border: 11px solid transparent;
    border-top: 9px solid #585B69;
  }
}
</style>
