import { render as renderDom } from 'preact';


type Content = string | {
  content: string;
  lineClampNum?: number | string;
  top?: string;
};

type IHandler =  (content: Content, duration?: number, clickWrap?: (toast: ToastOptions) => void) => void;

type ToastOptions = {
  className: string;
  container: any;
  root: any;
  timer: any;

  init: () => void;

  show: IHandler;

  close: () => void;
};


export function getToastCommand(ToastComponent, {
  defaultDuration: DEFAULT_DURATION,
}) {
  const toast: ToastOptions = {
    className: '',
    container: null,
    root: null,
    timer: null,

    init() {
      if (!this.container) {
        const clsName = 'press-toast-container';
        this.container = document.createElement('div');
        this.container.className = clsName;
        document.body.appendChild(this.container);
        this.className = clsName;
        this.root = this.container;
      }
    },

    show(content, duration = DEFAULT_DURATION, clickWrap = () => {}) {
      clearTimeout(this.timer);
      this.close();

      this.init();

      const innerContent = typeof content === 'string' ? content : content?.content;
      const lineClampNum = typeof content === 'string' ? undefined : content?.lineClampNum;
      const top = typeof content === 'string' ? undefined : content?.top;

      const toastElement = (
        <ToastComponent
          content={innerContent}
          lineClampNum={lineClampNum}
          top={top}
          clickWrap={() => clickWrap?.(toast)}
        />
      );

      renderDom(toastElement, this.container);

      if (duration > 0) {
        this.timer = setTimeout(() => this.close(), duration);
      }
    },

    close() {
      try {
        const found = document.body.querySelector(`.${this.className}`);
        if (this.container && found) {
          document.body.removeChild(this.container);
        }
      } catch (err) {}
      this.container = null;
      this.root = null;
    },
  };

  const showToast = toast.show.bind(toast);

  return {
    toast,
    showToast,
  };
}
