import { useCallback, useEffect, useMemo, createElement } from "react";
import { useEnvironment, EntityAccessor, Entity } from "@contember/binding";
import { emptyArray } from "@contember/react-utils";
import { Dropdown, AnchorButton, FieldContainer, Checkbox, ButtonGroup } from "@contember/ui";
import { renderByJoining } from "./renderByJoining.js";
import { RoutingLink } from "../../../../routing/RoutingLink.js";
import { useRedirect } from "../../../../routing/binding/useRedirect.js";
function DimensionsRenderer(props) {
  const environment = useEnvironment();
  const redirect = useRedirect();
  const renderSelected = useCallback((selectedDimensions2) => {
    const renderer = props.renderSelected || renderByJoining;
    return renderer(selectedDimensions2);
  }, [props.renderSelected]);
  const renderContent = (dimensionData, selectedDimensions2) => {
    const canSelectJustOne = props.minItems === 1 && props.maxItems === 1;
    const selectedDimensionsCount = selectedDimensions2.length;
    const canSelectAnother = selectedDimensionsCount < props.maxItems;
    const canSelectLess = selectedDimensionsCount > props.minItems;
    const getRequestChangeCallback = (dimension) => (reqState) => {
      if (reqState === null) {
        throw "Cannot switch dimension of unmatched request";
      }
      let updatedDimensions;
      if (!dimension.isSelected && !canSelectAnother) {
        updatedDimensions = [...selectedDimensions2.slice(1), dimension];
      } else if (dimension.isSelected && !canSelectLess) {
        updatedDimensions = selectedDimensions2;
      } else {
        updatedDimensions = dimensionData.filter((item) => {
          if (item.slug === dimension.slug) {
            return !item.isSelected;
          }
          return item.isSelected;
        });
      }
      return {
        ...reqState,
        dimensions: {
          ...reqState.dimensions || {},
          [props.dimension]: getUniqueDimensions(updatedDimensions.map((item) => item.slug).slice(0, props.maxItems))
        }
      };
    };
    const renderedDimensions = dimensionData.map((dimension) => {
      if (canSelectJustOne) {
        return /* @__PURE__ */ createElement(RoutingLink, {
          key: dimension.slug,
          to: getRequestChangeCallback(dimension),
          Component: ({ href, onClick }) => /* @__PURE__ */ createElement(AnchorButton, {
            href,
            flow: "block",
            distinction: "seamless",
            active: dimension.isSelected,
            onClick
          }, dimension.label)
        });
      } else {
        return /* @__PURE__ */ createElement(FieldContainer, {
          key: dimension.slug,
          label: dimension.label,
          labelPosition: "labelInlineRight"
        }, /* @__PURE__ */ createElement(Checkbox, {
          key: dimension.slug,
          value: dimension.isSelected,
          disabled: dimension.isSelected && !canSelectLess,
          onChange: () => redirect(getRequestChangeCallback(dimension))
        }));
      }
    });
    if (canSelectJustOne) {
      return /* @__PURE__ */ createElement(ButtonGroup, {
        orientation: "vertical"
      }, renderedDimensions);
    }
    return /* @__PURE__ */ createElement("div", {
      style: { display: "flex", flexDirection: "column", gap: "0.25em", padding: "0.75em" },
      key: "multipleDimensions"
    }, renderedDimensions);
  };
  const getNormalizedData = (currentDimensions, accessor) => {
    const entities = Array.from(accessor);
    const normalized = [];
    for (const entity of entities) {
      if (!(entity instanceof EntityAccessor)) {
        continue;
      }
      const slugField = entity.getField(props.slugField);
      if (typeof slugField.value === "string") {
        const slugValue = slugField.value;
        normalized.push({
          slug: slugValue,
          isSelected: currentDimensions.indexOf(slugValue) !== -1,
          label: /* @__PURE__ */ createElement(Entity, {
            accessor: entity
          }, props.labelFactory)
        });
      }
    }
    return normalized;
  };
  const getUniqueDimensions = (selectedDimensions2) => {
    return selectedDimensions2.filter((item, i, array) => array.indexOf(item) === i);
  };
  const uniqueDimensions = getUniqueDimensions(environment.getDimensionOrElse(props.dimension, []));
  const normalizedData = getNormalizedData(uniqueDimensions, props.accessor);
  const selectedDimensions = normalizedData ? uniqueDimensions.filter((slug) => normalizedData.find((item) => item.slug === slug) !== void 0).map((dimension) => normalizedData.find((item) => item.slug === dimension)).filter((item) => !!item && item.isSelected) : emptyArray;
  useEffect(() => {
    const redirectTarget = selectedDimensions.length === 0 ? normalizedData || [] : selectedDimensions;
    if (normalizedData !== void 0 && selectedDimensions.length === 0 && redirectTarget.length > 0) {
      redirect((requestState) => {
        return {
          ...requestState,
          dimensions: {
            ...requestState?.dimensions ?? {},
            [props.dimension]: getUniqueDimensions(redirectTarget.map((item) => item.slug).slice(0, props.maxItems))
          }
        };
      });
    }
  }, [normalizedData, props.dimension, props.maxItems, redirect, selectedDimensions]);
  const buttonProps = useMemo(() => ({
    size: "small",
    ...props.buttonProps,
    children: renderSelected(selectedDimensions)
  }), [props.buttonProps, renderSelected, selectedDimensions]);
  if (normalizedData.length === 0) {
    return null;
  }
  if (normalizedData.length === 1) {
    return /* @__PURE__ */ createElement("div", {
      className: "dimensionsSwitcher"
    }, /* @__PURE__ */ createElement("div", {
      className: "dimensionsSwitcher-staticSelected"
    }, renderSelected(selectedDimensions)));
  }
  return /* @__PURE__ */ createElement(Dropdown, {
    buttonProps
  }, renderContent(normalizedData, selectedDimensions));
}
export { DimensionsRenderer };
//# sourceMappingURL=DimensionsRenderer.js.map
