/*
 * 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 { Collapsible } from "@base-ui/react/collapsible";
import { CaretDown, Cog, SmallInfoSign } from "@blueprintjs/icons";
import { arrayMove } from "@dnd-kit/sortable";
import classNames from "classnames";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { ActionButton } from "../base-components/action-button/ActionButton.js";
import { Checkbox } from "../base-components/checkbox/Checkbox.js";
import { Dialog } from "../base-components/dialog/Dialog.js";
import { DraggableList } from "../base-components/draggable-list/DraggableList.js";
import { SearchBar } from "../base-components/search-bar/SearchBar.js";
import { useObjectTableLabels, withObjectTableLabels } from "./ObjectTableLabels.js";
import styles from "./ColumnConfigDialog.module.css.js";
export const ColumnConfigDialog = withObjectTableLabels(ColumnConfigDialogInner);
function ColumnConfigDialogInner({
  isOpen,
  onClose,
  columnOptions,
  currentVisibility,
  currentColumnOrder,
  onApply,
  isValidConfig
}) {
  const labels = useObjectTableLabels();
  const [visibleColumns, setVisibleColumns] = useState([]);
  const [searchQuery, setSearchQuery] = useState("");
  const allColumns = useMemo(() => {
    return columnOptions.map(opt => {
      const isVisible = currentVisibility ? currentVisibility[opt.id] : false;
      return {
        id: opt.id,
        label: opt.name,
        isVisible
      };
    });
  }, [columnOptions, currentVisibility]);

  // Sync local state with prop when dialog is opened
  useEffect(() => {
    if (isOpen) {
      const visibleCols = allColumns.filter(col => col.isVisible);

      // Sort by current column order if available
      if (!!currentColumnOrder?.length) {
        visibleCols.sort((a, b) => {
          const indexA = currentColumnOrder.indexOf(a.id);
          const indexB = currentColumnOrder.indexOf(b.id);
          // If not in order array, put at end
          const orderA = indexA === -1 ? Infinity : indexA;
          const orderB = indexB === -1 ? Infinity : indexB;
          return orderA - orderB;
        });
      }
      setVisibleColumns(visibleCols);
      setSearchQuery("");
    }
  }, [isOpen, allColumns, currentColumnOrder]);
  const handleApply = useCallback(() => {
    onApply(getColumnConfig(allColumns, visibleColumns));
    onClose();
  }, [allColumns, visibleColumns, onApply, onClose]);

  // If no condition provided, default to valid
  const isValid = isValidConfig ? isValidConfig(getColumnConfig(allColumns, visibleColumns)) : true;
  const isApplyDisabled = visibleColumns.length === 0 || !isValid;
  const handleReorderColumns = useCallback((fromIndex, toIndex) => {
    setVisibleColumns(items => arrayMove(items, fromIndex, toIndex));
  }, []);
  const handleRemoveColumn = useCallback(columnId => {
    setVisibleColumns(prev => prev.filter(col => col.id !== columnId));
  }, []);
  const handleToggleColumn = useCallback(column => {
    setVisibleColumns(prev => {
      const isCurrentlyVisible = prev.some(col => col.id === column.id);
      if (isCurrentlyVisible) {
        return prev.filter(col => col.id !== column.id);
      } else {
        return [...prev, column];
      }
    });
  }, []);
  const handleSearchChange = useCallback(event => {
    setSearchQuery(event.target.value);
  }, []);
  const handleSelectAll = useCallback(columns => {
    setVisibleColumns(prev => {
      const allSelected = columns.every(col => prev.some(v => v.id === col.id));
      if (allSelected) {
        // Deselect all filtered columns
        return prev.filter(v => !columns.some(col => col.id === v.id));
      } else {
        // Select all filtered columns that aren't already selected
        const newColumns = columns.filter(col => !prev.some(v => v.id === col.id));
        return [...prev, ...newColumns];
      }
    });
  }, []);
  const filteredAvailableColumns = useMemo(() => {
    const query = searchQuery.toLowerCase().trim();
    if (!query) {
      return allColumns;
    }
    return allColumns.filter(col => (col.label?.toLowerCase().includes(query) ?? false) || col.id.toLowerCase().includes(query));
  }, [allColumns, searchQuery]);
  const footer = useMemo(() => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ActionButton, {
    onClick: onClose
  }, labels.columnConfigCancel), /*#__PURE__*/React.createElement(ActionButton, {
    variant: "primary",
    onClick: handleApply,
    disabled: isApplyDisabled
  }, labels.columnConfigApply)), [onClose, handleApply, isApplyDisabled, labels]);
  const dialogTitle = useMemo(() => /*#__PURE__*/React.createElement("div", {
    className: styles.title
  }, /*#__PURE__*/React.createElement(Cog, null), labels.columnConfigTitle), [labels]);
  return /*#__PURE__*/React.createElement(Dialog, {
    isOpen: isOpen,
    onOpenChange: onClose,
    title: dialogTitle,
    footer: footer,
    className: styles.columnConfigDialog
  }, /*#__PURE__*/React.createElement("div", {
    className: styles.dialogLayout
  }, /*#__PURE__*/React.createElement(VisibleColumnsList, {
    columns: visibleColumns,
    onReorder: handleReorderColumns,
    onRemove: handleRemoveColumn
  }), /*#__PURE__*/React.createElement(AvailableColumnsList, {
    visibleColumns: visibleColumns,
    searchQuery: searchQuery,
    onSearchChange: handleSearchChange,
    onToggleColumn: handleToggleColumn,
    onSelectAll: handleSelectAll,
    filteredColumns: filteredAvailableColumns
  })));
}
const getColumnConfig = (allColumns, visibleColumns) => {
  const hiddenColumns = allColumns.filter(col => !visibleColumns.some(v => v.id === col.id));
  return [...visibleColumns.map(col => ({
    columnId: col.id,
    isVisible: true
  })), ...hiddenColumns.map(col => ({
    columnId: col.id,
    isVisible: false
  }))];
};
function VisibleColumnsList({
  columns,
  onReorder,
  onRemove
}) {
  const labels = useObjectTableLabels();
  return /*#__PURE__*/React.createElement("div", {
    className: styles.visibleColumnsContainer
  }, /*#__PURE__*/React.createElement("div", {
    className: styles.sectionHeader
  }, /*#__PURE__*/React.createElement("div", {
    className: styles.sectionTitle
  }, /*#__PURE__*/React.createElement("span", null, labels.columnConfigVisibleColumns), /*#__PURE__*/React.createElement("span", {
    className: styles.countTag
  }, columns.length)), /*#__PURE__*/React.createElement("div", {
    className: styles.sectionHint
  }, labels.columnConfigDragToReorder)), /*#__PURE__*/React.createElement(DraggableList, {
    items: columns,
    onReorder: onReorder,
    onRemove: onRemove,
    removeIconVariant: "trash",
    emptyMessage: labels.columnConfigNoVisibleColumns,
    className: styles.columnList
  }));
}
function AvailableColumnsList({
  visibleColumns,
  searchQuery,
  onSearchChange,
  onToggleColumn,
  onSelectAll,
  filteredColumns
}) {
  const selectedCount = visibleColumns.length;
  const totalCount = filteredColumns.length;
  const allFilteredSelected = filteredColumns.every(col => visibleColumns.some(v => v.id === col.id));
  const someFilteredSelected = filteredColumns.some(col => visibleColumns.some(v => v.id === col.id));
  const labels = useObjectTableLabels();
  const handleSelectAllClick = useCallback(() => {
    onSelectAll(filteredColumns);
  }, [filteredColumns, onSelectAll]);
  return /*#__PURE__*/React.createElement("div", {
    className: styles.availableColumnsContainer
  }, /*#__PURE__*/React.createElement("div", {
    className: classNames(styles.sectionHeader, styles.sectionTitle)
  }, labels.columnConfigAddOrRemoveColumns), /*#__PURE__*/React.createElement(SearchBar, {
    value: searchQuery,
    onChange: onSearchChange,
    placeholder: labels.columnConfigSearchPlaceholder,
    "aria-label": labels.columnConfigSearchAriaLabel,
    className: styles.searchContainer
  }), /*#__PURE__*/React.createElement(Collapsible.Root, {
    defaultOpen: true,
    className: styles.propertiesList
  }, /*#__PURE__*/React.createElement("div", {
    className: styles.categoryHeader
  }, /*#__PURE__*/React.createElement("label", {
    className: styles.selectAllLabel
  }, /*#__PURE__*/React.createElement(Checkbox, {
    checked: allFilteredSelected,
    indeterminate: someFilteredSelected && !allFilteredSelected,
    onCheckedChange: handleSelectAllClick,
    className: styles.checkbox
  }), labels.columnConfigAllColumns), /*#__PURE__*/React.createElement(Collapsible.Trigger, {
    className: styles.categoryTrigger
  }, /*#__PURE__*/React.createElement("span", {
    className: styles.categoryCount
  }, selectedCount, "/", totalCount), /*#__PURE__*/React.createElement(CaretDown, {
    className: styles.caretIcon
  }))), /*#__PURE__*/React.createElement(Collapsible.Panel, {
    className: styles.propertyList
  }, filteredColumns.length === 0 ? /*#__PURE__*/React.createElement("div", {
    className: styles.emptyState
  }, labels.columnConfigNoMatchingColumns) : filteredColumns.map(column => /*#__PURE__*/React.createElement(PropertyItem, {
    key: column.id,
    column: column,
    isSelected: visibleColumns.some(v => v.id === column.id),
    onToggle: onToggleColumn
  })))));
}
function PropertyItem({
  column,
  isSelected,
  onToggle,
  showInfoIcon = false
}) {
  const handleClick = useCallback(() => {
    onToggle(column);
  }, [onToggle, column]);
  return /*#__PURE__*/React.createElement("div", {
    className: styles.propertyItem
  }, /*#__PURE__*/React.createElement("label", {
    className: styles.propertyLabel
  }, /*#__PURE__*/React.createElement(Checkbox, {
    checked: isSelected,
    onCheckedChange: handleClick,
    className: styles.checkbox
  }), /*#__PURE__*/React.createElement("span", {
    className: styles.propertyName
  }, column.label)), showInfoIcon && /*#__PURE__*/React.createElement(SmallInfoSign, {
    className: styles.infoIcon
  }));
}
//# sourceMappingURL=ColumnConfigDialog.js.map