/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * The OpenSearch Contributors require contributions made to
 * this file be licensed under the Apache-2.0 license or a
 * compatible open source license.
 *
 * Modifications Copyright OpenSearch Contributors. See
 * GitHub history for details.
 */

/*
 * Licensed to Elasticsearch B.V. under one or more contributor
 * license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright
 * ownership. Elasticsearch B.V. 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 React, {
  FunctionComponent,
  HTMLAttributes,
  ReactElement,
  ReactNode,
} from 'react';
import classNames from 'classnames';

import { CommonProps } from '../common';
import { OuiTitle, OuiTitleSize } from '../title';
import { OuiFlexGroup, OuiFlexItem } from '../flex';
import { OuiSpacer } from '../spacer';
import { OuiIcon, IconColor, IconType } from '../icon';
import { OuiText, OuiTextColor } from '../text';

export type OuiEmptyPromptProps = CommonProps &
  Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {
    /*
     * Accepts any `OuiIcon.type` or pass a custom node
     */
    iconType?: IconType;
    /**
     * Color for `iconType` when passed as an `IconType`
     */
    iconColor?: IconColor;
    /**
     * Custom icon replacing the one generated by `iconType`
     */
    icon?: ReactNode;
    /**
     * Requires passing a single element that gets wrapped in an OuiTitle.
     * Recommendation is a heading, preferrably an `<h2>` if in its own section
     */
    title?: ReactElement<any>;
    /**
     * Choose from one of the `OuiTitle.size` options
     */
    titleSize?: OuiTitleSize;
    /**
     * Gets wrapped in a subdued OuiText block.
     * Recommendation is to pass typical text elements like `<p>`
     */
    body?: ReactNode;
    /**
     * Pass a single or an array of actions (buttons) that get stacked at the bottom.
     * Recommendation is to pass the primary action first and secondary actions as empty buttons
     */
    actions?: ReactNode;
  };

export const OuiEmptyPrompt: FunctionComponent<OuiEmptyPromptProps> = ({
  icon,
  iconType,
  iconColor = 'subdued',
  title,
  titleSize = 'm',
  body,
  actions,
  className,
  ...rest
}) => {
  const classes = classNames('ouiEmptyPrompt', className);

  let iconNode;
  if (icon) {
    iconNode = (
      <>
        {icon}
        <OuiSpacer size="m" />
      </>
    );
  } else if (iconType) {
    iconNode = (
      <>
        <OuiIcon type={iconType} size="xxl" color={iconColor} />
        <OuiSpacer size="m" />
      </>
    );
  }

  let titleNode;
  let bodyNode;
  if (body || title) {
    if (title) {
      titleNode = <OuiTitle size={titleSize}>{title}</OuiTitle>;
    }

    if (body) {
      bodyNode = (
        <OuiTextColor color="subdued">
          {title && <OuiSpacer size="m" />}
          <OuiText>{body}</OuiText>
        </OuiTextColor>
      );
    }
  }

  let actionsNode;
  if (actions) {
    let actionsRow;

    if (Array.isArray(actions)) {
      actionsRow = (
        <OuiFlexGroup
          gutterSize="m"
          alignItems="center"
          justifyContent="center"
          direction="column">
          {actions.map((action, index) => (
            <OuiFlexItem key={index} grow={false}>
              {action}
            </OuiFlexItem>
          ))}
        </OuiFlexGroup>
      );
    } else {
      actionsRow = actions;
    }

    actionsNode = (
      <>
        <OuiSpacer size="l" />
        {actionsRow}
      </>
    );
  }

  return (
    <div className={classes} {...rest}>
      {iconNode}
      {titleNode}
      {bodyNode}
      {actionsNode}
    </div>
  );
};
