<template>
  <view class="signature-wrap">
    <view
      class="img-wrap"
      @tap="showSignature()"
      @touchstart="touchSignature"
      v-if="!pages"
    >
      <image :src="absPrevView" mode="scaleToFill"></image>
    </view>
    <view v-if="!disabled" v-show="show" class="signature-contain">
      <view class="signature-main" style="z-index: 3000">
        <view class="signature-title"
          ><text v-for="(t, index) in titles" :key="index">{{ t }}</text></view
        >
        <canvas
          disable-scroll="true"
          class="signature"
          :class="cid"
          canvas-id="cvs"
          @touchstart="touchstart"
          @touchmove="touchmove"
          @touchend="touchend"
        ></canvas>
        <canvas
          class="tempCanvas"
          canvas-id="tempCanvas"
          style="display: none"
        ></canvas>
        <view class="signature-btns">
          <view
            class="btn btn-cancel cu-btn bg-main margin-tb-sm text-white"
            @tap="cancelSignature()"
          >
            <text>取</text><text>消</text>
          </view>
          <view
            class="btn btn-clear cu-btn bg-main margin-tb-sm text-white"
            @tap="clearSignature()"
          >
            <text>清</text><text>空</text>
          </view>
          <view
            class="btn btn-ok cu-btn bg-main margin-tb-sm text-white"
            @tap="onOK()"
          >
            <text>确</text><text>定</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  cxt: null,
  data() {
    return {
      VERSION: "1.0.0",
      cid: "cvs",
      show: false,
      ctrl: null,
      listeners: [],
      prevView: "",

      draws: [],
      lines: [],
      line: null,
    };
  },
  props: {
    value: {
      default: "",
    },
    title: {
      type: String,
      default: "请签字",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    // 新增属性：导出格式，'base64' 或 'tempFilePath'
    exportFormat: {
      type: String,
      default: "base64", // 默认导出base64格式
    },
    // 是否当作页面使用
    pages: {
      type: Boolean,
      default: false,
    },
  },
  watch: {
    value() {
      this.prevView = this.value;
    },
  },
  computed: {
    titles() {
      return this.title.split("");
    },
    absPrevView() {
      var pv = this.prevView;
      // if(pv){
      // 	pv = this.$wrapUrl(pv)
      // }
      return pv;
    },
  },
  mounted() {
    this.prevView = this.value;
    console.log("dx");
    if (this.pages) {
      this.showSignature();
    }
  },
  methods: {
    onOK() {
      // 修改此处以支持PNG格式
      let data = this.ctrl.getValue();
      // 如果返回的是Promise，则说明正在获取PNG格式
      if (data instanceof Promise) {
        data.then((pngData) => {
          this.$emit("input", pngData);
          this.prevView = pngData;
          if (!this.pages) {
            this.hideSignature();
          }
          let f = this.listeners.shift();
          if (f) {
            f(pngData);
          }
        });
      } else {
        // 否则使用原来的逻辑
        this.$emit("input", data);
        this.prevView = data;
        if (!this.pages) {
          this.hideSignature();
        }
        let f = this.listeners.shift();
        if (f) {
          f(data);
        }
      }
    },
    touchSignature() {
      let sig = this.prevView;
      if (!sig || !sig.length) {
        this.showSignature();
      }
    },
    showSignature() {
      if (this.disabled) return;
      if (!this.ctrl) {
        this.initCtrl();
      } else if (!this.show) {
        this.clearSignature();
        this.show = true;
      }
    },
    async getSyncSignature() {
      this.showSignature();
      return await new Promise(async (resolve, reject) => {
        // 修改此处以支持PNG格式
        this.listeners.push(async (res) => {
          resolve(res);
        });
      });
    },
    cancelSignature() {
      if (this.pages) {
        uni.navigateBack();
        return;
      }
      this.listeners.map((f) => {
        f(null);
      });
      this.hideSignature();
    },
    hideSignature() {
      this.ctrl && this.ctrl.clear();
      this.show = false;
    },
    clearSignature() {
      this.ctrl && this.ctrl.clear();
    },
    async initCtrl() {
      this.show = true;
      let cxt = uni.createCanvasContext(this.cid, this);
      this.cxt = cxt;
      // cxt.clearRect(0,0,c.width,c.height);
      this.ctrl = {
        width: 0,
        height: 0,
        clear: () => {
          this.lines = [];
          let info = uni
            .createSelectorQuery()
            .in(this)
            .select("." + this.cid);
          info
            .boundingClientRect((data) => {
              if (data) {
                cxt.clearRect(0, 0, data.width, data.height);
                if (data.width && data.height) {
                  this.ctrl.width = data.width;
                  this.ctrl.height = data.height;
                }
              }
            })
            .exec();
          this.redraw();
        },
        getValue: () => {
          if (!this.lines.length) return "";
          // 返回一个Promise，用于获取旋转-90度的PNG格式临时文件路径
          return new Promise((resolve, reject) => {
            const that = this;
            // 首先获取当前canvas的图像数据
            uni.canvasToTempFilePath(
              {
                canvasId: "cvs",
                fileType: "png",
                quality: 1,
                width: this.ctrl.width,
                height: this.ctrl.height,
                destWidth: this.ctrl.width / 3,
                destHeight: this.ctrl.height / 3,
                success: function (rotatedRes) {
                  console.log("rotatedRes", rotatedRes);
                  resolve(rotatedRes.tempFilePath);
                  return;
                  // 根据exportFormat属性决定返回格式
                  if (that.exportFormat === "tempFilePath") {
                    // 返回临时文件路径
                    resolve(rotatedRes.tempFilePath);
                  } else {
                    // 默认返回base64格式
                    uni.getFileSystemManager().readFile({
                      filePath: rotatedRes.tempFilePath,
                      encoding: "base64",
                      success: function (base64Res) {
                        // 将base64数据封装成data URL格式
                        const base64Data =
                          "data:image/png;base64," + base64Res.data;
                        resolve(base64Data);
                      },
                      fail: function () {
                        // 如果读取base64失败，返回空字符串
                        resolve("");
                      },
                    });
                  }
                },
                fail: function () {
                  // 获取原始canvas图像失败时返回空字符串
                  resolve("");
                },
              },
              that
            );
          });
        },
      };
      this.$nextTick(function () {
        this.ctrl.clear();
      });
    },
    _get_point(e) {
      return {
        x: e.changedTouches[0].x.toFixed(1),
        y: e.changedTouches[0].y.toFixed(1),
      };
    },
    touchstart(e) {
      let p = this._get_point(e);
      this.line = {
        start: p,
        points: [p],
      };
      this.lines.push(this.line);
    },
    touchmove(e) {
      let p = this._get_point(e);
      this.line.points.push(p);
      if (!this.tm) {
        this.tm = setTimeout(() => {
          this.redraw();
          this.tm = 0;
        }, 10);
      }
    },
    touchend(e) {
      let p = this._get_point(e);
      this.line.points.push(p);
      this.line.end = p;
      this.redraw();
    },
    redraw() {
      let cxt = this.cxt;
      cxt.setStrokeStyle("#000");
      cxt.setLineWidth(3);
      var last = null;
      this.lines.map((l) => {
        cxt.beginPath();
        if (l.points.length < 2) {
          return;
        }
        cxt.moveTo(l.start.x, l.start.y);
        l.points.map((p) => {
          cxt.lineTo(p.x, p.y);
        });
        cxt.stroke();
      });

      cxt.draw();
    },
    canvasIdErrorCallback: function (e) {
      console.error(e.detail.errMsg);
    },
  },
};
</script>

