import React, { useRef, useState } from "react";
import { Box, Paper, Typography } from "@mui/material";
import { useDrag, useDrop } from "react-dnd";
import QuestionsPageCard from "./QuestionPageCard";
import { questionStore, updateQuestionsLists } from "@root/questions";
import IconPlus from "@icons/IconPlus";

export const ItemTypes = {
  QUESTION: "question",
};

interface CardProps {
  event: any;
  index: number;
  moveCard: (fromIndex: number, toIndex: number) => void;
  isDraggingAllowed: boolean;
  setIsDraggingAllowed: React.Dispatch<React.SetStateAction<boolean>>;
}

const Placeholder: React.FC = () => {
  return (
    <Box sx={{ width: "850px", display: "flex", alignItems: "center" }}>
      <Typography sx={{ color: "#7E2AEA", cursor: "default" }}>
        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - - - - - -
        <IconPlus />
      </Typography>
    </Box>
  );
};

const QuestionCard: React.FC<CardProps> = ({ index, moveCard, isDraggingAllowed, setIsDraggingAllowed }) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState<boolean>(false);
  const [isPlaceholderVisible, setIsPlaceholderVisible] = useState<boolean>(false);

  const [{ isDragging: isDragPreviewVisible }, drag, dragPreview] = useDrag(
    () => ({
      type: ItemTypes.QUESTION,
      item: { index },
      canDrag: isDraggingAllowed,
      collect: (monitor) => ({
        isDragging: monitor.isDragging(),
      }),
    }),
    [index, isDraggingAllowed]
  );

  const [, drop] = useDrop({
    accept: ItemTypes.QUESTION,
    hover: (item: { index: number }, monitor) => {
      if (!containerRef.current) {
        return;
      }

      const dragIndex = item.index;
      const hoverIndex = index;

      if (dragIndex === hoverIndex) {
        return;
      }

      const containerRect = containerRef.current.getBoundingClientRect();
      const hoverMiddleY = (containerRect.bottom - containerRect.top) / 2;
      const clientOffset = monitor.getClientOffset();
      const hoverClientY = clientOffset ? clientOffset.y - containerRect.top : 0;

      if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
        setIsPlaceholderVisible(true);
        return;
      }

      if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
        setIsPlaceholderVisible(true);
        return;
      }

      setIsPlaceholderVisible(false);
      moveCard(dragIndex, hoverIndex);
      item.index = hoverIndex;
    },
    drop: () => {
      setIsPlaceholderVisible(false);
    },
  });

  drag(drop(containerRef));

  return (
    <div ref={containerRef}>
      <Paper
        ref={dragPreview}
        sx={{
          maxWidth: "796px",
          width: "100%",
          borderRadius: "12px",
          margin: "20px 0",
          boxShadow: isDragging || isDragPreviewVisible ? "0px 4px 10px rgba(0, 0, 0, 0.25)" : "none",
        }}
      >
        <QuestionsPageCard
          isDraggingAllowed={isDraggingAllowed}
          setIsDraggingAllowed={setIsDraggingAllowed}
          totalIndex={index}
        />
      </Paper>
      {isPlaceholderVisible && <Placeholder />}
    </div>
  );
};

const QuestionList: React.FC = () => {
  const { listQuestions } = questionStore();
  const [isDraggingAllowed, setIsDraggingAllowed] = useState<boolean>(false);

  const moveCard = (fromIndex: number, toIndex: number) => {
    const updatedQuestions = [...listQuestions];
    const [movedItem] = updatedQuestions.splice(fromIndex, 1);
    updatedQuestions.splice(toIndex, 0, movedItem);
    updateQuestionsLists(updatedQuestions);
  };

  return (
    <Box>
      {listQuestions.map((event: any, index: number) => (
        <QuestionCard
          key={event.id}
          event={event}
          index={index}
          moveCard={moveCard}
          isDraggingAllowed={isDraggingAllowed}
          setIsDraggingAllowed={setIsDraggingAllowed}
        />
      ))}
    </Box>
  );
};

export default QuestionList;
