import { Switch as OldSwicth, SwitchProps, ConfigProvider } from 'antd';
import React, { useContext, useEffect, useState } from 'react';
import './index.less';
import classNames from 'classnames';
import { Icon } from '../Icon';
import { AOP } from '../utils/AOP';
import { SwitchChangeEventHandler } from 'antd/lib/switch';

interface ExtraProps {
  type?: 'round' | 'rect' | 'line';
}

const Switch = (props: SwitchProps & ExtraProps) => {
  // 为了与 antd 的生态保持兼容性，我们要求必须要使用 `.@{ant-prefix}` 变量来生成类名
  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);
  const prefixCls = getPrefixCls('btri-switch');
  const { type = 'round', defaultChecked = false, loading, ...res } = props;
  const [check, setCheck] = useState(defaultChecked);

  //@ts-ignore
  const newOnChange: SwitchChangeEventHandler = new AOP(props.onChange)
    .before((checkVal) => {
      if (props.checked === undefined && !props.loading) {
        setCheck(checkVal as boolean);
      }
    })
    .getFunction();

  useEffect(() => {
    setCheck(defaultChecked);
  }, [defaultChecked]);
  useEffect(() => {
    if (typeof props.checked === 'boolean') {
      setCheck(props.checked);
    }
  }, [props.checked]);

  return (
    <>
      <OldSwicth
        checked={check}
        {...res}
        className={classNames(
          `${prefixCls}-box`,
          `${prefixCls}-${type}`,
          `${prefixCls}-${props.size}`,
          loading && `${prefixCls}-loading`,
          props.className,
          (res.checkedChildren || res.unCheckedChildren) && 'hasText',
        )}
        onChange={newOnChange}
      ></OldSwicth>
      {type === 'line' && (
        <Icon
          onClick={(e) => {
            if (props.checked === undefined) {
              setCheck((preCheck) => !preCheck);
              props.onChange?.(!check, e as any);
            }
          }}
          className={classNames(
            `${prefixCls}-check-box`,
            check ? `${prefixCls}-check` : `${prefixCls}-unCheck`,
          )}
          spin={loading}
          iconName={loading ? 'Loading' : check ? 'CheckSmall' : 'CloseSmall'}
        ></Icon>
      )}
      {loading && type !== 'line' && (
        <Icon
          className={classNames(
            `${prefixCls}-check-box`,
            check ? `${prefixCls}-check` : `${prefixCls}-unCheck`,
            `${prefixCls}-${type}`,
            `${prefixCls}-${res.size}`,
            `${prefixCls}-loading`,
          )}
          spin
          iconName={'Loading'}
        ></Icon>
      )}
    </>
  );
};
export { Switch };
