import { Button, Dialog, ModalContext } from '@8base/boost';
import React from 'react';

import { DialogForm } from 'shared/components';

// -- TYPES

interface IDialogProps {
  body: React.ReactNode;
  proceedText: string;
  title: string;
  onSubmit: () => void;
  awaitSubmit: boolean;
}

interface IDialogState {
  submitting: boolean;
}

// -- CONSTANTS

export const ALERT_DIALOG_ID = 'ALERT_DIALOG_ID';

// -- MAIN

class DialogContent extends React.Component<IDialogProps, IDialogState> {
  static contextType = ModalContext;
  static defaultProps = {
    proceedText: 'Proceed',
    awaitSubmit: true,
  };

  constructor(props: IDialogProps) {
    super(props);

    this.state = {
      submitting: false,
    };
  }

  render() {
    const { body, proceedText, title } = this.props;
    const { submitting } = this.state;

    return (
      <DialogForm onSubmit={this.onSubmit}>
        <Dialog.Header title={title} onClose={this.closeDialog} />

        <Dialog.Body scrollable={true}>{body}</Dialog.Body>

        <Dialog.Footer>
          <Button
            color="neutral"
            variant="outlined"
            onClick={this.closeDialog}
            disabled={submitting}
          >
            Cancel
          </Button>
          <Button color="danger" type="submit" loading={submitting}>
            {proceedText}
          </Button>
        </Dialog.Footer>
      </DialogForm>
    );
  }

  private onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    const { awaitSubmit, onSubmit } = this.props;

    if (this.state.submitting) {
      return;
    }

    if (awaitSubmit) {
      this.setState({
        submitting: true,
      });
    }

    await onSubmit();

    this.closeDialog();
  };

  private closeDialog = () => {
    this.context.closeModal(ALERT_DIALOG_ID);
  };
}

function AlertDialog() {
  return (
    <Dialog id={ALERT_DIALOG_ID} size="sm">
      {({ args }: any) => <DialogContent {...args} />}
    </Dialog>
  );
}

AlertDialog.id = ALERT_DIALOG_ID;

export default AlertDialog;
