import Bar from './Bar';
import ConfigProvider from '../config-provider';
import Container from './Container';
import React, { Component } from 'react';
import cls from 'classnames';
import { Loading as NextLoading } from '@alifd/next';
import { LoadingProps as NextLoadingProps } from '@alifd/next/types/loading';
import { useNProgress } from '@tanem/react-nprogress';

interface LoadingTypeProps {
  type?: 'circle' | 'linear' | 'global_linear'
}
interface LoadingProps extends Omit<NextLoadingProps, 'size'>, LoadingTypeProps {
  size?: 'xl' | 'large' | 'medium' | 'small',
}

// 圆形加载不同尺寸大小的加载图案
// 加大号
const indicator1 = prefix => (
  <div className={`${prefix}loading-circle`}>
    <svg viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
      <g id="13、Loading-加载-*" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Loading-加载" transform="translate(-624.000000, -659.000000)">
          <g id="圆形加载-/-40px" transform="translate(624.000000, 659.000000)">
            <rect id="矩形" x="0" y="0" width="40" height="40"></rect>
            <g id="编组" transform="translate(1.000000, 1.000000)">
              <path d="M19,0 C8.50658975,0 0,8.50658975 0,19 C0,29.4934102 8.50658975,38 19,38 C29.4934102,38 38,29.4934102 38,19 C38,8.50658975 29.4934102,0 19,0 Z M19,4 C27.2842712,4 34,10.7157288 34,19 C34,27.2842712 27.2842712,34 19,34 C10.7157288,34 4,27.2842712 4,19 C4,10.7157288 10.7157288,4 19,4 Z" id="椭圆形" opacity="0" fill-rule="nonzero"></path>
              <path d="M19,0 C29.4934102,0 38,8.50658975 38,19 C38,29.4934102 29.4934102,38 19,38 C14.859153,38 10.9142651,36.6696246 7.66163236,34.2473379 C6.7757348,33.5875961 6.59239937,32.3346078 7.25214121,31.4487102 C7.91188305,30.5628126 9.16487135,30.3794772 10.0507689,31.0392191 C12.6187461,32.9516321 15.7274132,34 19,34 C27.2842712,34 34,27.2842712 34,19 C34,10.7157288 27.2842712,4 19,4 C17.8954305,4 17,3.1045695 17,2 C17,0.8954305 17.8954305,0 19,0 Z" id="路径" fill="url(#linear-gradient2)"></path>
            </g>
          </g>
        </g>
      </g>
    </svg>
  </div>
);

// 大号
const indicator2 = prefix => (
  <div className={`${prefix}loading-circle`}>
    <svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
      <linearGradient
        id="linear-gradient2"
        x1="0" y1="0" x2="0" y2="1"
      >
        <stop className="loading-svg-style1" offset="10%"/>
        <stop className="loading-svg-style2" offset="100%"/>
      </linearGradient>;
      <g id="13、Loading-加载-*" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Loading-加载" transform="translate(-118.000000, -664.000000)">
          <g id="圆形加载-/-18px" transform="translate(118.000000, 664.000000)">
            <rect id="矩形" x="0" y="0" width="18" height="18"></rect>
            <g id="编组备份" transform="translate(1.125000, 1.125000)">
              <path d="M7.875,0 C3.5257576,0 0,3.5257576 0,7.875 C0,12.2242424 3.5257576,15.75 7.875,15.75 C12.2242424,15.75 15.75,12.2242424 15.75,7.875 C15.75,3.5257576 12.2242424,0 7.875,0 Z M7.875,2.25 C10.9816017,2.25 13.5,4.76839828 13.5,7.875 C13.5,10.9816017 10.9816017,13.5 7.875,13.5 C4.76839828,13.5 2.25,10.9816017 2.25,7.875 C2.25,4.76839828 4.76839828,2.25 7.875,2.25 Z" id="椭圆形" fill-rule="nonzero" opacity="0"></path>
              <path d="M7.875,0 C12.2242424,0 15.75,3.5257576 15.75,7.875 C15.75,12.2242424 12.2242424,15.75 7.875,15.75 C6.15901718,15.75 4.52349194,15.1984349 3.1753703,14.1944675 C2.67705293,13.8233627 2.57392675,13.1185568 2.94503153,12.6202394 C3.31613632,12.1219221 4.02094224,12.0187959 4.51925961,12.3899007 C5.48226252,13.1070641 6.64741351,13.5 7.875,13.5 C10.9816017,13.5 13.5,10.9816017 13.5,7.875 C13.5,4.76839828 10.9816017,2.25 7.875,2.25 C7.25367966,2.25 6.75,1.74632034 6.75,1.125 C6.75,0.503679656 7.25367966,0 7.875,0 Z" id="路径" fill="url(#linear-gradient2)"></path>
            </g>
          </g>
        </g>
      </g>
    </svg>
  </div>
);

