import { SeasonTheme } from './types';

/**
 * Single source of truth for when each seasonal theme auto-activates.
 *
 * Both `getActiveSeason` (the runtime "Auto" selector) and the settings UI read
 * this list, so the date windows shown to the user can never drift from the
 * dates actually used. Order matters: it is the activation PRIORITY — the first
 * entry whose window matches wins (e.g. Deep Space outranks Autumn in their
 * early-October overlap).
 */
export type SeasonScheduleEntry = {
  theme: SeasonTheme;
  /** Human-readable activation window for display in settings. */
  dateRange: string;
  /** Whether this theme is active on the given month (1-12) and day (1-31). */
  matches: (month: number, day: number) => boolean;
};

export const SEASON_SCHEDULE: SeasonScheduleEntry[] = [
  {
    theme: 'newyear',
    dateRange: 'Dec 31 – Jan 2',
    matches: (m, d) => (m === 12 && d === 31) || (m === 1 && d <= 2),
  },
  {
    theme: 'valentines',
    dateRange: 'Feb 10 – 15',
    matches: (m, d) => m === 2 && d >= 10 && d <= 15,
  },
  {
    theme: 'stpatricks',
    dateRange: 'Mar 15 – 18',
    matches: (m, d) => m === 3 && d >= 15 && d <= 18,
  },
  {
    theme: 'aprilfools',
    dateRange: 'Apr 1',
    matches: (m, d) => m === 4 && d === 1,
  },
  {
    theme: 'earthday',
    dateRange: 'Apr 20 – 23',
    matches: (m, d) => m === 4 && d >= 20 && d <= 23,
  },
  {
    theme: 'lunar',
    dateRange: 'Jan 22 – Feb 5',
    matches: (m, d) => (m === 1 && d >= 22) || (m === 2 && d <= 5),
  },
  {
    theme: 'arcade',
    dateRange: 'Sep 12',
    matches: (m, d) => m === 9 && d === 12,
  },
  {
    theme: 'deepspace',
    dateRange: 'Oct 4 – 10',
    matches: (m, d) => m === 10 && d >= 4 && d <= 10,
  },
  {
    theme: 'halloween',
    dateRange: 'Oct 15 – Nov 1',
    matches: (m, d) => (m === 10 && d >= 15) || (m === 11 && d === 1),
  },
  {
    theme: 'christmas',
    dateRange: 'Dec 10 – 30',
    matches: (m, d) => m === 12 && d >= 10,
  },
  {
    theme: 'autumn',
    dateRange: 'Sep 21 – Oct 14',
    matches: (m, d) => (m === 9 && d >= 21) || (m === 10 && d <= 14),
  },
];

/** Map of theme → human-readable activation window (for settings captions). */
export const SEASON_DATE_RANGES: Record<SeasonTheme, string> = SEASON_SCHEDULE.reduce(
  (acc, entry) => {
    acc[entry.theme] = entry.dateRange;
    return acc;
  },
  {} as Record<SeasonTheme, string>,
);

/**
 * The seasonal theme that should be active on `now`, or null if none. First
 * matching entry in SEASON_SCHEDULE priority order wins.
 */
export function getActiveSeason(now: Date): SeasonTheme | null {
  const month = now.getMonth() + 1; // 1-12
  const day = now.getDate();
  return SEASON_SCHEDULE.find((entry) => entry.matches(month, day))?.theme ?? null;
}

/** A seasonal-theme setting value: the active season, a pinned theme, or off. */
export type SeasonalOverride = SeasonTheme | 'auto' | 'off';

/**
 * The theme to render for a `seasonalThemeOverride` at time `now` (epoch ms):
 * 'off' → none, 'auto' → the active season for that instant, else the pinned
 * theme. Kept pure (and unit-tested) so the decision is verifiable without
 * mounting the React overlay.
 */
export function resolveSeasonTheme(override: SeasonalOverride, now: number): SeasonTheme | null {
  if (override === 'off') return null;
  if (override === 'auto') return getActiveSeason(new Date(now));
  return override;
}
