// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only

import * as React from 'react';
import { Button, ButtonVariant } from './Button';
import { LocalizerType } from '../types/Util';
import { Modal } from './Modal';
import { Theme } from '../util/theme';

export type ActionSpec = {
  text: string;
  action: () => unknown;
  style?: 'affirmative' | 'negative';
};

export type OwnProps = {
  readonly moduleClassName?: string;
  readonly actions?: Array<ActionSpec>;
  readonly cancelText?: string;
  readonly children?: React.ReactNode;
  readonly i18n: LocalizerType;
  readonly onCancel?: () => unknown;
  readonly onClose: () => unknown;
  readonly title?: string | React.ReactNode;
  readonly theme?: Theme;
  readonly hasXButton?: boolean;
};

export type Props = OwnProps;

function focusRef(el: HTMLElement | null) {
  if (el) {
    el.focus();
  }
}

function getButtonVariant(
  buttonStyle?: 'affirmative' | 'negative'
): ButtonVariant {
  if (buttonStyle === 'affirmative') {
    return ButtonVariant.Primary;
  }

  if (buttonStyle === 'negative') {
    return ButtonVariant.Destructive;
  }

  return ButtonVariant.Secondary;
}

export const ConfirmationDialog = React.memo(
  ({
    moduleClassName,
    actions = [],
    cancelText,
    children,
    i18n,
    onCancel,
    onClose,
    theme,
    title,
    hasXButton,
  }: Props) => {
    const cancelAndClose = React.useCallback(() => {
      if (onCancel) {
        onCancel();
      }
      onClose();
    }, [onCancel, onClose]);

    const handleCancel = React.useCallback(
      (e: React.MouseEvent) => {
        if (e.target === e.currentTarget) {
          cancelAndClose();
        }
      },
      [cancelAndClose]
    );

    const hasActions = Boolean(actions.length);

    return (
      <Modal
        moduleClassName={moduleClassName}
        i18n={i18n}
        onClose={cancelAndClose}
        title={title}
        theme={theme}
        hasXButton={hasXButton}
      >
        {children}
        <Modal.ButtonFooter>
          <Button
            onClick={handleCancel}
            ref={focusRef}
            variant={
              hasActions ? ButtonVariant.Secondary : ButtonVariant.Primary
            }
          >
            {cancelText || i18n('confirmation-dialog--Cancel')}
          </Button>
          {actions.map((action, i) => (
            <Button
              key={action.text}
              onClick={() => {
                action.action();
                onClose();
              }}
              data-action={i}
              variant={getButtonVariant(action.style)}
            >
              {action.text}
            </Button>
          ))}
        </Modal.ButtonFooter>
      </Modal>
    );
  }
);
