import React, { useEffect, useMemo, useState } from 'react';
import { useAtomValue } from 'jotai';
import { settingsAtom } from '../../state/settings';
import { useReducedMotion } from '../../hooks/useReducedMotion';
import { zIndices } from '../../styles/zIndex';
import { SeasonTheme } from './types';
import { resolveSeasonTheme } from './seasonSchedule';
import { HalloweenOverlay } from './themes/Halloween';
import { ChristmasOverlay } from './themes/Christmas';
import { NewYearOverlay } from './themes/NewYear';
import { AutumnOverlay } from './themes/Autumn';
import { AprilFoolsOverlay } from './themes/AprilFools';
import { LunarNewYearOverlay } from './themes/LunarNewYear';
import { ValentinesOverlay } from './themes/Valentines';
import { StPatricksOverlay } from './themes/StPatricks';
import { EarthDayOverlay } from './themes/EarthDay';
import { DeepSpaceOverlay } from './themes/DeepSpace';
import { ArcadeOverlay } from './themes/Arcade';

// SeasonTheme + the date-window logic now live in leaf modules (single source
// of truth, shared with the settings UI). Re-exported here for existing
// importers that still reach for it from this file.
export type { SeasonTheme };

// ─── Overlay content map (shared between SeasonalOverlay and SeasonalPreview) ──

function buildOverlayContent(theme: SeasonTheme, reduced: boolean): React.ReactNode {
  switch (theme) {
    case 'halloween':
      return <HalloweenOverlay reduced={reduced} />;
    case 'christmas':
      return <ChristmasOverlay reduced={reduced} />;
    case 'newyear':
      return <NewYearOverlay reduced={reduced} />;
    case 'autumn':
      return <AutumnOverlay reduced={reduced} />;
    case 'aprilfools':
      return <AprilFoolsOverlay reduced={reduced} />;
    case 'lunar':
      return <LunarNewYearOverlay reduced={reduced} />;
    case 'valentines':
      return <ValentinesOverlay reduced={reduced} />;
    case 'stpatricks':
      return <StPatricksOverlay reduced={reduced} />;
    case 'earthday':
      return <EarthDayOverlay reduced={reduced} />;
    case 'deepspace':
      return <DeepSpaceOverlay reduced={reduced} />;
    case 'arcade':
      return <ArcadeOverlay reduced={reduced} />;
    default:
      return null;
  }
}

// ─── Full-screen overlay (fixed position, used in App) ────────────────────────

function SeasonalOverlay({ theme, reduced }: { theme: SeasonTheme; reduced: boolean }) {
  return (
    <div
      aria-hidden="true"
      style={{
        position: 'fixed',
        inset: 0,
        pointerEvents: 'none',
        // Below the Night Light overlay (9998) so seasonal particles are tinted
        // by it, and below modals (9999) so dialogs are never obscured.
        zIndex: zIndices.seasonalEffect,
        overflow: 'hidden',
      }}
    >
      {buildOverlayContent(theme, reduced)}
    </div>
  );
}

// ─── Preview overlay (absolute position, contained in a card) ─────────────────

/**
 * Renders the ambient (reduced-motion) version of a seasonal overlay inside
 * a parent container. The parent must have `position: relative; overflow: hidden`.
 */
export function SeasonalPreview({ theme }: { theme: SeasonTheme }) {
  return (
    <div
      aria-hidden="true"
      style={{ position: 'absolute', inset: 0, overflow: 'hidden', pointerEvents: 'none' }}
    >
      {buildOverlayContent(theme, true)}
    </div>
  );
}

// ─── Main exported component ──────────────────────────────────────────────────

export function SeasonalEffect() {
  const settings = useAtomValue(settingsAtom);
  const reduced = useReducedMotion();
  const override = settings.seasonalThemeOverride ?? 'auto';

  // In auto mode, re-evaluate hourly so a long-lived session crosses a
  // season/holiday-window boundary (e.g. into a new day) without a reload —
  // otherwise the active season is frozen at the value it had on mount.
  const [now, setNow] = useState(() => Date.now());
  useEffect(() => {
    if (override !== 'auto') return undefined;
    // Refresh on entering auto too: `now` may be a stale mount-time value if we
    // were previously in a pinned/off mode (the interval only runs while auto).
    setNow(Date.now());
    const id = window.setInterval(() => setNow(Date.now()), 60 * 60 * 1000);
    return () => window.clearInterval(id);
  }, [override]);

  const theme = useMemo<SeasonTheme | null>(
    () => resolveSeasonTheme(override, now),
    [override, now],
  );

  if (!theme) return null;
  // Suppress seasonal overlay when a chat background is active — both running simultaneously
  // wastes GPU and looks cluttered. The settings UI enforces mutual exclusion on write;
  // this guard covers any legacy state already persisted.
  if (settings.chatBackground !== 'none') return null;
  return <SeasonalOverlay theme={theme} reduced={reduced} />;
}
