"use client"

import { useEffect, useState, useMemo, useCallback, useRef } from "react"
import { format, parseISO } from "date-fns"
import type { DateCountEntry } from "@/lib/types"

interface DateScrubberProps {
  dates: DateCountEntry[]
}

interface ScrubberEntry {
  label: string
  date: string
  dateId: string
}

function findVisibleDateId(): string | null {
  const headers = document.querySelectorAll<HTMLElement>("[data-date]")
  const viewportTop = window.scrollY + window.innerHeight * 0.15
  let best: HTMLElement | null = null
  for (const h of headers) {
    if (h.offsetTop <= viewportTop) best = h
    else break
  }
  return best?.id ?? headers[0]?.id ?? null
}

export function DateScrubber({ dates }: DateScrubberProps) {
  const [activeDate, setActiveDate] = useState<string | null>(null)
  const scrollingRef = useRef(false)

  const entries = useMemo<ScrubberEntry[]>(() => {
    const compact = dates.length > 30

    let lastYear = ""
    let lastMonth = ""
    const result: ScrubberEntry[] = []

    for (const { date } of dates) {
      const d = parseISO(date)
      const monthKey = format(d, "yyyy-MM")

      if (compact && monthKey === lastMonth) continue
      lastMonth = monthKey

      const year = format(d, "yyyy")
      const showYear = year !== lastYear
      lastYear = year

      const label = compact
        ? showYear
          ? format(d, "MMM yyyy")
          : format(d, "MMM")
        : showYear
          ? format(d, "MMM d, yyyy")
          : format(d, "MMM d")

      result.push({ label, date, dateId: `date-${date}` })
    }
    return result
  }, [dates])

  useEffect(() => {
    let raf = 0
    const onScroll = () => {
      cancelAnimationFrame(raf)
      raf = requestAnimationFrame(() => {
        if (!scrollingRef.current) {
          setActiveDate(findVisibleDateId())
        }
      })
    }
    window.addEventListener("scroll", onScroll, { passive: true })
    onScroll()
    return () => {
      window.removeEventListener("scroll", onScroll)
      cancelAnimationFrame(raf)
    }
  }, [])

  const scrollToDate = useCallback((dateId: string) => {
    const el = document.getElementById(dateId)
    if (!el) return

    scrollingRef.current = true
    setActiveDate(dateId)
    el.scrollIntoView({ behavior: "smooth", block: "start" })
    setTimeout(() => {
      scrollingRef.current = false
    }, 800)
  }, [])

  const handleClick = useCallback(
    (entry: ScrubberEntry) => {
      const el = document.getElementById(entry.dateId)
      if (el) {
        scrollToDate(entry.dateId)
        return
      }

      const headers = Array.from(
        document.querySelectorAll<HTMLElement>("[data-date]"),
      )
      let closest: HTMLElement | null = null
      for (const h of headers) {
        const d = h.dataset.date ?? ""
        if (d >= entry.date) {
          closest = h
          break
        }
      }
      if (!closest) closest = headers[headers.length - 1] ?? null

      if (closest) {
        scrollingRef.current = true
        setActiveDate(entry.dateId)
        closest.scrollIntoView({ behavior: "smooth", block: "start" })
        setTimeout(() => {
          scrollingRef.current = false
        }, 800)
      }
    },
    [scrollToDate],
  )

  if (entries.length < 1) return null

  return (
    <div className="sticky top-0 flex h-[calc(100svh-7rem)] w-8 shrink-0 flex-col items-center justify-start gap-0.5 overflow-y-auto py-2">
      {entries.map((entry) => (
        <button
          key={entry.dateId}
          onClick={() => handleClick(entry)}
          className={`w-full rounded px-0.5 py-0.5 text-center text-[9px] leading-tight transition-colors ${
            activeDate === entry.dateId
              ? "font-semibold text-foreground"
              : "text-muted-foreground hover:text-foreground"
          }`}
        >
          {entry.label}
        </button>
      ))}
    </div>
  )
}
