/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 { PopoverMenu } from "../../contextMenu/PopoverMenu";
import { PopoverPosition } from "@patternfly/react-core/dist/js/components/Popover";
import _ from "lodash";
import * as React from "react";
import { useCallback, useMemo } from "react";
import { useBoxedExpressionEditor } from "../../BoxedExpressionEditorContext";
import { MenuItemWithHelp } from "../../contextMenu/MenuWithHelp";
import { Menu } from "@patternfly/react-core/dist/js/components/Menu/Menu";
import { MenuGroup } from "@patternfly/react-core/dist/js/components/Menu/MenuGroup";
import { MenuList } from "@patternfly/react-core/dist/js/components/Menu/MenuList";
import { DMN_LATEST__tFunctionKind } from "@kie-tools/dmn-marshaller";
import { BoxedFunctionKind } from "../../api";
import { useBoxedExpressionEditorI18n } from "../../i18n";

export interface FunctionKindSelectorProps {
  /** Pre-selected function kind */
  selectedFunctionKind: DMN_LATEST__tFunctionKind;
  /** Callback invoked when function kind selection changes */
  onFunctionKindSelect: (functionKind: DMN_LATEST__tFunctionKind) => void;
  /** If should only display function kind */
  isReadOnly?: boolean;
}

export const FunctionKindSelector: React.FunctionComponent<FunctionKindSelectorProps> = ({
  selectedFunctionKind,
  onFunctionKindSelect,
  isReadOnly,
}) => {
  const { i18n } = useBoxedExpressionEditorI18n();
  const { editorRef } = useBoxedExpressionEditor();

  const functionKindSelectionCallback = useCallback(
    (hide: () => void) => (event?: React.MouseEvent, itemId?: string | number) => {
      onFunctionKindSelect(itemId as DMN_LATEST__tFunctionKind);
      setVisibleHelp("");
      hide();
    },
    [onFunctionKindSelect]
  );

  const functionKindHelp = useCallback(
    (functionKind: DMN_LATEST__tFunctionKind) => {
      switch (functionKind) {
        case "FEEL":
          return i18n.functionKindHelp.feel;
        case "Java":
          return i18n.functionKindHelp.java;
        case "PMML":
          return i18n.functionKindHelp.pmml;
        default:
          return i18n.functionKindHelp.notSupported;
      }
    },
    [
      i18n.functionKindHelp.feel,
      i18n.functionKindHelp.java,
      i18n.functionKindHelp.notSupported,
      i18n.functionKindHelp.pmml,
    ]
  );

  const [visibleHelp, setVisibleHelp] = React.useState<string>("");
  const toggleVisibleHelp = useCallback((help: string) => {
    setVisibleHelp((previousHelp) => (previousHelp !== help ? help : ""));
  }, []);

  const displaySelectedFunctionKind = useMemo(
    () => (
      <div className="selected-function-kind" data-testid="kie-tools--bee--selected-function-kind">
        {_.first(selectedFunctionKind)}
      </div>
    ),
    [selectedFunctionKind]
  );

  if (isReadOnly) {
    return displaySelectedFunctionKind;
  }

  return (
    <PopoverMenu
      onHidden={() => setVisibleHelp("")}
      appendTo={editorRef?.current ?? undefined}
      className="function-kind-popover"
      position={PopoverPosition.leftEnd}
      hasAutoWidth={true}
      body={(hide: () => void) => (
        <Menu onSelect={functionKindSelectionCallback(hide)} selected={selectedFunctionKind}>
          <MenuGroup className="menu-with-help">
            <MenuList>
              {_.map(Object.entries(BoxedFunctionKind), ([functionKindKey, functionKind]) => (
                <MenuItemWithHelp
                  key={functionKindKey}
                  menuItemKey={functionKind}
                  menuItemHelp={functionKindHelp(functionKind)}
                  setVisibleHelp={toggleVisibleHelp}
                  visibleHelp={visibleHelp}
                />
              ))}
            </MenuList>
          </MenuGroup>
        </Menu>
      )}
    >
      {displaySelectedFunctionKind}
    </PopoverMenu>
  );
};
