"use client"

import * as React from "react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { HoverCard, HoverCardContent, HoverCardTrigger } from "@/components/ui/hover-card"
import { cn } from "@/lib/utils"
import { ScrollArea } from "@/components/ui/scroll-area"
import { ChevronLeft, ChevronRight, Clock, Users, Tag, ZoomIn, ZoomOut } from "lucide-react"

type Participant = {
  id: string
  name: string
  image?: string
}

export type WeeklyEvent = {
  id: string
  title: string
  description?: string
  start: string
  end: string
  participants?: Participant[]
  status?: string
  tags?: string[]
}

type WeeklyCalendarProps = {
  events: WeeklyEvent[]
  height: string
}

const HOURS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
const HOUR_HEIGHT = 60
const DAYS = ["Sun", "Mon", "Tue", "Wed", "Thu"]
const TIME_COLUMN_WIDTH = 80 // Increased width for AM/PM format

function formatTime(hour: number): string {
  if (hour === 24) return "12:00 AM"
  if (hour === 0) return "12:00 AM"
  if (hour < 12) return `${hour}:00 AM`
  if (hour === 12) return "12:00 PM"
  return `${hour - 12}:00 PM`
}

function getMonday(date: Date) {
  const day = date.getDay()
  const diff = (day === 0 ? -6 : 1) - day
  const monday = new Date(date)
  monday.setDate(date.getDate() + diff)
  monday.setHours(0, 0, 0, 0)
  return monday
}

function addDays(date: Date, days: number) {
  const d = new Date(date)
  d.setDate(d.getDate() + days)
  return d
}

function dayIndexFromMonday(date: Date) {
  const idx = date.getDay() === 0 ? 6 : date.getDay() - 1
  return Math.min(idx, 5) // cap to Sat for this UI
}

function hourFloat(date: Date) {
  return date.getHours() + date.getMinutes() / 60
}

