import React from "react";
function useTina(props) {
  const stringifiedQuery = JSON.stringify({
    query: props.query,
    variables: props.variables
  });
  const id = React.useMemo(
    () => hashFromQuery(stringifiedQuery),
    [stringifiedQuery]
  );
  const processedData = React.useMemo(() => {
    if (props.data) {
      const dataCopy = JSON.parse(JSON.stringify(props.data));
      return addMetadata(id, dataCopy, []);
    }
  }, [props.data, id]);
  const [data, setData] = React.useState(processedData);
  const [isClient, setIsClient] = React.useState(false);
  const [quickEditEnabled, setQuickEditEnabled] = React.useState(false);
  const [isInTinaIframe, setIsInTinaIframe] = React.useState(false);
  React.useEffect(() => {
    setIsClient(true);
    setData(processedData);
    parent.postMessage({
      type: "url-changed"
    });
  }, [id, processedData]);
  React.useEffect(() => {
    if (quickEditEnabled) {
      let mouseDownHandler = function(e) {
        const attributeNames = e.target.getAttributeNames();
        const tinaAttribute = attributeNames.find(
          (name) => name.startsWith("data-tina-field")
        );
        let fieldName;
        if (tinaAttribute) {
          e.preventDefault();
          e.stopPropagation();
          fieldName = e.target.getAttribute(tinaAttribute);
        } else {
          const ancestor = e.target.closest(
            "[data-tina-field], [data-tina-field-overlay]"
          );
          if (ancestor) {
            const attributeNames2 = ancestor.getAttributeNames();
            const tinaAttribute2 = attributeNames2.find(
              (name) => name.startsWith("data-tina-field")
            );
            if (tinaAttribute2) {
              e.preventDefault();
              e.stopPropagation();
              fieldName = ancestor.getAttribute(tinaAttribute2);
            }
          }
        }
        if (fieldName) {
          if (lastHoveredField !== null) {
            lastHoveredField = null;
            if (isInTinaIframe) {
              parent.postMessage(
                { type: "field:hovered", fieldName: null },
                window.location.origin
              );
            }
          }
          if (isInTinaIframe) {
            parent.postMessage(
              { type: "field:selected", fieldName },
              window.location.origin
            );
          }
        }
      }, mouseEnterHandler = function(e) {
        if (!(e.target instanceof Element)) {
          return;
        }
        const attributeNames = e.target.getAttributeNames();
        const tinaAttribute = attributeNames.find(
          (name) => name.startsWith("data-tina-field")
        );
        let fieldName;
        if (tinaAttribute) {
          fieldName = e.target.getAttribute(tinaAttribute);
        } else {
          const ancestor = e.target.closest(
            "[data-tina-field], [data-tina-field-overlay]"
          );
          if (ancestor) {
            const attributeNames2 = ancestor.getAttributeNames();
            const tinaAttribute2 = attributeNames2.find(
              (name) => name.startsWith("data-tina-field")
            );
            if (tinaAttribute2) {
              fieldName = ancestor.getAttribute(tinaAttribute2);
            }
          }
        }
        if (fieldName && fieldName !== lastHoveredField) {
          lastHoveredField = fieldName;
          if (isInTinaIframe) {
            parent.postMessage(
              { type: "field:hovered", fieldName },
              window.location.origin
            );
          }
        }
      };
      const style = document.createElement("style");
      style.type = "text/css";
      style.textContent = `
        [data-tina-field] {
          outline: 2px dashed rgba(34,150,254,0.5);
          transition: box-shadow ease-out 150ms;
        }
        [data-tina-field]:hover {
          box-shadow: inset 100vi 100vh rgba(34,150,254,0.3);
          outline: 2px solid rgba(34,150,254,1);
          cursor: pointer;
        }
        [data-tina-field-focused] {
          outline: 2px dashed #C2410C !important;
          box-shadow: none !important;
        }
        [data-tina-field-focused]:hover {
          box-shadow: inset 100vi 100vh rgba(194, 65, 12, 0.3) !important;
          outline: 2px solid #C2410C !important;
          cursor: pointer;
        }
        [data-tina-field-overlay] {
          outline: 2px dashed rgba(34,150,254,0.5);
          position: relative;
        }
        [data-tina-field-overlay]:hover {
          cursor: pointer;
          outline: 2px solid rgba(34,150,254,1);
        }
        [data-tina-field-overlay]::after {
          content: '';
          position: absolute;
          inset: 0;
          z-index: 20;
          transition: opacity ease-out 150ms;
          background-color: rgba(34,150,254,0.3);
          opacity: 0;
        }
        [data-tina-field-overlay]:hover::after {
          opacity: 1;
        }
        [data-tina-field-overlay][data-tina-field-focused]::after {
          background-color: rgba(194, 65, 12, 0.3);
          opacity: 1;
        }
      `;
      document.head.appendChild(style);
      document.body.classList.add("__tina-quick-editing-enabled");
      let lastHoveredField = null;
      document.addEventListener("click", mouseDownHandler, true);
      document.addEventListener("mouseenter", mouseEnterHandler, true);
      return () => {
        document.removeEventListener("click", mouseDownHandler, true);
        document.removeEventListener("mouseenter", mouseEnterHandler, true);
        document.body.classList.remove("__tina-quick-editing-enabled");
        style.remove();
      };
    }
  }, [quickEditEnabled, isInTinaIframe]);
  React.useEffect(() => {
    if (props == null ? void 0 : props.experimental___selectFormByFormId) {
      parent.postMessage({
        type: "user-select-form",
        formId: props.experimental___selectFormByFormId()
      });
    }
  }, [id]);
  const lastFocusedFieldRef = React.useRef(null);
  React.useEffect(() => {
    const { experimental___selectFormByFormId, ...rest } = props;
    parent.postMessage({ type: "open", ...rest, id }, window.location.origin);
    const handleMessage = (event) => {
      if (event.data.type === "quickEditEnabled") {
        setQuickEditEnabled(event.data.value);
      }
      if (event.data.id === id && event.data.type === "updateData") {
        const rawData = event.data.data;
        const newlyProcessedData = addMetadata(
          id,
          JSON.parse(JSON.stringify(rawData)),
          []
        );
        setData(newlyProcessedData);
        setIsInTinaIframe(true);
        const anyTinaField = document.querySelector("[data-tina-field]");
        if (anyTinaField) {
          parent.postMessage(
            { type: "quick-edit", value: true },
            window.location.origin
          );
        } else {
          parent.postMessage(
            { type: "quick-edit", value: false },
            window.location.origin
          );
        }
      }
      if (event.data.type === "field:set-focused") {
        const newFieldName = event.data.fieldName;
        if (newFieldName === lastFocusedFieldRef.current) {
          return;
        }
        lastFocusedFieldRef.current = newFieldName;
        const allTinaFields = document.querySelectorAll("[data-tina-field]");
        allTinaFields.forEach((el) => {
          el.removeAttribute("data-tina-field-focused");
        });
        if (newFieldName) {
          let targetElement = document.querySelector(
            `[data-tina-field="${newFieldName}"]`
          );
          if (!targetElement) {
            const allFields = Array.from(allTinaFields);
            targetElement = allFields.find((el) => {
              const fieldValue = el.getAttribute("data-tina-field");
              return fieldValue && fieldValue.endsWith(newFieldName.split("---")[1]);
            });
          }
          if (targetElement) {
            targetElement.setAttribute("data-tina-field-focused", "true");
            const rect = targetElement.getBoundingClientRect();
            const isInViewport = rect.top >= 0 && rect.left >= 0 && rect.bottom <= window.innerHeight && rect.right <= window.innerWidth;
            if (!isInViewport) {
              targetElement.scrollIntoView({
                behavior: "smooth",
                block: "center"
              });
            }
          }
        }
      }
    };
    window.addEventListener("message", handleMessage);
    return () => {
      window.removeEventListener("message", handleMessage);
      parent.postMessage({ type: "close", id }, window.location.origin);
    };
  }, [id, setQuickEditEnabled]);
  return { data, isClient };
}
function useEditState() {
  const [edit, setEdit] = React.useState(false);
  React.useEffect(() => {
    if (typeof window !== "undefined") {
      parent.postMessage({ type: "isEditMode" }, window.location.origin);
      window.addEventListener("message", (event) => {
        var _a;
        if (((_a = event.data) == null ? void 0 : _a.type) === "tina:editMode") {
          setEdit(true);
        }
      });
    }
  }, []);
  return { edit };
}
const tinaField = (object, property, index) => {
  const contentSource = object == null ? void 0 : object._content_source;
  if (!contentSource) {
    return "";
  }
  const { queryId, path } = contentSource;
  if (!property) {
    return `${queryId}---${path.join(".")}`;
  }
  const fullPath = typeof index === "number" ? [...path, property, index] : [...path, property];
  return `${queryId}---${fullPath.join(".")}`;
};
const addMetadata = (id, obj, path = []) => {
  if (obj === null) {
    return obj;
  }
  if (isScalarOrUndefined(obj)) {
    return obj;
  }
  if (obj instanceof String) {
    return obj.valueOf();
  }
  if (Array.isArray(obj)) {
    return obj.map(
      (item, index) => addMetadata(id, item, [...path, index])
    );
  }
  const transformedObj = {};
  for (const [key, value] of Object.entries(obj)) {
    const currentPath = [...path, key];
    if ([
      "__typename",
      "_sys",
      "_internalSys",
      "_values",
      "_internalValues",
      "_content_source",
      "_tina_metadata"
    ].includes(key)) {
      transformedObj[key] = value;
    } else {
      transformedObj[key] = addMetadata(id, value, currentPath);
    }
  }
  if (transformedObj && typeof transformedObj === "object" && "type" in transformedObj && transformedObj.type === "root") {
    return transformedObj;
  }
  return { ...transformedObj, _content_source: { queryId: id, path } };
};
function isScalarOrUndefined(value) {
  const type = typeof value;
  if (type === "string")
    return true;
  if (type === "number")
    return true;
  if (type === "boolean")
    return true;
  if (type === "undefined")
    return true;
  if (value == null)
    return true;
  if (value instanceof String)
    return true;
  if (value instanceof Number)
    return true;
  if (value instanceof Boolean)
    return true;
  return false;
}
const hashFromQuery = (input) => {
  let hash = 0;
  for (let i = 0; i < input.length; i++) {
    const char = input.charCodeAt(i);
    hash = (hash << 5) - hash + char & 4294967295;
  }
  const nonNegativeHash = Math.abs(hash);
  const alphanumericHash = nonNegativeHash.toString(36);
  return alphanumericHash;
};
export {
  addMetadata,
  hashFromQuery,
  tinaField,
  useEditState,
  useTina
};
