/*
 * @Author: 赵伟
 * @Date: 2024-06-26 16:37:39
 * @Description: 全局网络请求 Loading
 */

import KFSpin from '@/components/KFSpin';
import { ConfigProvider, SpinProps } from 'antd';
import { globalConfig } from 'antd/es/config-provider';
import zhCN from 'antd/locale/zh_CN';
import { createRoot } from 'react-dom/client';

export class Loading {
  static total: number = 0;
  static isShowing: boolean = false;
  static startTime: Date = new Date();
  static removeTimeout: ReturnType<typeof setTimeout> | undefined;
  static show(props?: SpinProps) {
    this.total += 1;
    if (this.total > 1) {
      return;
    }

    // 是否有延时未关闭的 loading
    if (this.isShowing) {
      this.clearRemoveTimeout();
      return;
    }
    const container = document.createElement('div');
    container.id = 'loading';
    const rootContainer = document.body; // document.getElementsByTagName('main')[0];
    rootContainer?.appendChild(container);
    const root = createRoot(container);
    const global = globalConfig();
    let renderTimeoutId: ReturnType<typeof setTimeout>;

    const render = (spinProps: SpinProps) => {
      clearTimeout(renderTimeoutId);

      renderTimeoutId = setTimeout(() => {
        const rootPrefixCls = global.getPrefixCls();
        const iconPrefixCls = global.getIconPrefixCls();
        const theme = global.getTheme();
        const dom = <KFSpin {...spinProps} />;
        root.render(
          <ConfigProvider
            prefixCls={rootPrefixCls}
            iconPrefixCls={iconPrefixCls}
            theme={theme}
            locale={zhCN}
          >
            {global.holderRender ? global.holderRender(dom) : dom}
          </ConfigProvider>,
        );
      });
    };

    render({ size: 'large', ...props, spinning: true });
    this.startTime = new Date();
    this.isShowing = true;
  }

  static clearRemoveTimeout() {
    if (this.removeTimeout) {
      clearTimeout(this.removeTimeout);
      this.removeTimeout = undefined;
    }
  }

  static removeLoading() {
    this.clearRemoveTimeout();
    const container = document.getElementById('loading');
    if (container) {
      container.parentNode?.removeChild(container);
    }
    this.isShowing = false;
  }

  static hide(force: boolean = false) {
    this.total -= 1;
    if (this.total > 0 && !force) {
      return;
    }

    this.total = 0;
    const duration = new Date().getTime() - this.startTime.getTime();
    this.removeTimeout = setTimeout(() => {
      this.removeLoading();
    }, Math.max(300 - duration, 0));
  }
}

export default Loading;
