import { useEffect, useState, useCallback, useMemo } from 'react'
import { useNavigate } from 'react-router-dom'
import { fetchAPI } from '../api/client'
import ErrorBanner from '../components/ErrorBanner'

interface CalendarEvent {
  id: number
  media_type: string
  title: string
  date: string
  year: number | null
  status: string
  poster_url: string
}

interface CalendarResponse {
  data: CalendarEvent[]
  month: string
}

const typeColors: Record<string, { bg: string; border: string; text: string }> = {
  movie:     { bg: 'bg-indigo-600/20',  border: 'border-l-indigo-500',  text: 'text-indigo-300' },
  series:    { bg: 'bg-emerald-600/20', border: 'border-l-emerald-500', text: 'text-emerald-300' },
  music:     { bg: 'bg-amber-600/20',   border: 'border-l-amber-500',   text: 'text-amber-300' },
  audiobook: { bg: 'bg-rose-600/20',    border: 'border-l-rose-500',    text: 'text-rose-300' },
  podcast:   { bg: 'bg-violet-600/20',  border: 'border-l-violet-500',  text: 'text-violet-300' },
}

const dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
const monthNames = [
  'January', 'February', 'March', 'April', 'May', 'June',
  'July', 'August', 'September', 'October', 'November', 'December',
]

export default function Calendar() {
  const navigate = useNavigate()
  const now = useMemo(() => new Date(), [])

  const [year, setYear] = useState(now.getFullYear())
  const [month, setMonth] = useState(now.getMonth())
  const [events, setEvents] = useState<CalendarEvent[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  const monthParam = `${year}-${String(month + 1).padStart(2, '0')}`

  const fetchData = useCallback(() => {
    setLoading(true)
    setError(null)
    fetchAPI<CalendarResponse>(`/api/calendar?month=${monthParam}`)
      .then(res => {
        setEvents(res.data ?? [])
      })
      .catch(err => setError(err.message || 'Failed to load calendar events'))
      .finally(() => setLoading(false))
  }, [monthParam])

  useEffect(() => {
    fetchData()
  }, [fetchData])

  const goToPrevMonth = () => {
    if (month === 0) {
      setMonth(11)
      setYear(y => y - 1)
    } else {
      setMonth(m => m - 1)
    }
  }

  const goToNextMonth = () => {
    if (month === 11) {
      setMonth(0)
      setYear(y => y + 1)
    } else {
      setMonth(m => m + 1)
    }
  }

  const goToToday = () => {
    setYear(now.getFullYear())
    setMonth(now.getMonth())
  }

  const handleEventClick = (event: CalendarEvent) => {
    navigate(`/library/${event.media_type}/${event.id}`)
  }

  // Calendar grid calculations
  const firstDay = new Date(year, month, 1).getDay()
  const daysInMonth = new Date(year, month + 1, 0).getDate()
  const today = new Date()
  const isCurrentMonth = today.getFullYear() === year && today.getMonth() === month
  const todayDate = today.getDate()

  // Group events by day
  const eventsByDay = useMemo(() => {
    const map = new Map<number, CalendarEvent[]>()
    for (const event of events) {
      const day = parseInt(event.date.split('-')[2] ?? '0', 10)
      if (day > 0) {
        const existing = map.get(day) ?? []
        existing.push(event)
        map.set(day, existing)
      }
    }
    return map
  }, [events])

  // Build the 42-cell grid (6 rows × 7 cols)
  const cells: (number | null)[] = []
  for (let i = 0; i < firstDay; i++) {
    cells.push(null)
  }
  for (let d = 1; d <= daysInMonth; d++) {
    cells.push(d)
  }
  while (cells.length < 42) {
    cells.push(null)
  }

  return (
    <div>
      <div className="flex items-center justify-between mb-6">
        <div>
          <h2 className="text-2xl font-semibold text-gray-100">Calendar</h2>
          <p className="text-gray-500 text-sm">Upcoming release dates for monitored media</p>
        </div>
        <div className="flex items-center gap-3">
          <button
            onClick={goToToday}
            className="px-3 py-1.5 text-sm font-medium bg-gray-800 border border-gray-700 rounded-lg text-gray-300 hover:bg-gray-700 transition-colors"
          >
            Today
          </button>
          <div className="flex items-center gap-2">
<button
            onClick={goToPrevMonth}
            aria-label="Previous month"
            className="p-1.5 rounded-lg bg-gray-800 border border-gray-700 text-gray-400 hover:text-gray-200 hover:bg-gray-700 transition-colors"
          >
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
            </svg>
          </button>
          <span className="text-gray-100 font-medium min-w-[140px] text-center">
            {monthNames[month]} {year}
          </span>
          <button
            onClick={goToNextMonth}
            aria-label="Next month"
            className="p-1.5 rounded-lg bg-gray-800 border border-gray-700 text-gray-400 hover:text-gray-200 hover:bg-gray-700 transition-colors"
          >
              <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
              </svg>
            </button>
          </div>
        </div>
      </div>

      {error && <ErrorBanner error={error} onRetry={fetchData} />}

      {/* Day-of-week headers */}
      <div className="grid grid-cols-7 gap-1 mb-1">
        {dayLabels.map(d => (
          <div key={d} className="text-center text-xs font-medium text-gray-500 py-2">
            {d}
          </div>
        ))}
      </div>

      {loading ? (
        <div className="grid grid-cols-7 gap-1">
          {Array.from({ length: 42 }).map((_, i) => (
            <div key={i} className="bg-gray-900 border border-gray-800 rounded-lg min-h-[100px] p-2 animate-pulse">
              <div className="h-3 w-6 bg-gray-800 rounded" />
            </div>
          ))}
        </div>
      ) : (
        <div className="grid grid-cols-7 gap-1">
          {cells.map((day, idx) => {
            if (day === null) {
              return <div key={`empty-${idx}`} className="min-h-[100px]" />
            }

            const dayEvents = eventsByDay.get(day) ?? []
            const isToday = isCurrentMonth && day === todayDate
            const maxVisible = 3

            return (
              <div
                key={`day-${day}`}
                className="bg-gray-900 border border-gray-800 rounded-lg min-h-[100px] p-2"
              >
                <span
                  className={`text-xs font-medium ${
                    isToday
                      ? 'text-indigo-400 ring-1 ring-indigo-500 rounded-full w-5 h-5 flex items-center justify-center'
                      : 'text-gray-500'
                  }`}
                >
                  {day}
                </span>
                <div className="mt-1 space-y-0.5">
                  {dayEvents.slice(0, maxVisible).map(event => {
                    const colors = typeColors[event.media_type] ?? { bg: 'bg-gray-600/20', border: 'border-l-gray-500', text: 'text-gray-300' }
                    return (
                      <button
                        key={event.id}
                        onClick={() => handleEventClick(event)}
                        className={`w-full text-left text-xs px-1.5 py-0.5 rounded border-l-2 ${colors.bg} ${colors.border} ${colors.text} hover:brightness-125 transition-all line-clamp-1 cursor-pointer`}
                        title={event.title}
                      >
                        {event.title}
                      </button>
                    )
                  })}
                  {dayEvents.length > maxVisible && (
                    <span className="text-xs text-gray-500 pl-1">
                      +{dayEvents.length - maxVisible} more
                    </span>
                  )}
                </div>
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
