import { Component } from "react";
import Taro from "@tarojs/taro";
import { Image, Text, View } from "@tarojs/components";
import auth from "@/services/auth";
import { CSSTransition } from "react-transition-group";
import "./index.css";
import { aesEncrypt, uuid } from "./utils";

class Captcha extends Component {
  constructor(props) {
    super(props);
    this.state = {
      blockSize: {
        width: "50px",
        height: "50px",
      },
      setSize: {
        imgHeight: 155,
        imgWidth: 310,
        barHeight: 40,
        barWidth: 310,
      },
      backImgBase: "",
      blockBackImgBase: "",
      backToken: "",
      startMoveTime: "",
      secretKey: "",
      captchaType: "blockPuzzle",
      moveBlockBackgroundColor: "rgb(255, 255, 255)",
      leftBarBorderColor: "",
      iconColor: "",
      barAreaLeft: 0,
      barAreaOffsetWidth: 0,
      startLeft: null,
      moveBlockLeft: null,
      leftBarWidth: null,
      status: false,
      isEnd: false,
      passFlag: "",
      tipWords: "",
      text: "向右滑动完成验证",
    };
  }

  componentDidMount() {
    this.uuid();
    this.init();

    // 组件卸载时移除事件监听
    Taro.eventCenter.off("touchmove", this.touchMoveHandler);
    Taro.eventCenter.off("touchend", this.touchEndHandler);

    // 调用 setBarArea 方法
    setTimeout(() => {
      this.setBarArea(this.bararea);
    }, 0);
  }

  // 初始化 uuid
  uuid() {
    const s = uuid();
    const slider = "slider" + "-" + s;
    const point = "point" + "-" + s;

    if (!Taro.getStorageSync("slider")) {
      Taro.setStorageSync("slider", slider);
    }
    if (!Taro.getStorageSync("point")) {
      Taro.setStorageSync("point", point);
    }
  }

  init() {
    this.getData();
  }

  getData() {
    auth.captcha
      .get({
        captchaType: this.state.captchaType,
        clientUid: Taro.getStorageSync("slider"),
        ts: Date.now(),
      })
      .then((res) => {
        if (res.data.repCode === "0000") {
          console.log(res.data.repData, "res.data.repData");
          // 在组件中使用转换后的URL加载图片
          // const imgUrl = base64ToURL(res.data.repData.originalImageBase64);
          // console.log(imgUrl,'imgUrl');
          this.setState({
            backImgBase: res.data.repData.originalImageBase64,
            blockBackImgBase: res.data.repData.jigsawImageBase64,
            backToken: res.data.repData.token,
            secretKey: res.data.repData.secretKey,
          });
        }
        // 请求次数超限
        if (res.data.repCode === "6201") {
          this.setState({
            backImgBase: null,
            blockBackImgBase: null,
            leftBarBorderColor: "#d9534f",
            iconColor: "#fff",
            // eslint-disable-next-line react/no-unused-state
            iconClass: "icon-close",
            passFlag: false,
            tipWords: res.data.repMsg,
          });
          setTimeout(() => {
            this.setState({
              tipWords: "",
            });
          }, 1000);
        }
      });
  }

  refresh = () => {
    this.getData();
    this.setState({
      moveBlockLeft: "",
      leftBarWidth: "",
      text: "向右滑动完成验证",
      moveBlockBackgroundColor: "#fff",
      leftBarBorderColor: "#337AB7",
      iconColor: "#fff",
      status: false,
      isEnd: false,
    });
  };

  setBarArea = (barArea) => {
    if (barArea) {
      Taro.createSelectorQuery()
        .select(".verify-bar-area")
        .boundingClientRect((rect) => {
          console.log("setBarArea", rect.left, rect.width);
          if (rect) {
            this.setState({
              barAreaLeft: rect.left,
              barAreaOffsetWidth: rect.width,
            });
          }
        })
        .exec();
    }
  };

