import {extractParentFromKey} from '@remix-ui/helper'
import React, {useContext, useRef, useState} from 'react'
import {MoveContext} from './context/moveContext'
import {DraggableType, DragType} from './types'

export const Drag = (props: DragType) => {
  const [dragged, setDragged] = useState<{path: string; isDirectory: boolean}>({} as {path: string; isDirectory: boolean})

  return (
    <MoveContext.Provider
      value={{
        dragged: dragged,
        moveFile: props.onFileMoved,
        moveFolder: props.onFolderMoved,
        currentlyMoved: (path) => {
          setDragged(() => path)
        }
      }}
    >
      {props.children}
    </MoveContext.Provider>
  )
}

export const Draggable = (props: DraggableType) => {
  const dragRef = useRef<HTMLSpanElement>(null),
    destination = props.file,
    context = useContext(MoveContext)

  // delay timer
  const [timer, setTimer] = useState<NodeJS.Timeout>()
  // folder to open
  const [folderToOpen, setFolderToOpen] = useState<string>()

  const handleDrop = (event: React.DragEvent<HTMLSpanElement>) => {
    event.preventDefault()

    if (destination.isDirectory) {
      if (context.dragged.isDirectory) {
        context.moveFolder(destination.path, context.dragged.path)
      } else {
        context.moveFile(destination.path, context.dragged.path)
      }
    } else {
      const path = extractParentFromKey(destination.path) || '/'

      if (context.dragged.isDirectory) {
        context.moveFolder(path, context.dragged.path)
      } else {
        context.moveFile(path, context.dragged.path)
      }
    }
  }

  const handleDragover = (event: React.DragEvent<HTMLSpanElement>) => {
    //Checks if the folder is opened
    event.preventDefault()
    if (destination.isDirectory && !props.expandedPath.includes(destination.path) && folderToOpen !== destination.path &&  props.handleClickFolder) {
      setFolderToOpen(destination.path)
      timer && clearTimeout(timer)
      setTimer(
        setTimeout(() => {
          props.handleClickFolder(destination.path, destination.type)
          setFolderToOpen(null)
        }, 500)
      )
    }
  }

  const handleDrag = () => {
    if (context.dragged.path !== destination.path) {
      context.currentlyMoved({
        path: destination.path,
        isDirectory: destination.isDirectory
      })
    }
  }

  return (
    <>
      {props.isDraggable ? (
        props.children
      ) : (
        <span
          ref={dragRef}
          draggable
          onDrop={(event) => {
            handleDrop(event)
          }}
          onDragStart={(event) => {
            if(destination && destination.path === '/'){
              event.preventDefault()
              event.stopPropagation
            }else

            if (destination) {
              handleDrag()
            }
          }}
          onDragOver={(event) => {
            if (destination) {
              handleDragover(event)
            }
          }}
        >
          {props.children}
        </span>
      )}
    </>
  )
}
