"use client"

import { Select, SvgUse } from "@ivtui/base"
import clsx from "clsx"
import type * as React from "react"
import { DayPicker } from "react-day-picker"

export type CalendarProps = React.ComponentProps<typeof DayPicker>

function Calendar({
  captionLayout = "label",
  className,
  classNames,
  showOutsideDays = true,
  ...props
}: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      captionLayout={captionLayout}
      className={clsx("p-3", className)}
      classNames={{
        button_next: clsx(
          "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background border border-input bg-background hover:bg-accent hover:text-accent-foreground",
          "size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
        ),
        button_previous: clsx(
          "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background border border-input bg-background hover:bg-accent hover:text-accent-foreground",
          "size-7 bg-transparent p-0 opacity-50 hover:opacity-100",
        ),
        caption_label: "text-sm font-medium aria-hidden:hidden",
        day_button: clsx(
          "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background hover:bg-accent hover:text-accent-foreground",
          "size-9 font-normal",
        ),
        day: "rounded-md p-0 text-center text-sm aria-selected:bg-accent",
        disabled: "*:text-muted-foreground *:opacity-50",
        dropdown: "first:basis-3/5 last:basis-2/5",
        dropdowns: "flex basis-full items-center gap-2 text-sm font-medium",
        hidden: "invisible",
        month_caption: "flex items-center justify-center pt-1",
        month_grid: "w-full border-collapse space-y-1",
        month: clsx("space-y-4", captionLayout !== "label" && !props.hideNavigation && "mt-9"),
        months: "relative flex flex-col gap-y-4 sm:flex-row sm:gap-x-4 sm:gap-y-0",
        nav: "absolute flex w-full items-center justify-between space-x-1 px-1",
        outside:
          "*:text-muted-foreground *:opacity-50 *:aria-selected:bg-accent/50 *:aria-selected:text-muted-foreground *:aria-selected:opacity-30",
        range_end: "rounded-l-none",
        range_middle:
          "rounded-none first:rounded-l-md last:rounded-r-md *:aria-selected:bg-accent *:aria-selected:text-accent-foreground",
        range_start: "rounded-r-none",
        selected:
          "*:bg-primary *:text-primary-foreground *:hover:bg-primary *:hover:text-primary-foreground *:focus:bg-primary *:focus:text-primary-foreground",
        today: "*:bg-accent *:text-accent-foreground",
        week: "mt-2 flex w-full",
        weekday: "w-9 text-[0.8rem] font-normal text-muted-foreground",
        weekdays: "flex",
        ...classNames,
      }}
      components={{
        Chevron: ({ orientation }) => {
          switch (orientation) {
            case "up":
              return <SvgUse icon="chevron-up" className="size-4" />
            case "down":
              return <SvgUse icon="chevron-down" className="size-4" />
            case "left":
              return <SvgUse icon="chevron-left" className="size-4" />
            default:
              return <SvgUse icon="chevron-right" className="size-4" />
          }
        },
        Dropdown: ({ "aria-label": disabled, value, onChange, options }) => {
          return (
            <Select.Root
              disabled={!!disabled}
              value={`${value}`}
              onValueChange={value =>
                onChange?.({
                  target: { value },
                } as React.ChangeEvent<HTMLSelectElement>)
              }
            >
              <Select.Trigger />
              <Select.Content>
                {options?.map(option => (
                  <Select.Item
                    key={option.value}
                    value={`${option.value}`}
                    disabled={option.disabled}
                  >
                    {option.label}
                  </Select.Item>
                ))}
              </Select.Content>
            </Select.Root>
          )
        },
      }}
      {...props}
    />
  )
}
Calendar.displayName = "Calendar"

export { Calendar }
