import type { ReactNode } from "react";

export type CalendarView = "month" | "week" | "day";

/**
 * Named event color — each key maps to a token-backed class set in
 * `constants.ts` (`EVENT_COLOR_CLASSES`). Never pass raw hex; add a key here
 * and wire it to a CSS variable instead (see design system: no hardcoded hex).
 */
export type CalendarEventColor =
  "blue" | "sky" | "amber" | "green" | "red" | "purple" | "gray";

/**
 * A single calendar entry. Generic over `TMeta` so any screen can attach its
 * own payload (an order, a shift, a booking…) and read it back in
 * `onEventClick` / `renderEventDetail` — this is what keeps the component
 * reusable and data-agnostic.
 */
export interface CalendarEvent<TMeta = unknown> {
  id: string;
  title: string;
  start: Date;
  end: Date;
  /** All-day entries render in the top strip (week/day) and as plain chips (month). */
  allDay?: boolean;
  color?: CalendarEventColor;
  /** Arbitrary caller payload, surfaced back in event callbacks/renderers. */
  meta?: TMeta;
}

/** A timed event resolved to a box within a single day column (percent units). */
export interface PositionedEvent<TMeta = unknown> {
  event: CalendarEvent<TMeta>;
  /** Distance from the top of the rendered day range, 0–100. */
  topPct: number;
  /** Height as a share of the rendered day range, 0–100. */
  heightPct: number;
  /** Inline-start offset within the column, 0–100 (flips in RTL via logical CSS). */
  leftPct: number;
  /** Width within the column, 0–100. */
  widthPct: number;
}

export interface CalendarProps<TMeta = unknown> {
  events: CalendarEvent<TMeta>[];

  /** Controlled view. Omit for uncontrolled (seeded by `defaultView`). */
  view?: CalendarView;
  onViewChange?: (view: CalendarView) => void;
  defaultView?: CalendarView;

  /** Controlled focused date. Omit for uncontrolled (seeded by `defaultDate`). */
  date?: Date;
  onDateChange?: (date: Date) => void;
  defaultDate?: Date;

  /** Which views the switcher offers. Default: all three. */
  availableViews?: CalendarView[];

  /** 0 = Sunday … 6 = Saturday. Omit to use the active locale's convention. */
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;

  /** Clicking an event. If omitted, a built-in detail dialog opens instead. */
  onEventClick?: (event: CalendarEvent<TMeta>) => void;
  /** Clicking an empty day cell (month) or time slot (week/day). */
  onSelectSlot?: (date: Date) => void;

  /** Custom event body inside chips/blocks. Falls back to the built-in renderer. */
  renderEvent?: (event: CalendarEvent<TMeta>) => ReactNode;
  /** Custom body for the built-in detail dialog (ignored when `onEventClick` is set). */
  renderEventDetail?: (event: CalendarEvent<TMeta>) => ReactNode;

  /** Filter/actions slot rendered in the toolbar (e.g. a status `<Select>`). */
  toolbar?: ReactNode;

  loading?: boolean;
  /** Override the "no events this period" placeholder. */
  emptyState?: ReactNode;

  className?: string;
}
