import { defineComponent, ref, onBeforeUnmount, cloneVNode, createVNode, TransitionGroup, createApp, onMounted, mergeProps } from 'vue';
import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
import { InfoCircleFilled, CheckCircleFilled, CloseCircleFilled, ExclamationCircleFilled } from '../icon';
import { useTheme } from '../_theme/useTheme';
import { getFirstValidNode } from './vnode';

const _excluded = ["getContainer"];
let seed = 0;
const now = Date.now();
function genUid() {
  return `notice_manager_${now}_${seed++}`;
}
const Notification = defineComponent({
  props: {
    maxCount: Number,
    transitionName: String
  },
  setup(props) {
    const notices = ref([]);
    const timers = new Set();
    function remove(key) {
      const index = notices.value.findIndex(item => item.key === key);
      const notice = notices.value[index];
      if (notice) {
        var _notice$afterRemove;
        notices.value.splice(index, 1);
        (_notice$afterRemove = notice.afterRemove) === null || _notice$afterRemove === void 0 || _notice$afterRemove.call(notice);
      }
    }
    function append(notice) {
      if (!notice.key) {
        notice.key = genUid();
      }
      if (props.maxCount && notices.value.length >= props.maxCount) {
        notices.value.shift();
      }
      notices.value.push(notice);
      if (notice.duration > 0) {
        const timer = setTimeout(() => {
          remove(notice.key);
          clearTimeout(timer);
        }, notice.duration * 1000);
        timers.add(timer);
      }
      return notice;
    }
    onBeforeUnmount(() => {
      // 清理所有未触发的定时器
      timers.forEach(timer => {
        clearTimeout(timer);
      });
      timers.clear();
    });
    return {
      notices,
      append,
      remove
    };
  },
  render() {
    const {
      notices,
      transitionName
    } = this;
    const children = notices.map(notice => {
      let vNode = typeof notice.children === 'function' ? notice.children() : notice.children;
      vNode = getFirstValidNode([vNode]);
      if (vNode) {
        return cloneVNode(vNode, {
          key: notice.key
        });
      }
    });
    return createVNode(TransitionGroup, {
      "name": transitionName,
      "tag": "div"
    }, {
      default: () => [children]
    });
  }
});
function createManager(opt) {
  return new Promise(resolve => {
    const {
        getContainer
      } = opt,
      props = _objectWithoutProperties(opt, _excluded);
    const div = document.createElement('div');
    if (getContainer) {
      const root = getContainer();
      root === null || root === void 0 || root.appendChild(div);
    } else {
      document.body.appendChild(div);
    }
    const app = createApp({
      setup() {
        useTheme();
        const notificationRef = ref();
        const instance = {
          append: noticeProps => notificationRef.value.append(noticeProps),
          remove: key => notificationRef.value.remove(key),
          destroy() {
            app.unmount();
            if (div.parentNode) {
              div.parentNode.removeChild(div);
            }
          },
          exited() {
            // 容器是否存在
            if (!getContainer) {
              return true;
            }
            try {
              if (!getContainer()) {
                instance.destroy();
                return false;
              }
            } catch (error) {
              instance.destroy();
              return false;
            }
            return true;
          }
        };
        onMounted(() => resolve(instance));
        return () => createVNode(Notification, mergeProps({
          "ref": notificationRef
        }, props), null);
      }
    });
    app.mount(div);
  });
}
const iconComponentMap = {
  info: InfoCircleFilled,
  success: CheckCircleFilled,
  error: CloseCircleFilled,
  warning: ExclamationCircleFilled
};

export { createManager, iconComponentMap };
