/*
 * Copyright 2025 Palantir Technologies, Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with 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 { Button } from "@base-ui/react/button";
import classnames from "classnames";
import React, { memo, useCallback, useMemo, useState } from "react";
import { Checkbox } from "../../../base-components/checkbox/Checkbox.js";
import { filterValuesBySearch, isNoValue } from "../../utils/filterValues.js";
import { formatCompactCount } from "./formatCompactCount.js";
import { ListogramSkeleton } from "./ListogramSkeleton.js";
import { OptionLabel } from "./OptionLabel.js";
import { useStableData } from "./useStableData.js";
import styles from "./ListogramInput.module.css.js";
import sharedStyles from "./shared.module.css.js";
function ListogramInputInner({
  values,
  maxCount,
  isLoading,
  error,
  selectedValues,
  onChange,
  colorMap,
  displayMode = "full",
  showCount = true,
  isExcluding,
  showFilteredOutValues = true,
  className,
  style,
  maxVisibleItems,
  searchQuery,
  renderValue
}) {
  const [isExpanded, setIsExpanded] = useState(false);
  const stableValues = useStableData(values, isLoading);
  const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);
  const toggleValue = useCallback(value => {
    if (selectedSet.has(value)) {
      onChange(selectedValues.filter(v => v !== value));
    } else {
      onChange([...selectedValues, value]);
    }
  }, [selectedValues, selectedSet, onChange]);
  const filteredValues = useMemo(() => {
    if (searchQuery) {
      return filterValuesBySearch(stableValues, searchQuery, v => {
        const rendered = renderValue?.(v.value);
        return typeof rendered === "string" ? rendered : v.value;
      });
    }
    return stableValues;
  }, [stableValues, searchQuery, renderValue]);
  const sortedValues = useMemo(() => {
    const selected = filteredValues.filter(v => selectedSet.has(v.value));
    const unselected = filteredValues.filter(v => !selectedSet.has(v.value));
    return [...selected, ...unselected];
  }, [filteredValues, selectedSet]);
  const displayValues = useMemo(() => {
    if (isExpanded || !maxVisibleItems) return sortedValues;
    return sortedValues.slice(0, maxVisibleItems);
  }, [sortedValues, maxVisibleItems, isExpanded]);
  const hasMore = maxVisibleItems != null && sortedValues.length > maxVisibleItems;
  return /*#__PURE__*/React.createElement("div", {
    className: classnames(styles.listogram, className),
    style: style,
    "data-loading": isLoading && filteredValues.length > 0
  }, error && /*#__PURE__*/React.createElement("div", {
    className: sharedStyles.errorMessage
  }, "Error loading values: ", error.message), !error && filteredValues.length === 0 && isLoading && /*#__PURE__*/React.createElement(ListogramSkeleton, null), !error && filteredValues.length === 0 && !isLoading && /*#__PURE__*/React.createElement("div", {
    className: sharedStyles.emptyMessage
  }, "No values available"), filteredValues.length > 0 && /*#__PURE__*/React.createElement("div", {
    className: styles.container
  }, displayValues.map(({
    value,
    count
  }) => {
    const percentage = maxCount > 0 ? count / maxCount * 100 : 0;
    const perRowColor = colorMap?.[value];
    const isEmpty = isNoValue(value) || value === "";
    const isFilteredOut = showFilteredOutValues && count === 0 && !selectedSet.has(value);
    return /*#__PURE__*/React.createElement(Button, {
      key: value,
      className: styles.row,
      "data-empty": isEmpty || undefined,
      "data-filtered-out": isFilteredOut || undefined
      // eslint-disable-next-line react/jsx-no-bind
      ,
      onClick: () => toggleValue(value),
      "aria-pressed": selectedSet.has(value),
      style: perRowColor || percentage > 0 ? {
        "--osdk-filter-listogram-bar-fill-scale": percentage / 100,
        ...(perRowColor ? {
          "--osdk-filter-listogram-row-bar-color": perRowColor
        } : undefined)
      } : undefined
    }, /*#__PURE__*/React.createElement("span", {
      className: styles.checkbox,
      onClick: e => e.stopPropagation()
    }, /*#__PURE__*/React.createElement(Checkbox, {
      checked: selectedSet.has(value)
      // eslint-disable-next-line react/jsx-no-bind
      ,
      onCheckedChange: () => toggleValue(value),
      isExcluding: isExcluding
    })), /*#__PURE__*/React.createElement("span", {
      className: styles.label,
      "data-excluding": isExcluding && selectedSet.has(value) || undefined
    }, /*#__PURE__*/React.createElement(OptionLabel, {
      value: value,
      renderValue: renderValue,
      className: styles.noValueLabel
    })), showCount && displayMode !== "minimal" && /*#__PURE__*/React.createElement("span", {
      className: styles.count,
      title: count.toLocaleString()
    }, formatCompactCount(count)), displayMode === "full" && /*#__PURE__*/React.createElement("span", {
      className: styles.bar
    }, /*#__PURE__*/React.createElement("span", {
      className: styles.barFill
    })));
  }), hasMore && !isExpanded && /*#__PURE__*/React.createElement(Button, {
    type: "button",
    className: styles.viewAllButton
    // eslint-disable-next-line react/jsx-no-bind
    ,
    onClick: () => setIsExpanded(true)
  }, "View all (", sortedValues.length, ")")));
}
export const ListogramInput = /*#__PURE__*/memo(ListogramInputInner);
//# sourceMappingURL=ListogramInput.js.map