export type GuestThemePayload = {
  primary: string;
  secondary: string;
  background: string;
  surface: string;
  mode?: 'light' | 'dark' | 'auto';
};

type GuestThemeCleanup = () => void;

const prefersDarkScheme = (): boolean => {
  if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') {
    return false;
  }

  return window.matchMedia('(prefers-color-scheme: dark)').matches;
};

const applyColorScheme = (root: HTMLElement, theme: 'light' | 'dark') => {
  if (theme === 'dark') {
    root.classList.add('dark');
    root.style.colorScheme = 'dark';
  } else {
    root.classList.remove('dark');
    root.style.colorScheme = 'light';
  }
};

export function applyGuestTheme(payload: GuestThemePayload): GuestThemeCleanup {
  if (typeof document === 'undefined') {
    return () => {};
  }

  const root = document.documentElement;
  const hadGuestTheme = root.classList.contains('guest-theme');
  const wasDark = root.classList.contains('dark');
  const previousColorScheme = root.style.colorScheme;
  const previousVars = {
    primary: root.style.getPropertyValue('--guest-primary'),
    secondary: root.style.getPropertyValue('--guest-secondary'),
    background: root.style.getPropertyValue('--guest-background'),
    surface: root.style.getPropertyValue('--guest-surface'),
  };

  root.classList.add('guest-theme');
  root.style.setProperty('--guest-primary', payload.primary);
  root.style.setProperty('--guest-secondary', payload.secondary);
  root.style.setProperty('--guest-background', payload.background);
  root.style.setProperty('--guest-surface', payload.surface);

  const mode = payload.mode ?? 'auto';
  if (mode === 'dark') {
    applyColorScheme(root, 'dark');
  } else if (mode === 'light') {
    applyColorScheme(root, 'light');
  } else {
    applyColorScheme(root, prefersDarkScheme() ? 'dark' : 'light');
  }

  return () => {
    if (hadGuestTheme) {
      root.classList.add('guest-theme');
    } else {
      root.classList.remove('guest-theme');
    }

    if (wasDark) {
      root.classList.add('dark');
    } else {
      root.classList.remove('dark');
    }

    if (previousColorScheme) {
      root.style.colorScheme = previousColorScheme;
    } else {
      root.style.removeProperty('color-scheme');
    }

    if (previousVars.primary) {
      root.style.setProperty('--guest-primary', previousVars.primary);
    } else {
      root.style.removeProperty('--guest-primary');
    }

    if (previousVars.secondary) {
      root.style.setProperty('--guest-secondary', previousVars.secondary);
    } else {
      root.style.removeProperty('--guest-secondary');
    }

    if (previousVars.background) {
      root.style.setProperty('--guest-background', previousVars.background);
    } else {
      root.style.removeProperty('--guest-background');
    }

    if (previousVars.surface) {
      root.style.setProperty('--guest-surface', previousVars.surface);
    } else {
      root.style.removeProperty('--guest-surface');
    }
  };
}
