'use client';

import _extends from "@babel/runtime/helpers/esm/extends";
import * as React from 'react';
import { DEFAULT_MODE_STORAGE_KEY, DEFAULT_COLOR_SCHEME_STORAGE_KEY } from './getInitColorSchemeScript';
export function getSystemMode(mode) {
  if (typeof window !== 'undefined' && mode === 'system') {
    var mql = window.matchMedia('(prefers-color-scheme: dark)');
    if (mql.matches) {
      return 'dark';
    }
    return 'light';
  }
  return undefined;
}
function processState(state, callback) {
  if (state.mode === 'light' || state.mode === 'system' && state.systemMode === 'light') {
    return callback('light');
  }
  if (state.mode === 'dark' || state.mode === 'system' && state.systemMode === 'dark') {
    return callback('dark');
  }
  return undefined;
}
export function getColorScheme(state) {
  return processState(state, function (mode) {
    if (mode === 'light') {
      return state.lightColorScheme;
    }
    if (mode === 'dark') {
      return state.darkColorScheme;
    }
    return undefined;
  });
}
function initializeValue(key, defaultValue) {
  if (typeof window === 'undefined') {
    return undefined;
  }
  var value;
  try {
    value = localStorage.getItem(key) || undefined;
    if (!value) {
      // the first time that user enters the site.
      localStorage.setItem(key, defaultValue);
    }
  } catch (e) {
    // Unsupported
  }
  return value || defaultValue;
}
export default function useCurrentColorScheme(options) {
  var _options$defaultMode = options.defaultMode,
    defaultMode = _options$defaultMode === void 0 ? 'light' : _options$defaultMode,
    defaultLightColorScheme = options.defaultLightColorScheme,
    defaultDarkColorScheme = options.defaultDarkColorScheme,
    _options$supportedCol = options.supportedColorSchemes,
    supportedColorSchemes = _options$supportedCol === void 0 ? [] : _options$supportedCol,
    _options$modeStorageK = options.modeStorageKey,
    modeStorageKey = _options$modeStorageK === void 0 ? DEFAULT_MODE_STORAGE_KEY : _options$modeStorageK,
    _options$colorSchemeS = options.colorSchemeStorageKey,
    colorSchemeStorageKey = _options$colorSchemeS === void 0 ? DEFAULT_COLOR_SCHEME_STORAGE_KEY : _options$colorSchemeS,
    _options$storageWindo = options.storageWindow,
    storageWindow = _options$storageWindo === void 0 ? typeof window === 'undefined' ? undefined : window : _options$storageWindo;
  var joinedColorSchemes = supportedColorSchemes.join(',');
  var _React$useState = React.useState(function () {
      var initialMode = initializeValue(modeStorageKey, defaultMode);
      var lightColorScheme = initializeValue("".concat(colorSchemeStorageKey, "-light"), defaultLightColorScheme);
      var darkColorScheme = initializeValue("".concat(colorSchemeStorageKey, "-dark"), defaultDarkColorScheme);
      return {
        mode: initialMode,
        systemMode: getSystemMode(initialMode),
        lightColorScheme: lightColorScheme,
        darkColorScheme: darkColorScheme
      };
    }),
    state = _React$useState[0],
    setState = _React$useState[1];
  var colorScheme = getColorScheme(state);
  var setMode = React.useCallback(function (mode) {
    setState(function (currentState) {
      if (mode === currentState.mode) {
        // do nothing if mode does not change
        return currentState;
      }
      var newMode = !mode ? defaultMode : mode;
      try {
        localStorage.setItem(modeStorageKey, newMode);
      } catch (e) {
        // Unsupported
      }
      return _extends({}, currentState, {
        mode: newMode,
        systemMode: getSystemMode(newMode)
      });
    });
  }, [modeStorageKey, defaultMode]);
  var setColorScheme = React.useCallback(function (value) {
    if (!value) {
      setState(function (currentState) {
        try {
          localStorage.setItem("".concat(colorSchemeStorageKey, "-light"), defaultLightColorScheme);
          localStorage.setItem("".concat(colorSchemeStorageKey, "-dark"), defaultDarkColorScheme);
        } catch (e) {
          // Unsupported
        }
        return _extends({}, currentState, {
          lightColorScheme: defaultLightColorScheme,
          darkColorScheme: defaultDarkColorScheme
        });
      });
    } else if (typeof value === 'string') {
      if (value && !joinedColorSchemes.includes(value)) {
        console.error("`".concat(value, "` does not exist in `theme.colorSchemes`."));
      } else {
        setState(function (currentState) {
          var newState = _extends({}, currentState);
          processState(currentState, function (mode) {
            try {
              localStorage.setItem("".concat(colorSchemeStorageKey, "-").concat(mode), value);
            } catch (e) {
              // Unsupported
            }
            if (mode === 'light') {
              newState.lightColorScheme = value;
            }
            if (mode === 'dark') {
              newState.darkColorScheme = value;
            }
          });
          return newState;
        });
      }
    } else {
      setState(function (currentState) {
        var newState = _extends({}, currentState);
        var newLightColorScheme = value.light === null ? defaultLightColorScheme : value.light;
        var newDarkColorScheme = value.dark === null ? defaultDarkColorScheme : value.dark;
        if (newLightColorScheme) {
          if (!joinedColorSchemes.includes(newLightColorScheme)) {
            console.error("`".concat(newLightColorScheme, "` does not exist in `theme.colorSchemes`."));
          } else {
            newState.lightColorScheme = newLightColorScheme;
            try {
              localStorage.setItem("".concat(colorSchemeStorageKey, "-light"), newLightColorScheme);
            } catch (error) {
              // Unsupported
            }
          }
        }
        if (newDarkColorScheme) {
          if (!joinedColorSchemes.includes(newDarkColorScheme)) {
            console.error("`".concat(newDarkColorScheme, "` does not exist in `theme.colorSchemes`."));
          } else {
            newState.darkColorScheme = newDarkColorScheme;
            try {
              localStorage.setItem("".concat(colorSchemeStorageKey, "-dark"), newDarkColorScheme);
            } catch (error) {
              // Unsupported
            }
          }
        }
        return newState;
      });
    }
  }, [joinedColorSchemes, colorSchemeStorageKey, defaultLightColorScheme, defaultDarkColorScheme]);
  var handleMediaQuery = React.useCallback(function (e) {
    if (state.mode === 'system') {
      setState(function (currentState) {
        return _extends({}, currentState, {
          systemMode: e != null && e.matches ? 'dark' : 'light'
        });
      });
    }
  }, [state.mode]);

  // Ref hack to avoid adding handleMediaQuery as a dep
  var mediaListener = React.useRef(handleMediaQuery);
  mediaListener.current = handleMediaQuery;
  React.useEffect(function () {
    var handler = function handler() {
      return mediaListener.current.apply(mediaListener, arguments);
    };

    // Always listen to System preference
    var media = window.matchMedia('(prefers-color-scheme: dark)');

    // Intentionally use deprecated listener methods to support iOS & old browsers
    media.addListener(handler);
    handler(media);
    return function () {
      return media.removeListener(handler);
    };
  }, []);

  // Handle when localStorage has changed
  React.useEffect(function () {
    var handleStorage = function handleStorage(event) {
      var value = event.newValue;
      if (typeof event.key === 'string' && event.key.startsWith(colorSchemeStorageKey) && (!value || joinedColorSchemes.match(value))) {
        // If the key is deleted, value will be null then reset color scheme to the default one.
        if (event.key.endsWith('light')) {
          setColorScheme({
            light: value
          });
        }
        if (event.key.endsWith('dark')) {
          setColorScheme({
            dark: value
          });
        }
      }
      if (event.key === modeStorageKey && (!value || ['light', 'dark', 'system'].includes(value))) {
        setMode(value || defaultMode);
      }
    };
    if (storageWindow) {
      // For syncing color-scheme changes between iframes
      storageWindow.addEventListener('storage', handleStorage);
      return function () {
        return storageWindow.removeEventListener('storage', handleStorage);
      };
    }
    return undefined;
  }, [setColorScheme, setMode, modeStorageKey, colorSchemeStorageKey, joinedColorSchemes, defaultMode, storageWindow]);
  return _extends({}, state, {
    colorScheme: colorScheme,
    setMode: setMode,
    setColorScheme: setColorScheme
  });
}