"use client"

import * as React from "react"
import {
  format,
  getYear,
  isAfter,
  isSameMonth,
  startOfMonth,
} from "date-fns"
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"

import { cn } from "@/lib/utils"
import { Button, buttonVariants } from "@/components/ui/button"

interface MonthPickerProps {
  selected?: Date
  onSelect?: (month: Date) => void
  className?: string
  disableFutureMonths?: boolean
  fromYear?: number
  toYear?: number
}

function MonthPicker({
  selected,
  onSelect,
  className,
  disableFutureMonths = true,
  fromYear = 2000,
  toYear = getYear(new Date()) + 1,
}: MonthPickerProps) {
  const [viewYear, setViewYear] = React.useState(
    () => getYear(selected ?? new Date()),
  )

  React.useEffect(() => {
    if (selected) {
      setViewYear(getYear(selected))
    }
  }, [selected])

  const months = React.useMemo(
    () =>
      Array.from({ length: 12 }, (_, monthIndex) =>
        startOfMonth(new Date(viewYear, monthIndex, 1)),
      ),
    [viewYear],
  )

  const now = startOfMonth(new Date())
  const canGoBack = viewYear > fromYear
  const canGoForward = viewYear < toYear

  return (
    <div
      data-slot="month-picker"
      className={cn(
        "bg-background p-3 [--cell-size:--spacing(8)]",
        className,
      )}
    >
      <div className="relative flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)">
        <Button
          type="button"
          variant="ghost"
          size="icon"
          className="absolute left-0 size-(--cell-size) p-0 select-none"
          disabled={!canGoBack}
          aria-label="Previous year"
          onClick={() => setViewYear((year) => year - 1)}
        >
          <ChevronLeftIcon className="size-4" />
        </Button>
        <span className="text-sm font-medium select-none">{viewYear}</span>
        <Button
          type="button"
          variant="ghost"
          size="icon"
          className="absolute right-0 size-(--cell-size) p-0 select-none"
          disabled={!canGoForward}
          aria-label="Next year"
          onClick={() => setViewYear((year) => year + 1)}
        >
          <ChevronRightIcon className="size-4" />
        </Button>
      </div>

      <div
        className="mt-3 grid grid-cols-3 gap-2"
        role="grid"
        aria-label={`Select month in ${viewYear}`}
      >
        {months.map((month) => {
          const isSelected = selected ? isSameMonth(month, selected) : false
          const isDisabled =
            disableFutureMonths && isAfter(month, now)

          return (
            <Button
              key={month.toISOString()}
              type="button"
              variant="ghost"
              disabled={isDisabled}
              aria-selected={isSelected}
              aria-label={format(month, "MMMM yyyy")}
              className={cn(
                buttonVariants({ variant: "ghost" }),
                "h-9 w-full rounded-md px-2 text-sm font-normal",
                isSelected &&
                  "bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground",
              )}
              onClick={() => onSelect?.(month)}
            >
              {format(month, "MMM")}
            </Button>
          )
        })}
      </div>
    </div>
  )
}

export { MonthPicker }
