'use client';

import * as React from 'react';
import { ChevronLeft, ChevronRight, ChevronDown } from 'lucide-react';
import { DayPicker } from 'react-day-picker';
import { zhCN } from 'date-fns/locale';
import { cn } from '@/lib/utils';
import { buttonVariants } from './button';

export type CalendarProps = React.ComponentProps<typeof DayPicker>;

const WEEKDAYS_ZH = ['日', '一', '二', '三', '四', '五', '六'];
// 中文格式化:星期"日一二…"、标题"2026年7月"、下拉"7月"/"2026年"。
const zhFormatters = {
  formatWeekdayName: (d: Date) => WEEKDAYS_ZH[d.getDay()] ?? '',
  formatCaption: (d: Date) => `${d.getFullYear()}年${d.getMonth() + 1}月`,
  formatMonthDropdown: (d: Date) => `${d.getMonth() + 1}月`,
  formatYearDropdown: (d: Date) => `${d.getFullYear()}年`,
};

/// shadcn 官方 Calendar(react-day-picker v10)—— 全 Tailwind classNames,不引 rdp 默认样式表。
/// 主题走项目 CSS 变量(--primary=teal-600 / --accent / --ring),故选中/今天/焦点自动是 teal。
/// 支持 captionLayout="dropdown"(月/年下拉)与默认 label(左右翻页箭头)两种 caption。
/**
 * 日历(react-day-picker 封装)— 单选/范围由 mode 决定。
 * @category forms
 */
export function Calendar({ className, classNames, showOutsideDays = true, ...props }: CalendarProps) {
  return (
    <DayPicker
      showOutsideDays={showOutsideDays}
      locale={zhCN}
      weekStartsOn={0}
      formatters={zhFormatters}
      className={cn('relative p-3', className)}
      classNames={{
        months: 'flex flex-col sm:flex-row gap-2',
        month: 'relative flex flex-col gap-4',
        month_caption: 'flex justify-center pt-1 items-center h-9',
        caption_label: 'text-sm font-medium',
        // 月/年下拉(captionLayout="dropdown")
        dropdowns: 'flex items-center justify-center gap-1.5 text-sm font-medium',
        dropdown_root:
          'relative inline-flex items-center gap-1 rounded-md border border-input px-2 py-1 hover:bg-accent focus-within:ring-2 focus-within:ring-ring',
        dropdown: 'absolute inset-0 h-full w-full cursor-pointer opacity-0',
        // 左右翻页箭头:nav 绝对定位横跨日历宽度、两端对齐,箭头落在 caption 两侧(锚到 relative root)。
        // z-10 抬到 month_caption 之上(否则被居中的 caption 盖住导致点不动);容器 pointer-events-none
        // 让空白中段的点击穿透到下方的月/年下拉,按钮各自 pointer-events-auto 可点。
        nav: 'pointer-events-none absolute inset-x-3 top-3 z-10 flex items-center justify-between',
        button_previous: cn(
          buttonVariants({ variant: 'outline' }),
          'pointer-events-auto size-7 bg-transparent p-0 opacity-60 hover:opacity-100',
        ),
        button_next: cn(
          buttonVariants({ variant: 'outline' }),
          'pointer-events-auto size-7 bg-transparent p-0 opacity-60 hover:opacity-100',
        ),
        // 日期网格
        month_grid: 'w-full border-collapse',
        weekdays: 'flex',
        weekday: 'w-8 rounded-md text-[0.8rem] font-normal text-muted-foreground',
        week: 'mt-1 flex w-full',
        day: 'relative size-8 p-0 text-center text-sm focus-within:relative focus-within:z-20',
        day_button: cn(
          buttonVariants({ variant: 'ghost' }),
          'size-8 rounded-md p-0 font-normal aria-selected:opacity-100',
        ),
        // 状态修饰(targeting 内层 button)
        selected:
          '[&>button]:bg-primary [&>button]:text-primary-foreground [&>button]:hover:bg-primary [&>button]:hover:text-primary-foreground',
        today: '[&>button]:bg-accent [&>button]:text-accent-foreground',
        outside: 'text-muted-foreground opacity-50',
        disabled: 'text-muted-foreground opacity-40',
        hidden: 'invisible',
        ...classNames,
      }}
      components={{
        Chevron: ({ orientation, className: c, ...rest }) => {
          const Icon =
            orientation === 'left' ? ChevronLeft : orientation === 'right' ? ChevronRight : ChevronDown;
          return <Icon className={cn('size-4', c)} {...rest} />;
        },
      }}
      {...props}
    />
  );
}
