import React, { memo, useEffect, useState, useRef } from "react";
import { ImgBoxWrap, Message } from "./styled";
import {
  initInter,
  initGesture,
  operObj,
  maxMinScale,
  doStyle,
  initOperObj,
  doNumInt,
  initVar,
} from "./tools";
import { Icon } from "@tingwu/meeting-icon";
// import { IImgNum } from './type';
import classnames from "classnames";
// import { ReactComponent as NoPptIcon } from '../../../assets/noPpt.svg';

interface IProps {
  midStatus?: any;
  imgUrl: string | undefined;
  children?: any;
  cls?: string;
  showRestore: boolean;
  initScale?: number;
}

const nMax = 60;
let nX = 0;
const initLeft = 12;

export const PictureZoom = memo((props: IProps) => {
  const { midStatus = false, imgUrl, children, cls, showRestore, initScale = 1 } = props;
  const imgRef = useRef<any>(null);
  const slideRef = useRef<any>(null);
  const boxRef = useRef<any>(null);
  const nInitLeft = useRef<number>(12);
  const timer = useRef<any>(null);
  const [showTips, setShowTips] = useState<boolean>(false);
  const [scaleLeft, setScaleLeft] = useState<number>(initLeft * initScale);
  const [percent, setPercent] = useState<number>(100 * initScale);
  const [showImg, setShowImg] = useState<boolean>(false);

  const gesture = useRef<any>(null);

  const doMouse = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
    gesture.current.unbindEventMoveListener();
    const nInitX = e.clientX;
    let nxCopy = 0;
    const mousemove = (event: any) => {
      event.preventDefault();
      event.stopPropagation();
      nX = event.clientX - nInitX + nInitLeft.current;
      if (nX >= nMax) {
        nX = nMax;
      }
      if (nX <= 0) {
        nX = -1;
      }
      let scale_mouse = (nX / 60) * 5;
      if (scale_mouse <= 0) {
        scale_mouse = 0.1;
      }
      operObj.scale = scale_mouse;
      doStyle("transform 300ms");
      setPercent(doNumInt(operObj.scale));
      nxCopy = nX;
      setScaleLeft(nX);
    };

    const mouseup = (event: any) => {
      event.preventDefault();
      event.stopPropagation();
      gesture.current.bindEventMoveListener();
      boxRef.current.removeEventListener("mousemove", mousemove);
      nInitLeft.current = nxCopy;
    };

    boxRef.current.addEventListener("mousemove", mousemove);
    boxRef.current.addEventListener("mouseup", mouseup);
  };

  const initBoxMouse = () => {
    boxRef.current.onmouseenter = () => {
      setShowTips(true);
      initInter(timer, setShowTips);
    };

    boxRef.current.onmousemove = () => {
      setShowTips(true);
      timer.current && clearInterval(timer.current);
      initInter(timer, setShowTips);
    };

    boxRef.current.onmouseleave = () => {
      setShowTips(false);
      clearInterval(timer.current);
    };
  };

  // const slideFn = () => {
  //   slideRef.current.removeEventListener('mousedown', doMouse);
  //   slideRef.current.addEventListener('mousedown', doMouse);
  // };
  // const initSlideMove = () => {
  //   if (slideRef.current) {
  //     slideFn();
  //     return;
  //   }
  //   const observe = new MutationObserver((mutations: any) => {
  //     const addNode = mutations[0].addedNodes[0];
  //     if (!slideRef.current) return;
  //
  //     if (!addNode && slideRef.current) {
  //       slideFn();
  //     }
  //
  //     if (addNode && addNode.className === 'operation-panel') {
  //       slideFn();
  //     }
  //   });
  //
  //   observe.observe(boxRef.current, {
  //     characterData: true,
  //     subtree: true,
  //     attributes: true,
  //     childList: true,
  //   });
  // };
  useEffect(() => {
    initVar({ initScale });
    initBoxMouse();
    // initSlideMove();
    operObj.image = imgRef.current;
    initOperObj.image = imgRef.current;
    operObj.image.addEventListener("load", () => {
      Object.assign(operObj, initOperObj);
      gesture.current = initGesture(
        boxRef,
        timer,
        setScaleLeft,
        setShowTips,
        setPercent,
        setShowImg,
        nInitLeft
      );
    });
    return () => {
      operObj.image && operObj.image.removeEventListener("load", initGesture);
    };
  }, [initScale]);

  const cEval = (fn: string) => {
    // 一个变量指向Function，防止有些前端编译工具报错
    const Fn = Function;
    return new Fn(`return ${fn}`)();
  };

  const operImg = (e: any) => {
    e.stopPropagation();
    const { type } = e.target.dataset;
    const par: any = {
      reduce: {
        max: "<=",
        min: ">",
        oper: "-",
      },
      enlarge: {
        max: "<",
        min: ">=",
        oper: "+",
      },
    };

    if (cEval(`${operObj.scale + par[type].max + 5}&&${operObj.scale}${par[type].min}${0.1}`)) {
      operObj.scale = cEval(operObj.scale * 10 + par[type].oper + 1) / 10;
      const in_lf = maxMinScale();
      setPercent(doNumInt(operObj.scale));
      nInitLeft.current = in_lf;
      setScaleLeft(in_lf);
    }
    doStyle("transform 300ms");
  };

  const goRestore = () => {
    setPercent(100);
    setScaleLeft(initLeft);
    doStyle("transform 300ms", "reset");
  };

  return (
    <ImgBoxWrap ref={boxRef} className="WrapOperImgBox">
      <img
        ref={imgRef}
        id="WrapOperImg"
        src={imgUrl}
        className={classnames(!showImg ? "img-visibility" : "", cls)}
      />
      {children}
      {!midStatus && showTips ? (
        <div className="operation-panel">
          <div className="show-tips">
            <span className="opear-icon lf" data-type="reduce" onClick={operImg}>
              <Icon type={"tingwu-suoxiao"} size={20} />
            </span>
            <section className="tips-line">
              <span
                onMouseDown={doMouse}
                ref={slideRef}
                className="circleSlide"
                style={{ left: scaleLeft }}
              />
            </section>
            <span className="opear-icon" data-type="enlarge" onClick={operImg}>
              <Icon type={"tingwu-fangda"} size={20} />
            </span>

            <p className="percent">{percent}%</p>
          </div>
          {showRestore ? (
            <span className="opear-icon reset" onClick={goRestore}>
              <Icon type={"tingwu-yuanbili"} size={20} />
              <Message className={"show-tip"} style={{ left: -22 }}>
                <div className={"arrow"}>
                  <span>原始大小</span>
                </div>
              </Message>
            </span>
          ) : null}
        </div>
      ) : null}
    </ImgBoxWrap>
  );
});