  // 鼠标按下时的事件处理函数
  start = (e) => {
    console.log(e, "按下");
    this.setState({
      startMoveTime: new Date().getTime(), //记录开始滑动的时间
    });
    if (!this.state.isEnd) {
      this.setState({
        text: "",
        moveBlockBackgroundColor: "#337ab7", //移动块背景颜色
        leftBarBorderColor: "#337AB7", //左侧滑块边框颜色
        iconColor: "#fff", //图标颜色
        status: true, //状态标识为true
      });
      e.stopPropagation(); //阻止事件冒泡
    }
  };

  // 鼠标/触摸移动时的事件处理函数
  move = (e) => {
    console.log(e, "滑动滑动");
    if (this.state.status && !this.state.isEnd) {
      // 兼容触摸事件和鼠标事件
      let x = e.touches ? e.touches[0].pageX : e.pageX; // 获取鼠标/触摸点的X坐标
      console.log(x);
      let bar_area_left = this.state.barAreaLeft; // 滑块区域左侧距离
      let move_block_left = x - bar_area_left; // 计算移动块的左侧距离
      console.log(
        move_block_left >=
          this.state.barAreaOffsetWidth -
            parseInt(parseInt(this.state.blockSize.width) / 2) -
            2,
      );
      if (
        move_block_left >=
        this.state.barAreaOffsetWidth -
          parseInt(parseInt(this.state.blockSize.width) / 2) -
          2
      ) {
        console.log("第一个判断计算");
        move_block_left =
          this.state.barAreaOffsetWidth -
          parseInt(parseInt(this.state.blockSize.width) / 2) -
          2;
      }
      if (move_block_left <= 0) {
        console.log("第二个判断计算");
        move_block_left = parseInt(this.state.blockSize.width / 2);
      }
      let moveBlockLeft =
        Math.floor(move_block_left - this.state.startLeft) + "px"; //计算移动块的左侧位置并取整
      let leftBarWidth =
        Math.floor(move_block_left - this.state.startLeft) + "px"; //计算左侧滑块的宽度并取整
      console.log(moveBlockLeft, leftBarWidth); //打印移动块左侧位置和左侧滑块宽度
      this.setState({
        moveBlockLeft: moveBlockLeft, //更新移动块左侧位置
        leftBarWidth: leftBarWidth, //更新左侧滑块宽度
      });
    }
  };

  end = () => {
    console.log("鼠标放下");
    let endMoveTime = +new Date();
    if (this.state.status && !this.state.isEnd) {
      let moveLeftDistance = parseInt(
        (this.state.moveBlockLeft || "").replace("px", ""),
      );
      moveLeftDistance =
        (moveLeftDistance * 310) / parseInt(this.state.setSize.imgWidth);
      let data = {
        captchaType: this.state.captchaType,
        pointJson: this.state.secretKey
          ? aesEncrypt(
              JSON.stringify({
                x: moveLeftDistance,
                y: 5.0,
              }),
              this.state.secretKey,
            )
          : JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
        token: this.state.backToken,
        clientUid: Taro.getStorageSync("slider"),
        ts: Date.now(),
      };
      auth.captcha.check(data).then((res) => {
        if (res.data.repCode === "0000") {
          this.setState({
            isEnd: true,
            passFlag: true,
            tipWords: `${((endMoveTime - this.state.startMoveTime) / 1000).toFixed(2)}s验证成功`,
          });
          setTimeout(() => {
            this.setState({
              tipWords: "",
            });
            const captchaVerification = this.state.secretKey
              ? aesEncrypt(
                  this.state.backToken +
                    "---" +
                    JSON.stringify({
                      x: moveLeftDistance,
                      y: 5.0,
                    }),
                  this.state.secretKey,
                )
              : this.state.backToken +
                "---" +
                JSON.stringify({ x: moveLeftDistance, y: 5.0 });
            this.props.handleClick(captchaVerification);
            this.refresh();
          }, 1000);
        } else {
          this.setState({
            isEnd: true,
            moveBlockBackgroundColor: "#d9534f",
            leftBarBorderColor: "#d9534f",
            iconColor: "#fff",
            // eslint-disable-next-line react/no-unused-state
            iconClass: "icon-close",
            passFlag: false,
            tipWords: res.data.repMsg || "验证失败",
          });
          setTimeout(() => {
            this.refresh();
            this.setState({
              tipWords: "",
            });
          }, 1000);
        }
      });
      this.setState({
        status: false,
      });
    }
  };