export function WeeklyCalendar({ events, height }: WeeklyCalendarProps) {
  const [currentDate, setCurrentDate] = React.useState(() => {
    if (!events?.length) return new Date()
    return new Date(events[0].start)
  })
  
  const [zoomedDate, setZoomedDate] = React.useState<Date | null>(null)
  const scrollAreaRef = React.useRef<HTMLDivElement>(null)

  const weekStart = React.useMemo(() => getMonday(currentDate), [currentDate])
  const monthLabel = React.useMemo(() => {
    return currentDate.toLocaleString(undefined, { month: "long", year: "numeric" })
  }, [currentDate])

  const prevMonthLabel = React.useMemo(() => {
    const prevMonth = new Date(currentDate)
    prevMonth.setMonth(prevMonth.getMonth() - 1)
    return prevMonth.toLocaleString(undefined, { month: "short" })
  }, [currentDate])

  const nextMonthLabel = React.useMemo(() => {
    const nextMonth = new Date(currentDate)
    nextMonth.setMonth(nextMonth.getMonth() + 1)
    return nextMonth.toLocaleString(undefined, { month: "short" })
  }, [currentDate])

  const handlePrevWeek = () => {
    setCurrentDate(prev => {
      const newDate = new Date(prev)
      newDate.setDate(newDate.getDate() - 7)
      return newDate
    })
  }

  const handleNextWeek = () => {
    setCurrentDate(prev => {
      const newDate = new Date(prev)
      newDate.setDate(newDate.getDate() + 7)
      return newDate
    })
  }

  const handlePrevMonth = () => {
    setCurrentDate(prev => {
      const newDate = new Date(prev)
      newDate.setMonth(newDate.getMonth() - 1)
      return newDate
    })
  }

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

  // Determine the date range based on zoom level
  const { displayStart, displayEnd, displayDays } = React.useMemo(() => {
    if (zoomedDate) {
      // Single day view
      const start = new Date(zoomedDate)
      start.setHours(0, 0, 0, 0)
      const end = new Date(zoomedDate)
      end.setHours(23, 59, 59, 999)
      return {
        displayStart: start,
        displayEnd: end,
        displayDays: [zoomedDate.toLocaleDateString(undefined, { weekday: 'short' })]
      }
    } else {
      // Week view
      const end = new Date(weekStart)
      end.setDate(end.getDate() + 6)
      end.setHours(23, 59, 59, 999)
      return {
        displayStart: weekStart,
        displayEnd: end,
        displayDays: DAYS
      }
    }
  }, [weekStart, zoomedDate])

  const displayEvents = React.useMemo(() => {
    return events.filter(event => {
      const eventStart = new Date(event.start)
      const eventEnd = new Date(event.end)
      
      return (
        (eventStart >= displayStart && eventStart <= displayEnd) ||
        (eventEnd >= displayStart && eventEnd <= displayEnd) ||
        (eventStart <= displayStart && eventEnd >= displayEnd)
      )
    })
  }, [events, displayStart, displayEnd])

  const handleZoomIn = (dayIndex: number) => {
    if (!zoomedDate) {
      const targetDate = addDays(weekStart, dayIndex)
      setZoomedDate(targetDate)
      // Scroll to 8 AM after zoom
      setTimeout(() => {
        if (scrollAreaRef.current) {
          const viewport = scrollAreaRef.current.querySelector('[data-slot="scroll-area-viewport"]') as HTMLElement
          if (viewport) {
            const scrollTarget = (8 - 1) * HOUR_HEIGHT // 8 AM position
            viewport.scrollTo({ top: scrollTarget, behavior: 'smooth' })
          }
        }
      }, 100)
    }
  }

  const handleZoomOut = () => {
    setZoomedDate(null)
  }

  const handleDayNavigation = (direction: 'prev' | 'next') => {
    if (zoomedDate) {
      const newDate = new Date(zoomedDate)
      newDate.setDate(newDate.getDate() + (direction === 'next' ? 1 : -1))
      setZoomedDate(newDate)
    }
  }

  React.useEffect(() => {
    // Auto scroll to 8 AM when component mounts or zoom changes
    if (scrollAreaRef.current && !zoomedDate) {
      const viewport = scrollAreaRef.current.querySelector('[data-slot="scroll-area-viewport"]') as HTMLElement
      if (viewport) {
        const scrollTarget = (8 - 1) * HOUR_HEIGHT
        viewport.scrollTo({ top: scrollTarget, behavior: 'smooth' })
      }
    }
  }, [zoomedDate])

  const containerHeight = HOURS.length * HOUR_HEIGHT
  const isZoomed = !!zoomedDate
  const gridColumns = isZoomed ? 1 : 5

  return (
    <div className="w-full rounded-3xl bg-rose-50/40 dark:bg-background border border-border p-4 md:p-6">
      {/* Header with navigation */}
      <div className="relative pb-4 md:pb-6">
        {/* Month navigation */}
        <div className="flex items-center justify-between mb-3">
          <Button
            variant="outline"
            size="sm"
            onClick={isZoomed ? () => handleDayNavigation('prev') : handlePrevMonth}
            className="text-sm md:text-base rounded-full bg-white dark:bg-card border px-3 py-1 shadow-sm hover:shadow-md transition-shadow"
          >
            <ChevronLeft className="h-3 w-3 mr-1" />
            {isZoomed ? "Prev Day" : prevMonthLabel}
          </Button>
          <div className="flex items-center gap-3">
            <h2 className="text-xl md:text-2xl font-semibold tracking-tight">
              {isZoomed 
                ? zoomedDate?.toLocaleDateString(undefined, { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric' })
                : monthLabel
              }
            </h2>
            <Button
              variant="ghost"
              size="sm"
              onClick={isZoomed ? handleZoomOut : undefined}
              className="h-8 w-8 p-0 rounded-full hover:bg-white/50 dark:hover:bg-card/50"
              title={isZoomed ? "Zoom out to week view" : "Week view"}
            >
              {isZoomed ? <ZoomOut className="h-4 w-4" /> : <ZoomIn className="h-4 w-4 opacity-50" />}
            </Button>
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={isZoomed ? () => handleDayNavigation('next') : handleNextMonth}
            className="text-sm md:text-base rounded-full bg-white dark:bg-card border px-3 py-1 shadow-sm hover:shadow-md transition-shadow"
          >
            {isZoomed ? "Next Day" : nextMonthLabel}
            <ChevronRight className="h-3 w-3 ml-1" />
          </Button>
        </div>
        
        {/* Week navigation - only show in week view */}
        {!isZoomed && (
          <div className="flex items-center justify-center gap-4">
            <Button
              variant="ghost"
              size="sm"
              onClick={handlePrevWeek}
              className="h-8 w-8 p-0 rounded-full hover:bg-white/50 dark:hover:bg-card/50"
            >
              <ChevronLeft className="h-4 w-4" />
            </Button>
            <span className="text-sm text-muted-foreground">
              Week of {weekStart.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })}
            </span>
            <Button
              variant="ghost"
              size="sm"
              onClick={handleNextWeek}
              className="h-8 w-8 p-0 rounded-full hover:bg-white/50 dark:hover:bg-card/50"
            >
              <ChevronRight className="h-4 w-4" />
            </Button>
          </div>
        )}
      </div>

      <div className="w-full overflow-x-auto scrollbar-hide">
        <div className={cn("min-w-[900px]", isZoomed && "min-w-[400px]")}>
          {/* Days header */}
          <div 
            className={cn("grid gap-0", `grid-cols-${gridColumns}`)} 
            style={{ marginLeft: TIME_COLUMN_WIDTH }}
          >
            {displayDays.map((d, i) => (
              <div 
                key={d} 
                className={cn(
                  "flex flex-col items-center py-2 cursor-pointer hover:bg-muted/50 rounded-lg transition-colors",
                  !isZoomed && "group"
                )}
                onClick={() => !isZoomed && handleZoomIn(i)}
                title={!isZoomed ? "Click to zoom into this day" : undefined}
              >
                <div className="text-sm text-muted-foreground flex items-center gap-1">
                  {d}
                  {!isZoomed && <ZoomIn className="h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity" />}
                </div>
                <div className="text-xs text-muted-foreground">
                  {isZoomed 
                    ? zoomedDate?.getDate()
                    : addDays(weekStart, i).getDate()
                  }
                </div>
              </div>
            ))}
          </div>
          <ScrollArea className={`h-[${height}] overflow-y-auto`} ref={scrollAreaRef}>
          <div className="relative">
            {/* Time labels - Sticky */}
            <div 
              className="sticky left-0 top-0 z-10 bg-transparent backdrop-blur-sm border-r border-border" 
              style={{ width: TIME_COLUMN_WIDTH, height: containerHeight }}
            >
              {HOURS.map((h, i) => (
                <div
                  key={h}
                  className="pr-3 text-sm text-muted-foreground flex items-start justify-end border-b border-border/30"
                  style={{ height: HOUR_HEIGHT }}
                >
                  <span className="mt-1">{formatTime(h)}</span>
                </div>
              ))}
            </div>

            {/* Grid */}
            <div
              className={cn("grid relative", `grid-cols-${gridColumns}`)}
              style={{ height: containerHeight, marginLeft: TIME_COLUMN_WIDTH }}
            >
              {Array.from({ length: gridColumns }).map((_, col) => (
                <div key={col} className="relative border-l border-dashed border-border/70 last:border-r">
                  {HOURS.map((h) => (
                    <div key={h} className="border-t border-dashed border-border/60" style={{ height: HOUR_HEIGHT }} />
                  ))}
                </div>
              ))}

              {/* Events layer */}
              <div className="absolute inset-0 pointer-events-none" aria-hidden>
                {/* spacer to align with grid */}
              </div>

              {displayEvents.map((event) => {
                const start = new Date(event.start)
                const end = new Date(event.end)
                
                let startIdx = 0
                let span = 1
                
                if (!isZoomed) {
                  // Week view: calculate day position
                  startIdx = dayIndexFromMonday(start)
                  const endIdx = Math.max(startIdx, dayIndexFromMonday(end))
                  span = Math.min(5, endIdx - startIdx + 1)
                } else {
                  // Day view: all events in single column
                  startIdx = 0
                  span = 1
                }
                
                const startHour = hourFloat(start)
                const top = (startHour - 1) * HOUR_HEIGHT // Adjusted for 1-24 hour range

                const isPrimary = event.title.toLowerCase().includes("weekly team")

                return (
                  <HoverCard key={event.id}>
                    <HoverCardTrigger asChild>
                      <div
                        className="absolute hover:shadow-md transition-all duration-300 cursor-pointer transform hover:scale-105"
                        style={{
                          top,
                          left: `calc(${startIdx} * (100% / ${gridColumns}))`,
                          width: `calc(${span} * (100% / ${gridColumns}) - 0.5rem)`,
                        }}
                      >
                        <div
                          className={cn(
                            "pointer-events-auto rounded-2xl shadow-sm border flex items-start gap-3 px-4 py-3 md:px-6 md:py-4",
                            isPrimary
                              ? "bg-slate-900 text-white border-transparent"
                              : "bg-white text-foreground"
                          )}
                        >
                          <div className="flex-1 min-w-0">
                            <div className="font-semibold text-sm md:text-base leading-tight line-clamp-1">{event.title}</div>
                            {/* {event.description ? (
                              <div className={cn("text-xs md:text-sm mt-1 line-clamp-1", isPrimary ? "text-white/80" : "text-muted-foreground")}>{event.description}</div>
                            ) : null} */}
                          </div>
                          {event.participants?.length ? (
                            <div className="flex items-center gap-1 md:gap-2 shrink-0">
                              {event.participants.slice(0, 3).map((p, idx) => (
                                <Avatar key={p.id} className={cn("h-6 w-6 border", idx > 0 ? "-ml-2" : "")}>
                                  {p.image && <AvatarImage src={p.image} alt={p.name} />}
                                  <AvatarFallback className={cn(
                                    "text-[10px] font-semibold",
                                    isPrimary
                                      ? ["bg-yellow-400","bg-blue-400","bg-rose-400"][idx] ?? "bg-gray-300"
                                      : "bg-gray-100"
                                  )}>{p.name?.[0] ?? "?"}</AvatarFallback>
                                </Avatar>
                              ))}
                            </div>
                          ) : null}
                        </div>
                      </div>
                    </HoverCardTrigger>
                    <HoverCardContent className="w-80 p-4" side="top" align="start">
                      <div className="space-y-3">
                        {/* Event Title and Status */}
                        <div className="flex items-start justify-between gap-2">
                          <h3 className="font-semibold text-lg leading-tight">{event.title}</h3>
                          <div className={cn(
                            "px-2 py-1 rounded-full text-xs font-medium",
                            event.status === "confirmed" 
                              ? "bg-green-100 text-green-700 dark:bg-green-900 dark:text-green-300"
                              : "bg-yellow-100 text-yellow-700 dark:bg-yellow-900 dark:text-yellow-300"
                          )}>
                            {event.status}
                          </div>
                        </div>

                        {/* Description */}
                        {event.description && (
                          <p className="text-sm text-muted-foreground leading-relaxed">
                            {event.description}
                          </p>
                        )}

                        {/* Time Information */}
                        <div className="flex items-center gap-2 text-sm">
                          <Clock className="h-4 w-4 text-muted-foreground" />
                          <span>
                            {new Date(event.start).toLocaleString(undefined, {
                              weekday: 'short',
                              month: 'short',
                              day: 'numeric',
                              hour: 'numeric',
                              minute: '2-digit',
                              hour12: true
                            })} - {new Date(event.end).toLocaleTimeString(undefined, {
                              hour: 'numeric',
                              minute: '2-digit',
                              hour12: true
                            })}
                          </span>
                        </div>

                        {/* Participants */}
                        {event.participants?.length ? (
                          <div className="space-y-2">
                            <div className="flex items-center gap-2 text-sm">
                              <Users className="h-4 w-4 text-muted-foreground" />
                              <span className="font-medium">Participants ({event.participants.length})</span>
                            </div>
                            <div className="flex flex-wrap gap-2">
                              {event.participants.map((participant) => (
                                <div key={participant.id} className="flex items-center gap-2 bg-muted rounded-lg px-2 py-1">
                                  <Avatar className="h-5 w-5">
                                    {participant.image && <AvatarImage src={participant.image} alt={participant.name} />}
                                    <AvatarFallback className="text-[10px]">{participant.name?.[0] ?? "?"}</AvatarFallback>
                                  </Avatar>
                                  <span className="text-xs font-medium">{participant.name}</span>
                                </div>
                              ))}
                            </div>
                          </div>
                        ) : null}

                        {/* Tags */}
                        {event.tags?.length ? (
                          <div className="space-y-2">
                            <div className="flex items-center gap-2 text-sm">
                              <Tag className="h-4 w-4 text-muted-foreground" />
                              <span className="font-medium">Tags</span>
                            </div>
                            <div className="flex flex-wrap gap-1">
                              {event.tags.map((tag) => (
                                <span
                                  key={tag}
                                  className="px-2 py-1 bg-primary/10 text-primary rounded-md text-xs font-medium"
                                >
                                  {tag}
                                </span>
                              ))}
                            </div>
                          </div>
                        ) : null}
                      </div>
                    </HoverCardContent>
                  </HoverCard>
                )
              })}
            </div>
          </div>
          </ScrollArea>
        </div>
      </div>
    </div>
  )
}

export default WeeklyCalendar