// 中号
const indicator3 = prefix => (
  <div className={`${prefix}loading-circle`}>
    <svg viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
      <g id="13、Loading-加载-*" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Loading-加载" transform="translate(-623.000000, -496.000000)">
          <g id="圆形加载-/-16px" transform="translate(623.000000, 496.000000)">
            <rect id="矩形" x="0" y="0" width="16" height="16"></rect>
            <g id="编组备份" transform="translate(1.000000, 1.000000)">
              <path d="M7,0 C3.13400675,0 0,3.13400675 0,7 C0,10.8659932 3.13400675,14 7,14 C10.8659932,14 14,10.8659932 14,7 C14,3.13400675 10.8659932,0 7,0 Z M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z" id="椭圆形" fill="#979797" fill-rule="nonzero" opacity="0"></path>
              <path d="M7,0 C10.8659932,0 14,3.13400675 14,7 C14,10.8659932 10.8659932,14 7,14 C5.47468194,14 4.02088172,13.5097199 2.82255138,12.6173045 C2.3796026,12.2874335 2.28793488,11.6609394 2.61780581,11.2179906 C2.94767673,10.7750418 3.57417088,10.6833741 4.01711965,11.013245 C4.87312224,11.6507236 5.90881201,12 7,12 C9.76142375,12 12,9.76142375 12,7 C12,4.23857625 9.76142375,2 7,2 C6.44771525,2 6,1.55228475 6,1 C6,0.44771525 6.44771525,0 7,0 Z" id="路径" fill="url(#linear-gradient2)"></path>
            </g>
          </g>
        </g>
      </g>
    </svg>
  </div>
);

// 小号
const indicator4 = prefix => (
  <div className={`${prefix}loading-circle`}>
    <svg viewBox="0 0 12 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink">
      <g id="13、Loading-加载-*" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Loading-加载" transform="translate(-118.000000, -496.000000)">
          <g id="圆形加载-/-12px" transform="translate(118.000000, 496.000000)">
            <rect id="矩形" x="0" y="0" width="12" height="12"></rect>
            <g id="编组备份" transform="translate(0.750000, 0.750000)">
              <path d="M5.25,0 C2.35050506,0 0,2.35050506 0,5.25 C0,8.14949494 2.35050506,10.5 5.25,10.5 C8.14949494,10.5 10.5,8.14949494 10.5,5.25 C10.5,2.35050506 8.14949494,0 5.25,0 Z M5.25,1.5 C7.32106781,1.5 9,3.17893219 9,5.25 C9,7.32106781 7.32106781,9 5.25,9 C3.17893219,9 1.5,7.32106781 1.5,5.25 C1.5,3.17893219 3.17893219,1.5 5.25,1.5 Z" id="椭圆形" fill="#979797" fill-rule="nonzero" opacity="0"></path>
              <path d="M5.25,0 C8.14949494,0 10.5,2.35050506 10.5,5.25 C10.5,8.14949494 8.14949494,10.5 5.25,10.5 C4.10601145,10.5 3.01566129,10.1322899 2.11691354,9.46297835 C1.78470195,9.21557516 1.71595116,8.74570455 1.96335435,8.41349296 C2.21075754,8.08128138 2.68062816,8.01253059 3.01283974,8.25993378 C3.65484168,8.73804272 4.43160901,9 5.25,9 C7.32106781,9 9,7.32106781 9,5.25 C9,3.17893219 7.32106781,1.5 5.25,1.5 C4.83578644,1.5 4.5,1.16421356 4.5,0.75 C4.5,0.335786438 4.83578644,0 5.25,0 Z" id="路径" fill="url(#linear-gradient2)"></path>
            </g>
          </g>
        </g>
      </g>
    </svg>
  </div>
);

// 全局线性加载组件
const Progress = ({ isAnimating }) => {
  const { animationDuration, isFinished, progress } = useNProgress({
    isAnimating,
  });

  return (
    <Container animationDuration={animationDuration} isFinished={isFinished}>
      <Bar animationDuration={animationDuration} progress={progress} />
    </Container>
  );
};

class Loading extends Component<LoadingProps> {
  readonly state = {
    isAnimating: false,
    key: 0,
  };

  render() {
    const { prefix = 'next-', size = 'large', type = 'circle', className, fullScreen, visible = true, ...otherProps } = this.props;
    let loading_indicator;

    if (size === 'xl' || fullScreen) {
      loading_indicator = indicator1(prefix);
    } else if (size === 'large') {
      loading_indicator = indicator2(prefix);
    } else if (size === 'medium') {
      loading_indicator = indicator3(prefix);
    } else if (size === 'small') {
      loading_indicator = indicator4(prefix);
    }

    if (type === 'global_linear') {
      return (
        <>
          <Progress isAnimating={visible} key={this.state.key} />
          <NextLoading
            size = 'large'
            {...otherProps}
            indicator = {loading_indicator}
            visible = {visible}
            className = {cls(
              className, {
                [`${prefix}loading-default`]: true,
                [`${prefix}loading-large`]: true,
                [`${prefix}loading-global-circle`]: true,
              },
            )}
          />
        </>
      );
    }

    return (
      <NextLoading
        fullScreen = {fullScreen}
        size = {size as 'medium' | 'large'}
        {...otherProps}
        indicator = {(type === 'circle') ? loading_indicator : undefined}
        visible = {visible}
        className = {cls(
          className, {
            [`${prefix}loading-xl`]: size === 'xl' || fullScreen,
            [`${prefix}loading-large`]: size === 'large' && !fullScreen,
            [`${prefix}loading-medium`]: size === 'medium',
            [`${prefix}loading-small`]: size === 'small',
            [`${prefix}loading-linear`]: type === 'linear',
            [`${prefix}loading-default`]: type === 'circle',
          },
        )}
      />
    );
  }
}

export default ConfigProvider.config(Loading);
