'use client'

// React Imports
import type { RefObject } from 'react'
import { useEffect, useState } from 'react'

// Third-party imports
import { useDragAndDrop } from '@formkit/drag-and-drop/react'
import { animations } from '@formkit/drag-and-drop'
import { useSelector } from 'react-redux'

// Type Imports
import type { RootState } from '@/redux-store'
import { useAppDispatch } from '@/redux-store'

// Slice Imports
import { addColumn, updateColumns, fetchBoard, createColumnAsync, moveTaskAsync } from '@/redux-store/slices/kanban'

// Component Imports
import KanbanList from './KanbanList'
import NewColumn from './NewColumn'
import KanbanDrawer from './KanbanDrawer'

const KanbanBoard = () => {
  // State
  const [drawerOpen, setDrawerOpen] = useState(false)

  // Hooks
  const kanbanStore = useSelector((state: RootState) => state.kanbanReducer)
  const dispatch = useAppDispatch()

  // Fetch board on mount
  useEffect(() => {
    dispatch(fetchBoard())
  }, [dispatch])

  const [boardRef, columns, setColumns] = useDragAndDrop(kanbanStore.columns, {
    plugins: [animations()],
    dragHandle: '.list-handle'
  })

  // Add New Column
  const addNewColumn = async (title: string) => {
    try {
      const newColumn = await dispatch(createColumnAsync(title)).unwrap()
      setColumns([...columns, newColumn])
    } catch (error) {
      console.error('Error creating column:', error)
    }
  }

  // To get the current task for the drawer
  const currentTask = kanbanStore.tasks.find(task => task.id === kanbanStore.currentTaskId)

  // Update Columns on Drag and Drop
  useEffect(() => {
    if (columns !== kanbanStore.columns) {
      dispatch(updateColumns(columns))
      // Find moved tasks and update via API
      columns.forEach((column, columnIndex) => {
        const oldColumn = kanbanStore.columns.find(col => col.id === column.id)
        if (oldColumn) {
          const movedTasks = column.taskIds.filter(taskId => !oldColumn.taskIds.includes(taskId))
          movedTasks.forEach((taskId, taskIndex) => {
            const fromColumn = kanbanStore.columns.find(col => col.taskIds.includes(taskId))
            if (fromColumn) {
              dispatch(
                moveTaskAsync({
                  taskId,
                  fromColumnId: fromColumn.id,
                  toColumnId: column.id,
                  position: taskIndex
                })
              )
            }
          })
        }
      })
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [columns])

  return (
    <div className='flex items-start gap-6'>
      <div ref={boardRef as RefObject<HTMLDivElement>} className='flex gap-6'>
        {columns.map(column => (
          <KanbanList
            key={column.id}
            dispatch={dispatch}
            column={column}
            store={kanbanStore}
            setDrawerOpen={setDrawerOpen}
            columns={columns}
            setColumns={setColumns}
            currentTask={currentTask}
            tasks={column.taskIds.map(taskId => kanbanStore.tasks.find(task => task.id === taskId))}
          />
        ))}
      </div>
      <NewColumn addNewColumn={addNewColumn} />
      {currentTask && (
        <KanbanDrawer
          task={currentTask}
          drawerOpen={drawerOpen}
          setDrawerOpen={setDrawerOpen}
          dispatch={dispatch}
          columns={columns}
          setColumns={setColumns}
        />
      )}
    </div>
  )
}

export default KanbanBoard
