import { useRef, useState, useCallback, useEffect } from 'react'
import FullCalendar from '@fullcalendar/react'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import interactionPlugin from '@fullcalendar/interaction'
import useProjectStore from '../../store/useProjectStore'
import useFocusStore from '../../store/useFocusStore'
import useUIStore from '../../store/useUIStore'
import useToastStore from '../../store/useToastStore'
import { updateDeliverable, deleteDeliverable } from '../../api/deliverables'
import DeliverableModal from '../Deliverables/DeliverableModal'
import ContextMenu from '../UI/ContextMenu'
import EventTooltip from './EventTooltip'
import WorkloadHeatmap from './WorkloadHeatmap'

export default function MainCalendar({ onCalendarReady }) {
  const calRef     = useRef(null)
  const wrapperRef = useRef(null)
  const { projects, updateDeliverable: storeUpdate, removeDeliverable } = useProjectStore()
  const openFocus       = useFocusStore(s => s.openFocus)
  const { showHeatmap, toggleHeatmap } = useUIStore()
  const addToast        = useToastStore(s => s.addToast)

  const [modal,       setModal]       = useState({ open: false, deliverable: null, defaultDate: '' })
  const [contextMenu, setContextMenu] = useState(null)
  const [tooltip,     setTooltip]     = useState(null)

  // Expose calendar API to App.jsx for keyboard shortcuts
  useEffect(() => {
    if (calRef.current && onCalendarReady) {
      onCalendarReady(calRef.current.getApi())
    }
  }, [])

  // ResizeObserver: call updateSize() on every frame the container changes width
  // during the sidebar CSS transition so FullCalendar reflows smoothly
  useEffect(() => {
    const el = wrapperRef.current
    if (!el) return
    const ro = new ResizeObserver(() => {
      calRef.current?.getApi().updateSize()
    })
    ro.observe(el)
    return () => ro.disconnect()
  }, [])

  const events = projects.flatMap(p =>
    (p.deliverables || []).map(d => ({
      id:              String(d.id),
      title:           `${p.name}: ${d.title}`,
      start:           d.due_date,
      allDay:          true,
      backgroundColor: p.color,
      borderColor:     p.color,
      extendedProps:   { deliverableId: d.id, projectId: p.id },
    }))
  )

  const getCtx = (projectId, deliverableId) => {
    const project     = projects.find(p => p.id === projectId)
    const deliverable = project?.deliverables.find(d => d.id === deliverableId)
    return { project, deliverable }
  }

  const handleEventClick = useCallback(({ event }) => {
    const { deliverableId, projectId } = event.extendedProps
    openFocus(projectId, deliverableId)
  }, [openFocus])

  // Drag-and-drop with 30-second undo toast
  const handleEventDrop = useCallback(async ({ event, oldEvent }) => {
    const { deliverableId } = event.extendedProps
    const newDate = event.startStr.substring(0, 10)
    const oldDate = oldEvent.startStr.substring(0, 10)
    storeUpdate(await updateDeliverable(deliverableId, { due_date: newDate }))
    addToast({
      message: `Moved to ${newDate}`,
      duration: 30,
      undoFn: async () => {
        storeUpdate(await updateDeliverable(deliverableId, { due_date: oldDate }))
      },
    })
  }, [storeUpdate, addToast])

  // Click empty date - open add modal
  const handleDateClick = useCallback(({ dateStr }) => {
    setModal({ open: true, deliverable: null, defaultDate: dateStr.substring(0, 10) })
  }, [])

  // Date range drag-select - pre-fill modal with start date
  const handleSelect = useCallback(({ startStr }) => {
    setModal({ open: true, deliverable: null, defaultDate: startStr.substring(0, 10) })
  }, [])

  // Attach dblclick + contextmenu + tooltip via eventDidMount
  const handleEventDidMount = useCallback(({ event, el }) => {
    const { deliverableId, projectId } = event.extendedProps

    el.addEventListener('mouseenter', (e) => {
      const { project, deliverable } = getCtx(projectId, deliverableId)
      setTooltip({ x: e.clientX, y: e.clientY, project, deliverable })
    })
    el.addEventListener('mouseleave', () => setTooltip(null))
    el.addEventListener('mousemove', (e) => {
      setTooltip(prev => prev ? { ...prev, x: e.clientX, y: e.clientY } : null)
    })

    el.addEventListener('dblclick', (e) => {
      e.preventDefault(); e.stopPropagation()
      setTooltip(null)
      const { deliverable } = getCtx(projectId, deliverableId)
      if (deliverable) setModal({ open: true, deliverable, defaultDate: '' })
    })

    el.addEventListener('contextmenu', (e) => {
      e.preventDefault(); e.stopPropagation()
      setTooltip(null)
      const { project, deliverable } = getCtx(projectId, deliverableId)
      if (!deliverable) return
      setContextMenu({
        x: e.clientX, y: e.clientY,
        items: [
          { icon: '\u2714\ufe0e', label: 'Edit Deliverable', action: () => setModal({ open: true, deliverable, defaultDate: '' }) },
          { icon: '\u2756', label: 'Open Focus View',  action: () => openFocus(projectId, deliverableId) },
          ...(project?.drive_url ? [{ icon: '\u2b21', label: 'Open Drive Folder', action: () => window.open(project.drive_url, '_blank') }] : []),
          { separator: true },
          { icon: '\u2715', label: 'Delete Deliverable', danger: true,
            action: async () => {
              if (window.confirm(`Delete "${deliverable.title}"?`)) {
                await deleteDeliverable(deliverableId); removeDeliverable(deliverableId)
              }
            }
          },
        ],
      })
    })
  }, [projects, openFocus])

  return (
    <div className="h-full flex flex-col bg-surface" onContextMenu={e => e.preventDefault()}>
      {/* View toggle toolbar */}
      <div className="flex items-center justify-end gap-2 px-4 pt-3 pb-0 flex-shrink-0">
        <button onClick={toggleHeatmap}
          className={`text-xs px-3 py-1.5 rounded-lg border transition-all font-medium
            ${showHeatmap
              ? 'bg-gold text-surface border-gold'
              : 'bg-surface-elevated border-surface-border text-text-muted hover:border-gold/40 hover:text-gold'
            }`}>
          {showHeatmap ? '\u2190 Calendar' : '\u2b21 Heatmap'}
        </button>
      </div>

      {/* Main content area */}
      <div className="flex-1 overflow-hidden">
        {showHeatmap ? (
          <WorkloadHeatmap />
        ) : (
          <div ref={wrapperRef} className="h-full p-4 pt-2">
            <FullCalendar
              ref={calRef}
              plugins={[dayGridPlugin, timeGridPlugin, interactionPlugin]}
              initialView="dayGridMonth"
              headerToolbar={{ left: 'prev,next today', center: 'title', right: 'dayGridMonth,timeGridWeek,timeGridDay' }}
              events={events}
              editable={true}
              selectable={true}
              weekNumbers={true}
              eventDrop={handleEventDrop}
              eventClick={handleEventClick}
              dateClick={handleDateClick}
              select={handleSelect}
              eventDidMount={handleEventDidMount}
              height="100%"
              dayMaxEvents={4}
              eventDisplay="block"
              displayEventTime={false}
            />
          </div>
        )}
      </div>

      <DeliverableModal
        isOpen={modal.open}
        onClose={() => setModal({ open: false, deliverable: null, defaultDate: '' })}
        deliverable={modal.deliverable}
        defaultDate={modal.defaultDate}
      />

      {contextMenu && (
        <ContextMenu x={contextMenu.x} y={contextMenu.y} items={contextMenu.items} onClose={() => setContextMenu(null)} />
      )}

      <EventTooltip tooltip={tooltip} />
    </div>
  )
}