<style lang="scss">
.signature-wrap {
  height: 100%;
  width: 100%;
  // padding: 0 5px;

  // min-width: 60vw;
  .img-wrap {
    width: 100%;
    min-height: calc(100vh / 3);
    display: flex;
    align-items: center;
    text-align: center;
    align-content: center;
    justify-content: center;
    image {
      width: 100%;
      //   transform: rotate(-90deg);
    }
    // background: red;
  }
}

.signature-contain {
  z-index: 9000;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;

  .signature-main {
    background: white;
    flex-direction: row-reverse;
    display: flex;
    align-items: stretch;
    height: 101%;
    overflow: scroll;
  }

  .signature-title {
    font-weight: bold;
    font-size: 18px;
    display: flex;
    padding: 0 20rpx;
    flex-direction: column;
    justify-content: center;
    height: 100vh;
    color: $uni-text-color;

    text {
      transform: rotate(90deg);
    }
  }

  .signature {
    border: 1px dotted black;
    border-bottom: 1px dotted black;
    background: #fff;
    margin: 10px 0;
    width: 90vw;
    height: 90vh;
    align-self: center;
    // pointer-events:none;
    // transform: rotate(-90deg);
  }

  .signature-90 {
    transform: rotate(-90deg);
  }

  .signature-btns {
    display: flex;
    padding: 2px;
    // margin-right: 5px;
    flex-direction: column;

    .btn {
      flex-grow: 1;
      flex-shrink: 0;
      padding: 20rpx;
      font-size: 20px;
      margin: 0;
      text-align: center;
      text-decoration: none;
      height: 30vh;
      display: flex;
      align-content: center;
      justify-content: center;
      flex-direction: column;

      text {
        transform: rotate(90deg);
      }

      & + .btn {
        border-top: 1px solid #eee;
      }

      &.btn-clear {
        // background-color: #fc2a07;
        color: $uni-color-success;
      }

      &.btn-cancel {
        // background-color: #eff4f4;
        color: $uni-color-warning;
      }

      &.btn-ok {
        // background-color: $uni-color-success;
        color: $uni-color-primary;
      }
    }
  }
}
</style>
