// @ts-ignore
import { createElement, FunctionComponent, useState, useEffect, render, shared } from 'rax';
// @ts-ignore
import { StyledComponentProps } from '@rax-ui/styles';
import ActionSheet, { ActionSheetButtonProps, ActionSheetItemProps } from './action-sheet';

export interface ActionSheetCurrent {
  hide?: (e: any) => void;
  destroyed?: boolean;
}

export interface ActionSheetWrapperProps extends StyledComponentProps<any> {
  title?: string;
  fullWidth?: boolean;
  content?: (h: any) => any;
  cancelButton?: string | ActionSheetButtonProps;
  buttons?: Array<string | ActionSheetButtonProps>;
  items?: ActionSheetItemProps[][];
  onUnmount?: () => void;
  callback?: (e: any) => void;
  maskCancelable?: boolean;
  current?: ActionSheetCurrent;
}

const ActionSheetWrapper: FunctionComponent<ActionSheetWrapperProps> = (props) => {
  const {
    title,
    fullWidth,
    content,
    cancelButton = 'cancel',
    buttons = [],
    items = [],
    onUnmount = () => {},
    callback = () => {},
    maskCancelable = true,
    current,
  } = props;
  const [visible, setVisible] = useState(true);

  const btns = (buttons || [])
    .filter((b) => !!b)
    .map(function(b, i) {
      if (typeof b === 'string') {
        b = { text: b };
      }
      b.index = i;
      return b;
    });

  const cancelBtn: ActionSheetButtonProps =
    typeof cancelButton === 'string'
      ? {
          text: cancelButton,
          style: {},
          textStyle: {},
        }
      : cancelButton;

  const handleCallback = (e) => {
    setVisible(false);
    if (callback) {
      callback(e);
    }
  };

  function handleCancel() {
    handleCallback({
      ...cancelBtn,
      cancel: true,
      index: btns.length,
    });
  }

  function handleMask() {
    if (maskCancelable) {
      handleCallback({
        ...cancelBtn,
        mask: true,
        cancel: true,
        index: btns.length,
      });
    }
  }

  const handler = (e?: any) => {
    if (e) {
      handleCallback(e);
    } else {
      handleCancel();
    }
  };

  useEffect(() => {
    if (current && !current.destroyed) {
      current.hide = handler;
    }
  });

  return (
    <ActionSheet
      visible={visible}
      title={title}
      fullWidth={fullWidth}
      buttons={btns}
      portal={false}
      cancelButton={cancelBtn}
      items={items}
      renderContent={content ? () => content(handler) : null}
      onUnmount={onUnmount}
      onHide={(reason) => {
        switch (reason) {
          case 'cancelClick':
            return handleCancel();
          case 'backdropClick':
            return handleMask();
        }
        setVisible(false);
      }}
      onClick={(index, cols) => {
        if (items.length > 0) {
          handleCallback(items[index][cols]);
        } else {
          handleCallback(btns[index]);
        }
      }}
    />
  );
};

export default {
  current: {},

  show(props, callback) {
    const current: ActionSheetCurrent = (this.current = {});
    const root = document.createElement('div');
    const unmount = () => document.body.removeChild(root);
    document.body.appendChild(root);
    render(<ActionSheetWrapper callback={callback} {...props} current={current} onUnmount={unmount} />, root, {
      driver: shared.Host.driver,
    });
    return (e) => {
      if (current && current.hide) {
        current.hide(e);
        current.destroyed = true;
        delete current.hide;
      }
    };
  },

  hide(e) {
    if (this.current && this.current.hide) {
      this.current.hide(e);
      this.current = {};
    }
  },
};
