import React from "react";
import { TransitionProps } from "react-transition-group/Transition";
import { Transition } from "../_util/transition";
import { BaseTransition } from "../transition/BaseTransition";
import { hashObject } from "../_util/hash-object";
import { insertCSS } from "../_util/insert-css";

const rootId = "tea-message-root";

export function getRoot(classPrefix: string) {
  let root: HTMLElement = window[rootId] || document.getElementById(rootId);
  if (!root) {
    root = document.createElement("div");
    root.id = rootId;
    document.body.appendChild(root);
    window[rootId] = root;
  }
  return root;
}

const maxCountLimit = 1;
const listKey = "tea-message-list-identification";

export function limit(notice: { hide: () => void }) {
  if (!window[listKey]) {
    window[listKey] = [];
  }
  if (window[listKey].length >= maxCountLimit) {
    try {
      window[listKey][0].hide();
      window[listKey].shift();
    } catch (_) {
      // hide failed
    }
  }
  window[listKey].push(notice);
}

export interface MessageTransitionProps extends Partial<TransitionProps> {
  /**
   * 动画元素目标高度
   */
  height?: number;
}

export function MessageTransition(props: MessageTransitionProps) {
  return <BaseTransition {...transition()} {...props} />;
}

const generateCSS = (transition: Transition) => `
.${transition.classNames}-enter {
  opacity: 0 !important;
  transform: translate3d(-50%, 0, 0);
}
.${transition.classNames}-enter-active {
  opacity: 1 !important;
  transform: translate3d(-50%, 0, 0);
  transition: opacity ${transition.timeout.enter}ms ease,
    transform ${transition.timeout.enter}ms ease;
}
.${transition.classNames}-exit {
  opacity: 1 !important;
}
.${transition.classNames}-exit-active {
  opacity: 0 !important;
  transition: opacity ${transition.timeout.enter}ms ease;
}
`;

const setupTransitions: { [hash: number]: Transition } = {};

export function transition(enterTimeout = 300, leaveTimeout = 300) {
  const name = `tea-transition-notification`;
  const hash = hashObject({ name, enterTimeout, leaveTimeout });

  if (!setupTransitions[hash]) {
    setupTransitions[hash] = {
      classNames: name + hash,
      timeout: {
        enter: enterTimeout,
        exit: leaveTimeout,
      },
      unmountOnExit: true,
      mountOnEnter: true,
    };
    const transition = setupTransitions[hash];
    const css = generateCSS(transition);
    insertCSS(name + hash, css);
  }

  return setupTransitions[hash];
}
