import { useEffect, useMemo, useState } from 'react';
import { useFormContext } from 'react-hook-form';

import {
  closestCenter,
  DndContext,
  type DragEndEvent,
  DragOverlay,
  type DragStartEvent,
  PointerSensor,
  type UniqueIdentifier,
  useSensor,
  useSensors,
} from '@dnd-kit/core';
import {
  SortableContext,
  verticalListSortingStrategy,
} from '@dnd-kit/sortable';

import {
  type NewPathFormValues,
  type PathCourse,
} from 'src/pages/dashboard/Learning/Paths/types';
import { sortCourses } from 'src/pages/dashboard/Learning/Paths/utils';

import CoursesListItem from './CoursesListItem';
import CoursesSortableListItem from './CoursesSortableListItem';

type CoursesListItemsProps = {
  courses: PathCourse[];
};

const CoursesListItems = ({ courses }: CoursesListItemsProps) => {
  const [sortedCourses, setSortedCourses] = useState(courses);

  const { setValue } = useFormContext<NewPathFormValues>();
  const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
  const sensors = useSensors(useSensor(PointerSensor));

  const handleDragEnd = (event: DragEndEvent) => {
    setActiveId(null);

    const newSortedCourses = sortCourses(
      sortedCourses,
      event.active.id,
      event.over?.id,
    );

    if (!newSortedCourses) return;

    setSortedCourses(newSortedCourses);
    setValue('content.courses', newSortedCourses);
  };

  const handleDragStart = (event: DragStartEvent) =>
    setActiveId(event.active.id);

  const activeCourse = useMemo(
    () => sortedCourses.find(course => course.courseId === activeId),
    [sortedCourses, activeId],
  );

  const activeIndex = useMemo(() => {
    if (!activeId) return -1;
    return sortedCourses.findIndex(course => course.courseId === activeId);
  }, [sortedCourses, activeId]);

  useEffect(() => {
    setSortedCourses(courses);
  }, [courses]);

  return (
    <DndContext
      sensors={sensors}
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
      onDragStart={handleDragStart}
    >
      <SortableContext
        items={sortedCourses}
        strategy={verticalListSortingStrategy}
      >
        {sortedCourses.map((course, index) => (
          <CoursesSortableListItem
            key={course.courseId}
            course={course}
            index={index}
            activeIndex={activeIndex}
          />
        ))}
      </SortableContext>
      <DragOverlay>
        {activeId && activeCourse && (
          <CoursesListItem
            course={activeCourse}
            isOverlay
          />
        )}
      </DragOverlay>
    </DndContext>
  );
};

export default CoursesListItems;
