/* stylelint-disable */
import React, { FC, useCallback, useEffect, useRef, useState } from 'react';
import classNames from 'classnames';

const INITIAL_STEP = 10;
const STUCK_THRESHOLD = 99;

export interface LoadingProps {
  /** 是否完成 */
  done?: boolean;
}

const Loading: FC<LoadingProps> = ({ done }) => {
  const [progress, setProgress] = useState(0);
  const [step, setStep] = useState(INITIAL_STEP);
  const animation = useRef<null | number>(null);
  const [isEnd, setIsEnd] = useState(false);

  const increment = useCallback(() => {
    if (progress >= STUCK_THRESHOLD) {
      return;
    }

    setProgress(Math.min(progress + step, 100));
    setStep(INITIAL_STEP ** -(progress / 25));
  }, [progress, step]);

  useEffect(() => {
    increment();
  }, []);

  useEffect(() => {
    if (done) {
      setIsEnd(done);
    }
  }, [done]);

  useEffect(() => {
    if (progress >= STUCK_THRESHOLD) {
      return;
    }

    if (isEnd) {
      return setProgress(100);
    }

    animation.current = requestAnimationFrame(() => increment());

    return () => {
      if (animation.current != null) {
        cancelAnimationFrame(animation.current);
      }
    };
  });

  const customStyles = {
    transform: `scaleX(${+progress.toFixed() / 100})`,
  };

  return (
    <div className="loading-wrapper">
      <div className={classNames('loading-bar', { done: progress === 100 })}>
        <div className="level" style={customStyles} />
      </div>
    </div>
  );
};

export default Loading;