  render() {
    const { vSpace, barSize, transitionWidth, finishText, transitionLeft } =
      this.props;
    return (
      <View style={{ position: "relative" }} className="stop-user-select">
        <View
          className="verify-img-out"
          style={{ height: parseInt(this.state.setSize.imgHeight) + vSpace }}
        >
          <View
            className="verify-img-panel"
            style={{
              width: this.state.setSize.imgWidth,
              height: this.state.setSize.imgHeight,
            }}
          >
            <Image
              src={"data:image/png;base64," + this.state.backImgBase}
              mode="aspectFill"
              style={{
                width: "100%",
                height: "100%",
              }}
            />
            {/* 其他内容 */}
            <CSSTransition
              in={this.state.tipWords.length > 0}
              timeout={150}
              classNames="tips"
              unmountOnExit
            >
              <View
                className={
                  this.state.passFlag
                    ? `${"verify-tips"} ${"suc-bg"}`
                    : `${"verify-tips"} ${"err-bg"}`
                }
              >
                {this.state.tipWords}
              </View>
            </CSSTransition>
          </View>
        </View>

        <View
          className="verify-bar-area"
          style={{
            width: this.state.setSize.imgWidth,
            height: barSize.height,
            lineHeight: barSize.height,
          }}
          ref={(ref) => (this.bararea = ref)}
        >
          <Text className="verify-msg">{this.state.text}</Text>
          <View
            className="verify-left-bar"
            style={{
              width:
                this.state.leftBarWidth !== undefined
                  ? this.state.leftBarWidth
                  : barSize.height,
              height: barSize.height,
              borderColor: this.state.leftBarBorderColor,
              transaction: transitionWidth,
            }}
          >
            <Text className="verify-msg">{finishText}</Text>

            <View
              className="verify-move-block"
              onTouchStart={this.start}
              onMouseDown={this.start}
              onTouchMove={this.move}
              onMouseMove={this.move}
              onTouchEnd={this.end}
              onMouseUp={this.end}
              onMouseLeave={this.end}
              style={{
                width: barSize.height,
                height: barSize.height,
                backgroundColor: this.state.moveBlockBackgroundColor,
                left: this.state.moveBlockLeft,
                transition: transitionLeft,
              }}
            >
              <Text
                className="verify-icon iconfont icon-right"
                style={{ color: this.state.iconColor }}
              ></Text>
              <View
                className="verify-sub-block"
                style={{
                  width:
                    Math.floor(
                      (parseInt(this.state.setSize.imgWidth) * 47) / 310,
                    ) + "px",
                  height: this.state.setSize.imgHeight,
                  top:
                    "-" +
                    (parseInt(this.state.setSize.imgHeight) + vSpace) +
                    "px",
                  backgroundSize:
                    this.state.setSize.imgWidth +
                    " " +
                    this.state.setSize.imgHeight,
                }}
              >
                <Image
                  src={"data:image/png;base64," + this.state.blockBackImgBase}
                  alt=""
                  style={{ width: "100%", height: "100%", display: "block" }}
                />
              </View>
            </View>
          </View>
        </View>
      </View>
    );
  }
}

Captcha.defaultProps = {
  mode: "fixed",
  vSpace: 5,
  imgSize: {
    width: "310px",
    height: "200px",
  },
  barSize: {
    width: "310px",
    height: "40px",
  },
  setSize: {
    imgHeight: 200,
    imgWidth: 310,
    barHeight: 0,
    barWidth: 0,
  },
};

export default Captcha;
