import { DayPicker, type DateRange as RdpDateRange } from 'react-day-picker'
import { cn, surface } from './cva'

// Platform-owned date range. The public `CalendarProps` seam MUST NOT carry the
// optional-peer date library's range type — it ships from the same barrel as every
// other primitive, so leaking it would break the type contract for any consumer
// (e.g. Badge-only) without that optional peer installed. The peer's type is used
// internal-only (function-body casts), erased from the published DTS.
// (Line comments, not a /** */ doc block — keeps the peer's package name out of dist/index.d.ts so the leak-check grep stays clean.)
export interface DateRange {
  from?: Date
  to?: Date
}

export interface CalendarProps {
  selected?: Date | Date[] | DateRange
  onSelect?(d: Date | undefined): void
  mode?: 'single' | 'multiple' | 'range'
  month?: Date
  onMonthChange?(month: Date): void
}

const calendarClassNames = {
  root: cn(surface({ tone: 'surface', radius: 'lg' }), 'p-3'),
  month_caption: 'flex items-center justify-center text-fg',
  nav: 'flex items-center gap-1',
  button_previous: cn(
    surface({ tone: 'surface', radius: 'md' }),
    'inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center border border-border hover:bg-[var(--mod-color-accent-a3)] active:bg-[var(--mod-color-accent-a4)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]',
  ),
  button_next: cn(
    surface({ tone: 'surface', radius: 'md' }),
    'inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center border border-border hover:bg-[var(--mod-color-accent-a3)] active:bg-[var(--mod-color-accent-a4)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]',
  ),
  month_grid: 'w-full border-collapse',
  weekdays: 'text-fg-muted',
  weekday: 'text-center text-sm font-normal',
  week: '',
  day: 'p-0 text-center',
  day_button: cn(
    'inline-flex h-[var(--mod-touch-min)] w-[var(--mod-touch-min)] items-center justify-center rounded-md text-sm text-fg hover:bg-[var(--mod-color-accent-4)] hover:text-[var(--mod-color-accent-contrast)] active:bg-[var(--mod-color-accent-5)] active:text-[var(--mod-color-accent-contrast)] focus-visible:outline-[var(--mod-focus-ring-width)] focus-visible:outline-[var(--mod-focus-ring-color)] focus-visible:outline-offset-[var(--mod-focus-ring-offset)]',
  ),
  selected:
    'bg-[var(--mod-color-accent-9)] text-[var(--mod-color-accent-contrast)] hover:bg-[var(--mod-color-accent-10)] hover:text-[var(--mod-color-accent-contrast)] active:bg-[var(--mod-color-accent-11)]',
  today: 'border border-border',
  outside: 'text-fg-muted opacity-50',
  disabled: 'text-fg-muted opacity-[var(--mod-opacity-disabled)]',
}

export function Calendar({ selected, onSelect, mode = 'single', month, onMonthChange }: CalendarProps) {
  if (mode === 'multiple') {
    return (
      <DayPicker
        mode="multiple"
        selected={selected as Date[] | undefined}
        month={month}
        onMonthChange={onMonthChange}
        onSelect={(dates) => onSelect?.(dates?.[dates.length - 1])}
        classNames={calendarClassNames}
        showOutsideDays
      />
    )
  }

  if (mode === 'range') {
    const range = selected as DateRange | undefined
    return (
      <DayPicker
        mode="range"
        selected={range ? ({ from: range.from, to: range.to } as RdpDateRange) : undefined}
        month={month}
        onMonthChange={onMonthChange}
        onSelect={(r) => onSelect?.(r?.to ?? r?.from)}
        classNames={calendarClassNames}
        showOutsideDays
      />
    )
  }

  return (
    <DayPicker
      mode="single"
      selected={selected as Date | undefined}
      month={month}
      onMonthChange={onMonthChange}
      onSelect={(date) => onSelect?.(date)}
      classNames={calendarClassNames}
      showOutsideDays
    />
  )
}
