import { useState, useEffect, useRef } from "react";
import { mapOptions } from "../constants";
import { shuffleArray } from "../utils";
import { voteService } from "../services/api";

export function useVoteLogic() {
  const [cards, setCards] = useState(() => shuffleArray(mapOptions));
  const [selectedCard, setSelectedCard] = useState<number | null>(null);
  const [showConfirmation, setShowConfirmation] = useState(false);
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [voteTimestamp, setVoteTimestamp] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);
  const [pollEnded, setPollEnded] = useState(false);
  const dragItem = useRef<number | null>(null);
  const dragOverItem = useRef<number | null>(null);

  useEffect(() => {
    checkVoteStatus();
  }, []);

  const checkVoteStatus = async () => {
    try {
      const data = await voteService.getVoteStatus();
      setPollEnded(data.isPollEnded);
      
      if (data.hasVoted && data.vote) {
        setVoteTimestamp(data.timestamp || null);
        setCards(data.vote);
        setIsSubmitted(true);
      }
    } catch (error) {
      console.error("Failed to check vote status:", error);
    } finally {
      setLoading(false);
    }
  };

  const handleDragStart = (index: number) => {
    if (isSubmitted || pollEnded) return;
    dragItem.current = index;
  };

  const handleDragEnter = (index: number) => {
    if (isSubmitted || pollEnded) return;
    dragOverItem.current = index;
  };

  const handleDragEnd = () => {
    if (isSubmitted || pollEnded) return;
    const from = dragItem.current;
    const to = dragOverItem.current;
    if (from === null || to === null || from === to) return;
    const updatedCards = [...cards];
    const [removed] = updatedCards.splice(from, 1);
    updatedCards.splice(to, 0, removed);
    setCards(updatedCards);
    dragItem.current = null;
    dragOverItem.current = null;
  };

  const handleCardTap = (index: number) => {
    if (isSubmitted || pollEnded) return;

    if (selectedCard === null) {
      setSelectedCard(index);
    } else if (selectedCard === index) {
      setSelectedCard(null);
    } else {
      const updatedCards = [...cards];
      const [removed] = updatedCards.splice(selectedCard, 1);
      updatedCards.splice(index, 0, removed);
      setCards(updatedCards);
      setSelectedCard(null);
    }
  };

  const handleSubmit = () => {
    setShowConfirmation(true);
  };

  const handleConfirmSubmit = async () => {
    try {
      await voteService.submitVote(cards);
      setIsSubmitted(true);
      setShowConfirmation(false);
      setSelectedCard(null);
      setVoteTimestamp(new Date().toISOString());
    } catch (error) {
      if (error instanceof Error) {
        alert(`Error submitting vote: ${error.message}`);
      } else {
        alert("Failed to submit vote. Please try again.");
      }
    }
  };

  const handleCancelSubmit = () => {
    setShowConfirmation(false);
  };

  const handleTouchStart = (index: number) => {
    dragItem.current = index;
  };

  const handleTouchMove = (e: React.TouchEvent) => {
    e.preventDefault();
    const touch = e.touches[0];
    const elementBelow = document.elementFromPoint(
      touch.clientX,
      touch.clientY
    );
    const cardElement = elementBelow?.closest(
      "[data-card-index]"
    ) as HTMLElement;
    if (cardElement) {
      const index = parseInt(cardElement.dataset.cardIndex || "0");
      dragOverItem.current = index;
    }
  };

  const handleTouchEnd = () => {
    handleDragEnd();
  };

  return {
    cards,
    selectedCard,
    showConfirmation,
    isSubmitted,
    voteTimestamp,
    loading,
    pollEnded,
    handleDragStart,
    handleDragEnter,
    handleDragEnd,
    handleCardTap,
    handleSubmit,
    handleConfirmSubmit,
    handleCancelSubmit,
    handleTouchStart,
    handleTouchMove,
    handleTouchEnd,
  };
}
