/*!
 * Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
 * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
 *
 * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and limitations under the License.
 */

import * as Tokens from "@okta/odyssey-design-tokens";
import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
import { hexToRgb } from "./hexToRgb.js";
export const ContrastModeContext = createContext({
  contrastMode: "lowContrast"
});
export const defaultContrast = "lowContrast";
export const useContrastModeContext = () => useContext(ContrastModeContext);
export const hueNeutral50Rgb = hexToRgb(Tokens.HueNeutral50).asFormattedString;
export const isTransparentColor = color => color === "rgba(0, 0, 0, 0)" || color === "transparent";
export const normalizeRgbaToRgb = rgba => rgba.replace(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/, "rgb($1, $2, $3)");
export const getElementComputedBackgroundColor = element => window.getComputedStyle(element).backgroundColor;
export const normalizeBackgroundColor = bgColor => {
  if (/rgba\((\d+),\s*(\d+),\s*(\d+),\s*[\d.]+\)/.test(bgColor)) {
    const normalizedColor = normalizeRgbaToRgb(bgColor);
    return normalizedColor === hueNeutral50Rgb ? Tokens.HueNeutral50 : normalizedColor;
  }
  return bgColor === hueNeutral50Rgb ? Tokens.HueNeutral50 : bgColor;
};
export const defaultParentBackgroundColor = Tokens.HueNeutral50;
export const getBackgroundColor = element => {
  while (element) {
    const bgColor = getElementComputedBackgroundColor(element);
    if (!isTransparentColor(bgColor)) {
      return normalizeBackgroundColor(bgColor);
    }
    element = element.parentElement;
  }
  return defaultParentBackgroundColor;
};
export const useContrastMode = ({
  contrastMode: explicitContrastMode
}) => {
  const contrastContainerRef = useRef(null);
  const {
    contrastMode: existingContrastMode
  } = useContrastModeContext();
  const [parentBackgroundColor, setParentBackgroundColor] = useState(defaultParentBackgroundColor);
  const [contrastMode, setContrastMode] = useState(() => explicitContrastMode || existingContrastMode);
  const updateBackgroundColor = useCallback(() => {
    const newBgColor = getBackgroundColor(contrastContainerRef.current);
    setParentBackgroundColor(newBgColor);
    if (!explicitContrastMode) {
      setContrastMode(newBgColor === Tokens.HueNeutral50 ? "highContrast" : "lowContrast");
    }
  }, [explicitContrastMode]);
  useEffect(() => {
    const observer = new MutationObserver(updateBackgroundColor);
    observer.observe(document.querySelector("html"), {
      attributes: true,
      attributeFilter: ["class", "style"]
    });
    observer.observe(document.head, {
      childList: true,
      subtree: true
    });
    const onTransitionEnd = event => {
      if (event.propertyName === "background-color") {
        updateBackgroundColor();
      }
    };
    document.addEventListener("transitionend", onTransitionEnd);
    updateBackgroundColor();
    return () => {
      document.removeEventListener("transitionend", onTransitionEnd);
      observer.disconnect();
    };
  }, [updateBackgroundColor]);
  return {
    contrastContainerRef,
    contrastMode,
    parentBackgroundColor
  };
};
//# sourceMappingURL=useContrastMode.js.map