/*
 * 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 React, { memo, useCallback, useMemo } from "react";
import { assertUnreachable } from "../../shared/assertUnreachable.js";
import { FilterInputExcludeRow } from "../base/FilterInputExcludeRow.js";
import { ListogramInput } from "../base/inputs/ListogramInput.js";
import { MultiSelectInput } from "../base/inputs/MultiSelectInput.js";
import { SingleSelectInput } from "../base/inputs/SingleSelectInput.js";
import { TextTagsInput } from "../base/inputs/TextTagsInput.js";
import { coerceToString, coerceToStringArray } from "../utils/coerceFilterValue.js";

// Static values are caller-provided options, not aggregation results, so their
// zero counts should not be interpreted as values filtered out by another facet.
const SHOW_FILTERED_OUT_VALUES = false;
/**
 * Hooks for EXACT_MATCH state management (used by LISTOGRAM and TEXT_TAGS).
 */
function useExactMatchState(filterState, onFilterStateChanged, isExcluding) {
  const selectedValues = useMemo(() => filterState?.type === "EXACT_MATCH" ? coerceToStringArray(filterState.values) : [], [filterState]);
  const handleClearAll = useCallback(() => {
    onFilterStateChanged({
      type: "EXACT_MATCH",
      values: [],
      isExcluding
    });
  }, [onFilterStateChanged, isExcluding]);
  const handleChange = useCallback(values => {
    onFilterStateChanged({
      type: "EXACT_MATCH",
      values,
      isExcluding
    });
  }, [onFilterStateChanged, isExcluding]);
  return {
    selectedValues,
    handleClearAll,
    handleChange
  };
}

/**
 * Hooks for SELECT state management (used by SINGLE_SELECT and MULTI_SELECT).
 */
function useSelectState(filterState, onFilterStateChanged, isExcluding) {
  const selectedValue = useMemo(() => filterState?.type === "SELECT" ? coerceToString(filterState.selectedValues[0]) : undefined, [filterState]);
  const selectedValues = useMemo(() => filterState?.type === "SELECT" ? coerceToStringArray(filterState.selectedValues) : [], [filterState]);
  const handleClearAll = useCallback(() => {
    onFilterStateChanged({
      type: "SELECT",
      selectedValues: [],
      isExcluding
    });
  }, [onFilterStateChanged, isExcluding]);
  const handleSingleChange = useCallback(value => {
    onFilterStateChanged({
      type: "SELECT",
      selectedValues: value !== undefined ? [value] : [],
      isExcluding
    });
  }, [onFilterStateChanged, isExcluding]);
  const handleMultiChange = useCallback(selectedValues => {
    onFilterStateChanged({
      type: "SELECT",
      selectedValues,
      isExcluding
    });
  }, [onFilterStateChanged, isExcluding]);
  return {
    selectedValue,
    selectedValues,
    handleClearAll,
    handleSingleChange,
    handleMultiChange
  };
}
function StaticValuesFilterInputInner({
  definition,
  filterState,
  onFilterStateChanged,
  searchQuery,
  excludeRowOpen,
  layout
}) {
  const aggregationValues = useMemo(() => definition.values.map(value => ({
    value,
    count: 0
  })), [definition.values]);
  const isExcluding = filterState?.isExcluding ?? false;
  const exactMatch = useExactMatchState(filterState, onFilterStateChanged, isExcluding);
  const select = useSelectState(filterState, onFilterStateChanged, isExcluding);
  switch (definition.filterComponent) {
    case "LISTOGRAM":
      return /*#__PURE__*/React.createElement(FilterInputExcludeRow, {
        excludeRowOpen: excludeRowOpen,
        filterState: filterState,
        onFilterStateChanged: onFilterStateChanged,
        totalValueCount: aggregationValues.length,
        onClearAll: exactMatch.handleClearAll
      }, /*#__PURE__*/React.createElement(ListogramInput, {
        values: aggregationValues,
        maxCount: 0,
        isLoading: false,
        error: null,
        selectedValues: exactMatch.selectedValues,
        onChange: exactMatch.handleChange,
        colorMap: definition.colorMap,
        displayMode: definition.listogramConfig?.displayMode,
        showCount: definition.showCount,
        isExcluding: isExcluding,
        showFilteredOutValues: SHOW_FILTERED_OUT_VALUES,
        maxVisibleItems: definition.listogramConfig?.maxVisibleItems ?? 5,
        searchQuery: searchQuery,
        renderValue: definition.renderValue
      }));
    case "SINGLE_SELECT":
      return /*#__PURE__*/React.createElement(FilterInputExcludeRow, {
        excludeRowOpen: excludeRowOpen,
        filterState: filterState,
        onFilterStateChanged: onFilterStateChanged,
        totalValueCount: aggregationValues.length,
        onClearAll: select.handleClearAll
      }, /*#__PURE__*/React.createElement(SingleSelectInput, {
        values: aggregationValues,
        isLoading: false,
        error: null,
        selectedValue: select.selectedValue,
        onChange: select.handleSingleChange,
        showCounts: definition.showCount,
        ariaLabel: `Select ${definition.key}`,
        renderValue: definition.renderValue
      }));
    case "MULTI_SELECT":
      return /*#__PURE__*/React.createElement(FilterInputExcludeRow, {
        excludeRowOpen: excludeRowOpen,
        filterState: filterState,
        onFilterStateChanged: onFilterStateChanged,
        totalValueCount: aggregationValues.length,
        onClearAll: select.handleClearAll
      }, /*#__PURE__*/React.createElement(MultiSelectInput, {
        values: aggregationValues,
        isLoading: false,
        error: null,
        selectedValues: select.selectedValues,
        onChange: select.handleMultiChange,
        showCounts: definition.showCount,
        showFilteredOutValues: SHOW_FILTERED_OUT_VALUES,
        ariaLabel: `Search ${definition.key} values`,
        renderValue: definition.renderValue,
        layout: layout
      }));
    case "TEXT_TAGS":
      return /*#__PURE__*/React.createElement(FilterInputExcludeRow, {
        excludeRowOpen: excludeRowOpen,
        filterState: filterState,
        onFilterStateChanged: onFilterStateChanged,
        totalValueCount: aggregationValues.length,
        onClearAll: exactMatch.handleClearAll
      }, /*#__PURE__*/React.createElement(TextTagsInput, {
        suggestions: aggregationValues,
        isLoading: false,
        error: null,
        tags: exactMatch.selectedValues,
        onChange: exactMatch.handleChange
      }));
    default:
      return assertUnreachable(definition.filterComponent);
  }
}
export const StaticValuesFilterInput = /*#__PURE__*/memo(StaticValuesFilterInputInner);
//# sourceMappingURL=StaticValuesFilterInput.js.map