"use client"

import { useState, useCallback, useRef, useEffect } from "react"
import { CalendarIcon, ChevronLeft, ChevronRight, Clock, CheckCircle2 } from "lucide-react"
import Flatpickr from "react-flatpickr"
import "flatpickr/dist/flatpickr.min.css"
import PostCard from "@/Components/Calendar/PostCard"

const CalendarView = ({
  currentDate,
  setCurrentDate,
  dateRange,
  setDateRange,
  posts = [],
  onMenuAction,
  openMenus,
  onToggleMenu,
  onDragStart,
  handleScheduleChange,
  draggedPost
}) => {
  const [showCalendarMenu, setShowCalendarMenu] = useState(false)
  const [dragOverDate, setDragOverDate] = useState(null)
  const [isDragging, setIsDragging] = useState(false)
  const [dragPreview, setDragPreview] = useState(null)
  const [rescheduleLoading, setRescheduleLoading] = useState(null)
  const [rescheduleSuccess, setRescheduleSuccess] = useState(null)

  const dragTimeoutRef = useRef(null)
  const successTimeoutRef = useRef(null)

  const monthNames = [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
  ]

  const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]

  const navigateMonth = (direction) => {
    setCurrentDate((prev) => {
      const newDate = new Date(prev)
      newDate.setMonth(prev.getMonth() + direction)
      return newDate
    })
  }

  const formatDateRange = () => {
    const { startDate, endDate } = dateRange
    const formatDate = (date) => {
      return date.toLocaleDateString("en-US", {
        month: "short",
        day: "numeric",
      })
    }
    return `${formatDate(startDate)} - ${formatDate(endDate)}`
  }

  const handleDateChange = (selectedDates) => {
    if (selectedDates.length === 2) {
      setDateRange({
        startDate: selectedDates[0],
        endDate: selectedDates[1],
      })
      setShowCalendarMenu(false)
    }
  }

  const getDaysInMonth = (date) => {
    const year = date.getFullYear()
    const month = date.getMonth()
    const daysInMonth = new Date(year, month + 1, 0).getDate()
    const daysArray = []

    for (let i = 1; i <= daysInMonth; i++) {
      daysArray.push(i)
    }

    return daysArray
  }

  const getPostsForDay = (day) => {
    const currentYear = currentDate.getFullYear()
    const currentMonth = currentDate.getMonth()
    const targetDate = new Date(currentYear, currentMonth, day)
    const targetDateString = targetDate.toISOString().split("T")[0]

    const filteredPosts = posts.filter((post) => {
      if (!post.dateGroup) return false

      const postDateString = post.dateGroup.split("T")[0]
      return postDateString === targetDateString
    })

    return filteredPosts
  }

  // Professional drag and drop handlers with smooth animations
  const handleDragOver = useCallback((e, day) => {
    try {
      e.preventDefault()
      e.stopPropagation()

      if (e.dataTransfer) {
        e.dataTransfer.dropEffect = "move"
      }

      // Debounce the drag over state changes for smoother performance
      if (dragOverDate !== day) {
        // Cancel any pending drag over updates
        if (dragTimeoutRef.current) {
          clearTimeout(dragTimeoutRef.current)
        }

        // Set new drag over state with slight delay for smoothness
        dragTimeoutRef.current = setTimeout(() => {
          setDragOverDate(day)
        }, 10)
      }
    } catch (error) {
      console.warn('Drag over error:', error)
    }
  }, [dragOverDate])

  const handleDragEnter = useCallback((e, day) => {
    try {
      e.preventDefault()
      e.stopPropagation()

      if (!isDragging) setIsDragging(true)

      // Only update if different to prevent unnecessary rerenders
      if (dragOverDate !== day) {
        setDragOverDate(day)
      }
    } catch (error) {
      console.warn('Drag enter error:', error)
    }
  }, [isDragging, dragOverDate])

  const handleDragLeave = useCallback((e) => {
    e.preventDefault()

    // Clear drag over state with slight delay for smooth transitions
    if (dragTimeoutRef.current) clearTimeout(dragTimeoutRef.current)

    dragTimeoutRef.current = setTimeout(() => {
      // Add null check to prevent getBoundingClientRect error
      if (!e.currentTarget) {
        setDragOverDate(null)
        return
      }

      try {
        const rect = e.currentTarget.getBoundingClientRect()
        const x = e.clientX
        const y = e.clientY

        // Only clear if mouse is actually outside the element
        if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
          setDragOverDate(null)
        }
      } catch (error) {
        // If getBoundingClientRect fails, just clear the drag state
        console.warn('Drag leave error:', error)
        setDragOverDate(null)
      }
    }, 50)
  }, [])

  const handleDrop = useCallback(async (e, day) => {
    try {
      e.preventDefault()
      setDragOverDate(null)
      setIsDragging(false)

      if (dragTimeoutRef.current) {
        clearTimeout(dragTimeoutRef.current)
      }

      // Validate event and dataTransfer
      if (!e.dataTransfer) {
        console.warn('Drop event missing dataTransfer')
        return
      }

      const postId = e.dataTransfer.getData("text/plain")
      const post = draggedPost

      if (post && handleScheduleChange && post.id) {
        // Show loading state
        setRescheduleLoading(post.id)

        const currentYear = currentDate.getFullYear()
        const currentMonth = currentDate.getMonth()
        const newDate = new Date(currentYear, currentMonth, day)

        const originalDate = post.dateGroup ? new Date(post.dateGroup) : null
        if (originalDate && !isNaN(originalDate.getTime())) {
          newDate.setHours(originalDate.getHours(), originalDate.getMinutes(), originalDate.getSeconds())
        } else {
          newDate.setHours(6, 0, 0)
        }

        const newDateString = newDate.toISOString().replace(/\.\d{3}Z$/, "Z")

        // Execute schedule change
        await handleScheduleChange(post.id, newDateString)

        // Show success state
        setRescheduleLoading(null)
        setRescheduleSuccess(post.id)

        // Clear success state after animation
        successTimeoutRef.current = setTimeout(() => {
          setRescheduleSuccess(null)
        }, 2000)
      }
    } catch (error) {
      console.error("Failed to reschedule post:", error)
      setRescheduleLoading(null)
      setDragOverDate(null)
      setIsDragging(false)

      // TODO: Add proper error toast notification
      // For now, just log the error
    }
  }, [draggedPost, currentDate, handleScheduleChange])

  // Enhanced drag start handler with improved smoothness
  const handleEnhancedDragStart = useCallback((e, post) => {
    try {
      // Set drag effect for better browser support
      e.dataTransfer.effectAllowed = 'move'
      e.dataTransfer.dropEffect = 'move'

      setIsDragging(true)
      setDragPreview(post)

      // Create a more professional drag image
      if (e.target && document.body) {
        try {
          // Find the closest post card element
          const postCard = e.target.closest('[data-post-card]') || e.target
          const dragElement = postCard.cloneNode(true)

          // Style the drag image for professional appearance
          dragElement.style.position = 'absolute'
          dragElement.style.top = '-1000px'
          dragElement.style.left = '-1000px'
          dragElement.style.transform = 'rotate(3deg) scale(0.9)'
          dragElement.style.opacity = '0.9'
          dragElement.style.background = 'linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%)'
          dragElement.style.color = 'white'
          dragElement.style.borderRadius = '8px'
          dragElement.style.padding = '12px'
          dragElement.style.fontSize = '12px'
          dragElement.style.maxWidth = '200px'
          dragElement.style.boxShadow = '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)'
          dragElement.style.border = '2px solid rgba(255, 255, 255, 0.2)'

          // Remove any nested interactive elements
          const buttons = dragElement.querySelectorAll('button')
          buttons.forEach(btn => btn.style.pointerEvents = 'none')

          document.body.appendChild(dragElement)

          if (e.dataTransfer && e.dataTransfer.setDragImage) {
            e.dataTransfer.setDragImage(dragElement, 75, 30)
          }

          // Clean up drag image after drag starts
          setTimeout(() => {
            try {
              if (document.body && dragElement && document.body.contains(dragElement)) {
                document.body.removeChild(dragElement)
              }
            } catch (cleanupError) {
              console.warn('Cleanup error:', cleanupError)
            }
          }, 50)
        } catch (dragImageError) {
          console.warn('Drag image creation error:', dragImageError)
        }
      }

      if (onDragStart) {
        onDragStart(e, post)
      }
    } catch (error) {
      console.warn('Drag start error:', error)
      // Continue with basic drag functionality
      setIsDragging(true)
      setDragPreview(post)

      if (onDragStart) {
        onDragStart(e, post)
      }
    }
  }, [onDragStart])

  const handleDragEnd = useCallback(() => {
    setIsDragging(false)
    setDragOverDate(null)
    setDragPreview(null)

    if (dragTimeoutRef.current) {
      clearTimeout(dragTimeoutRef.current)
    }
  }, [])

  // Cleanup timeouts on unmount
  useEffect(() => {
    return () => {
      if (dragTimeoutRef.current) clearTimeout(dragTimeoutRef.current)
      if (successTimeoutRef.current) clearTimeout(successTimeoutRef.current)
    }
  }, [])

  return (
    <div className="flex-1 bg-white dark:bg-zinc-900 rounded-xl border border-gray-200 dark:border-zinc-800">
      <div className="p-6 border-b border-gray-200 dark:border-zinc-800">
        <div className="flex items-center justify-between flex-wrap gap-2">
          <div className="flex-1">
            <div className="relative inline-block">
              <div
                className="flex items-center gap-2 p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors cursor-pointer"
                onClick={() => setShowCalendarMenu(!showCalendarMenu)}
              >
                <CalendarIcon className="w-5 h-5 text-gray-600 dark:text-gray-400" />
                <span className="text-sm text-gray-600 dark:text-gray-400">{formatDateRange()}</span>
              </div>

              {showCalendarMenu && (
                <div className="absolute top-full left-0 mt-2 z-50 bg-white dark:bg-zinc-900 border border-gray-200 dark:border-zinc-800 rounded-lg shadow-lg p-4">
                  <Flatpickr
                    options={{
                      mode: "range",
                      dateFormat: "Y-m-d",
                      inline: true,
                      static: true,
                      showMonths: 1,
                      enableTime: false,
                      altInput: false,
                      clickOpens: false,
                    }}
                    value={[dateRange.startDate, dateRange.endDate]}
                    onChange={handleDateChange}
                    className="flatpickr-calendar-custom"
                  />
                </div>
              )}
            </div>
          </div>

          <div className="flex items-center gap-4">
            <button
              onClick={() => navigateMonth(-1)}
              className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              <ChevronLeft className="w-5 h-5 text-gray-600 dark:text-gray-400" />
            </button>

            <h2 className="text-xl font-semibold text-gray-900 dark:text-white min-w-[140px] text-center">
              {monthNames[currentDate.getMonth()]} {currentDate.getFullYear()}
            </h2>

            <button
              onClick={() => navigateMonth(1)}
              className="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors"
            >
              <ChevronRight className="w-5 h-5 text-gray-600 dark:text-gray-400" />
            </button>
          </div>

          <div className="flex-1"></div>
        </div>
      </div>

      <div className="p-6">
        <div className="overflow-x-auto -mx-4 sm:mx-0">
          <div className="min-w-[700px]">
            <div className="grid grid-cols-7 mb-2">
              {dayNames.map((day) => (
                <div key={day} className="p-3 text-center border-b border-gray-200 dark:border-zinc-800">
                  <span className="text-sm font-medium text-gray-600 dark:text-gray-400">{day}</span>
                </div>
              ))}
            </div>

            <div className="grid grid-cols-7 border-l border-t border-gray-200 dark:border-zinc-800">
              {getDaysInMonth(currentDate).map((day, index) => {
                const dayPosts = day ? getPostsForDay(day) : []
                const visiblePosts = dayPosts.slice(0, 3)
                const remainingCount = dayPosts.length - 3

                return (
                  <div
                    key={index}
                    className={`min-h-[120px]  min-w-[100px] p-2 border-r border-b border-gray-200 dark:border-zinc-800 relative ${
                      day
                        ? `bg-white dark:bg-zinc-900 hover:bg-gray-50 dark:hover:bg-gray-700 ${
                            dragOverDate === day
                              ? "bg-gradient-to-br from-blue-50 via-indigo-50 to-purple-50 dark:from-blue-900/30 dark:via-indigo-900/30 dark:to-purple-900/30 border-2 border-dashed border-blue-400 dark:border-blue-500 shadow-lg scale-[1.02]"
                              : ""
                          } ${isDragging ? "transition-all duration-300 ease-out" : "transition-colors"}`
                        : "bg-gray-50 dark:bg-gray-900"
                    }`}
                    onDragOver={(e) => {
                      try {
                        if (day) handleDragOver(e, day)
                      } catch (error) {
                        console.warn('Drag over error:', error)
                      }
                    }}
                    onDragEnter={(e) => {
                      try {
                        if (day) handleDragEnter(e, day)
                      } catch (error) {
                        console.warn('Drag enter error:', error)
                      }
                    }}
                    onDragLeave={(e) => {
                      try {
                        handleDragLeave(e)
                      } catch (error) {
                        console.warn('Drag leave error:', error)
                      }
                    }}
                    onDrop={(e) => {
                      try {
                        if (day) handleDrop(e, day)
                      } catch (error) {
                        console.warn('Drop error:', error)
                      }
                    }}
                  >
                    {/* Professional drag overlay */}
                    {isDragging && dragOverDate === day && (
                      <div className="absolute inset-0 bg-gradient-to-br from-blue-400/10 via-indigo-400/10 to-purple-400/10 dark:from-blue-400/20 dark:via-indigo-400/20 dark:to-purple-400/20 rounded-lg flex items-center justify-center pointer-events-none">
                        <div className="bg-white/90 dark:bg-gray-800/90 backdrop-blur-sm rounded-full p-3 shadow-xl">
                          <Clock className="w-6 h-6 text-blue-600 dark:text-blue-400 animate-pulse" />
                        </div>
                      </div>
                    )}
                    {day && (
                      <>
                        <div className="text-sm font-medium text-gray-900 dark:text-white mb-2">{day}</div>

                        <div className="space-y-1 relative">
                          {visiblePosts.map((post) => (
                            <div key={post.id} className="relative">
                              <PostCard
                                post={post}
                                viewMode="calendar"
                                onMenuAction={onMenuAction}
                                openMenus={openMenus}
                                onToggleMenu={onToggleMenu}
                                onDragStart={handleEnhancedDragStart}
                                onDragEnd={handleDragEnd}
                              />

                              {/* Loading overlay */}
                              {rescheduleLoading === post.id && (
                                <div className="absolute inset-0 bg-white/80 dark:bg-gray-800/80 backdrop-blur-sm rounded-md flex items-center justify-center">
                                  <div className="flex items-center gap-2 text-blue-600 dark:text-blue-400">
                                    <Clock className="w-4 h-4 animate-spin" />
                                    <span className="text-xs font-medium">Rescheduling...</span>
                                  </div>
                                </div>
                              )}

                              {/* Success overlay */}
                              {rescheduleSuccess === post.id && (
                                <div className="absolute inset-0 bg-green-50/90 dark:bg-green-900/50 backdrop-blur-sm rounded-md flex items-center justify-center animate-in fade-in zoom-in-95 duration-500">
                                  <div className="flex items-center gap-2 text-green-600 dark:text-green-400">
                                    <CheckCircle2 className="w-4 h-4 animate-pulse" />
                                    <span className="text-xs font-medium">Rescheduled!</span>
                                  </div>
                                </div>
                              )}
                            </div>
                          ))}

                          {remainingCount > 0 && (
                            <div className="text-center">
                              <span className="text-xs text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-700 px-2 py-1 rounded-full">
                                +{remainingCount} more
                              </span>
                            </div>
                          )}
                        </div>
                      </>
                    )}
                  </div>
                )
              })}
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}

export default CalendarView