<template>
  <view>
    <view class="seach">
      <view class="neibox"> 子点位 </view>
      <view class="seach_i">
        <view class="inputbox" @click="childNodeListVisible = true">
          <view class="">
            {{ selectedChildNodeName ? selectedChildNodeName : '请选择子点位' }}
          </view>
          <u-icon name="arrow-right" size="24rpx" color="#005bac"></u-icon>
        </view>
      </view>
      <view class="neibox" @click="popShow = true"> 筛选 </view>
    </view>
    <view class="mainbox">
      <view class="main_bottom">
        <view
          class="scoll_main"
          ref="scrollMain"
          @touchstart.prevent="handleTouchStart"
          @touchmove.prevent="handleTouchMove"
          @touchend="handleTouchEnd"
          @dblclick="handleDoubleClick"
          :style="containerStyle"
        >
          <TreeChart
            :size="size"
            :json="data"
            :class="{ landscape: landscape.length }"
            @click-node="clickNode"
          />
        </view>
      </view>
    </view>
    <u-popup
      :show="popShow"
      mode="right"
      @close="popShow = false"
      :closeOnClickOverlay="false"
    >
      <view class="rightPopup">
        <view class="popup_top">
          <view
            @click="
              () => {
                getDataList(), (popShow = false)
              }
            "
            >筛选</view
          >
          <view class="top_red" @click="popShow = false">{{ '返回' }}</view>
        </view>
        <view class="typesBox">
          <view class="typeTitle" @click="stageListVisible = true"> 阶段 </view>
          <view class="choiceBox">
            <view class="inputbox" @click="stageListVisible = true">
              <view class="">
                {{ stageName ? stageName : '请选择' }}
              </view>
              <u-icon name="arrow-right" size="24rpx" color="#090000"></u-icon>
            </view>
          </view>
        </view>
        <view class="typesBox">
          <view class="typeTitle" @click="statusListVisible = true">
            状态
          </view>
          <view class="choiceBox">
            <view class="inputbox" @click="statusListVisible = true">
              <view class="">
                {{ statusName ? statusName : '请选择' }}
              </view>
              <u-icon name="arrow-right" size="24rpx" color="#090000"></u-icon>
            </view>
          </view>
        </view>

        <view class="popup_bottom">
          <view class="bottom_btn thebtn1" @click="clearAll">清空筛选条件</view>
          <view
            class="bottom_btn thebtn2"
            @click="
              () => {
                handleSearch(), (popShow = false)
              }
            "
            >{{ '确定' }}
          </view>
        </view>
      </view>
      <u-picker
        @cancel="stageListVisible = false"
        :show="stageListVisible"
        ref="uPicker"
        :columns="stageList"
        @confirm="stagePickerHandleConfirm"
        keyName="label"
      ></u-picker>
      <u-picker
        @cancel="statusListVisible = false"
        :show="statusListVisible"
        ref="uPicker"
        :columns="statusList"
        @confirm="statusPickerHandleConfirm"
        keyName="label"
      ></u-picker>
    </u-popup>
    <!-- 子点位选择picker -->
    <u-picker
      @cancel="childNodeListVisible = false"
      :show="childNodeListVisible"
      ref="childNodePicker"
      :columns="childNodeColumns"
      @confirm="childNodePickerHandleConfirm"
      keyName="childNode"
    ></u-picker>

    <Eposter
      width="750"
      height="1334"
      :list="list"
      backgroundColor="rgb(255, 255, 255)"
      @on-success="onSuccess"
      ref="Eposter"
    >
    </Eposter>
  </view>
</template>

<script>
import html2canvas from 'html2canvas'
import TreeChart from '@/components/architectures/resettleSO.vue'
import Eposter from '@/components/architectures/Poster.vue'

import * as arc from '@/config/architecture.js'
export default {
  components: {
    TreeChart,
    Eposter,
  },
  data() {
    return {
      childNodeList: [],
      childNodeColumns: [[]],
      childNodeListVisible: false,
      selectedChildNodeName: '',
      treeData: [],
      queryParams: {
        childNode: '',
        stage: 1,
        status: 0,
      },
      stageList: [
        [
          { value: 1, label: '阶段一' },
          { value: 2, label: '阶段二' },
          { value: 3, label: '阶段三' },
        ],
      ], //期数
      statusList: [
        [
          { value: 0, label: '已完成' },
          { value: 1, label: '未完成' },
        ],
      ], //期数
      popShow: false,
      stageListVisible: false,
      statusListVisible: false,
      stageName: '',
      statusName: '',
      data: {},
      size: 0.5,
      landscape: [],
      popMould: {},
      isPop: false,
      touchStartPosition1: {
        x: 0,
        y: 0,
      },
      touchStartPosition2: {
        x: 0,
        y: 0,
      },
      initialDistance: 0,
      initialSize: 0.4, // 记录缩放开始时的初始尺寸
      minSize: 0.2, // 最小缩放值
      maxSize: 3.0, // 最大缩放值
      isZooming: false, // 是否正在缩放
      isDragging: false, // 是否正在拖动
      dragStartPosition: { x: 0, y: 0 }, // 拖动开始位置
      containerTransform: { x: 0, y: 0 }, // 容器变换位置
      lastTouchTime: 0, // 上次触摸时间，用于区分点击和拖动
      lastTouchPosition: { x: 0, y: 0 }, // 上次触摸位置，用于计算速度
      velocity: { x: 0, y: 0 }, // 拖动速度，用于惯性滚动
      maxTransform: { x: 1000, y: 1000 }, // 最大变换距离限制
      list: [],
    }
  },
  onLoad() {
    this.init()
    this.getChildList().then(() => {
      this.getDataList()
    })
  },

  mounted() {
    // 初始化容器变换
    this.$nextTick(() => {
      console.log('组件已挂载')
    })
  },

  computed: {
    containerStyle() {
      return {
        transform: `translate(${this.containerTransform.x}px, ${this.containerTransform.y}px) scale(${this.size})`,
        transformOrigin: 'center center',
        transition:
          this.isDragging || this.isZooming
            ? 'none'
            : 'transform 0.1s ease-out',
      }
    },
  },
  methods: {
    init() {
      this.stageName = this.stageList[0][0].label
      this.statusName = this.statusList[0][0].label
      this.queryParams.stage = this.stageList[0][0].value
      this.queryParams.status = this.statusList[0][0].value
    },
    //复制文字
    copyText() {
      let self = this
      let md = self.popMould
      let text = `会员编号：${md.memberCode} \n会员姓名：${md.name}支付时间：${md.payDate} \n业绩  左区  右区 \n真实新增  ${md.leftRealNewPv}  ${md.rightRealNewPv} \n首购新增  ${md.leftFirstPurchaseAdd}  ${md.rightFirstPurchaseAdd} \n复购新增  ${md.leftRepeatPurchaseSurplus}  ${md.rightRepeatPurchaseSurplus} \n真实累计  ${md.leftRealTotal}  ${md.rightRealTotal} \n首购累计  ${md.leftFirstTotal}  ${md.rightFirstTotal} \n复购累计  ${md.leftRepeatPurchaseTotal}  ${md.rightRepeatPurchaseTotal} \n首购结余  ${md.leftFirstSurplus}  ${md.rightFirstSurplus} \n复购结余  ${md.leftRepeatPurchaseSurplus}  ${md.rightRepeatPurchaseSurplus} \n`
      uni.setClipboardData({
        data: text,
        success: function (res) {
          uni.getClipboardData({
            success: function (res) {
              uni.showToast({
                title: '复制成功',
              })
            },
          })
        },
      })
    },
    //下载图片
    downImage(elClass) {
      this.$refs.Eposter.createForElRect(elClass, false)
    },
    downloadImg() {
      let self = this
      let element = document.querySelector('.Poster1')
      uni.showLoading({
        title: '图片保存中',
      })
      html2canvas(element)
        .then(function (canvas) {
          let dataURL = canvas.toDataURL('image/jpeg')
          let link = document.createElement('a')
          link.style.display = 'none'
          link.href = dataURL
          link.download = 'image.jpg'
          document.body.appendChild(link)
          link.click()
          document.body.removeChild(link)
          uni.showToast({
            icon: 'none',
            title: '保存成功',
            duration: 2000,
          })
          uni.hideLoading()
        })
        .catch(function (error) {
          uni.hideLoading()
          uni.showModal({
            title: '保存失败',
          })
        })
    },
    onSuccess(val) {
      // console.log('🌈val',val)
      this.posterImg = val
      this.downloadImg(this.posterImg)
    },

    handleTouchStart(event) {
      console.log('handleTouchStart triggered', event.touches.length)
      const touch1 = event.touches[0]
      const touch2 = event.touches[1]
      const currentTime = Date.now()

      if (touch2) {
        // 双指触摸 - 缩放模式
        this.isZooming = true
        this.isDragging = false
        this.initialSize = this.size

        this.touchStartPosition1 = {
          x: touch1.clientX,
          y: touch1.clientY,
        }
        this.touchStartPosition2 = {
          x: touch2.clientX,
          y: touch2.clientY,
        }
        this.initialDistance = Math.hypot(
          touch2.clientX - touch1.clientX,
          touch2.clientY - touch1.clientY
        )
      } else {
        // 单指触摸 - 拖动模式
        this.isZooming = false
        this.isDragging = true
        this.dragStartPosition = {
          x: touch1.clientX,
          y: touch1.clientY,
        }
        this.lastTouchTime = currentTime
      }
    },
    handleTouchMove(event) {
      const touch1 = event.touches[0]
      const touch2 = event.touches[1]

      if (touch2 && this.isZooming && this.initialDistance > 0) {
        // 双指缩放处理
        const currentDistance = Math.hypot(
          touch2.clientX - touch1.clientX,
          touch2.clientY - touch1.clientY
        )

        const scale = currentDistance / this.initialDistance
        let newSize = this.initialSize * scale

        // 应用边界限制
        newSize = Math.max(this.minSize, Math.min(this.maxSize, newSize))

        // 平滑缩放
        const sizeDiff = newSize - this.size
        this.size = this.size + sizeDiff * 0.3
      } else if (!touch2 && this.isDragging) {
        // 单指拖动处理
        const deltaX = touch1.clientX - this.dragStartPosition.x
        const deltaY = touch1.clientY - this.dragStartPosition.y

        console.log('拖动中', {
          deltaX,
          deltaY,
          touch: { x: touch1.clientX, y: touch1.clientY },
          dragStart: this.dragStartPosition,
          containerTransform: this.containerTransform,
        })

        // 计算拖动速度
        this.velocity.x = deltaX * 0.1
        this.velocity.y = deltaY * 0.1

        // 更新容器变换位置（添加阻尼效果）
        let newX = this.containerTransform.x + deltaX * 0.8
        let newY = this.containerTransform.y + deltaY * 0.8

        // 应用边界限制（根据缩放调整边界）
        const scaledMaxX = this.maxTransform.x * this.size
        const scaledMaxY = this.maxTransform.y * this.size

        newX = Math.max(-scaledMaxX, Math.min(scaledMaxX, newX))
        newY = Math.max(-scaledMaxY, Math.min(scaledMaxY, newY))

        this.containerTransform.x = newX
        this.containerTransform.y = newY

        // 更新拖动起始位置
        this.dragStartPosition.x = touch1.clientX
        this.dragStartPosition.y = touch1.clientY

        // 应用变换到DOM元素
        this.updateContainerTransform()
      }
    },
    handleTouchEnd(event) {
      const currentTime = Date.now()
      const touchDuration = currentTime - this.lastTouchTime

      // 如果是拖动结束，启动惯性滚动
      if (
        this.isDragging &&
        (Math.abs(this.velocity.x) > 1 || Math.abs(this.velocity.y) > 1)
      ) {
        this.startInertiaScroll()
      }

      // 重置触摸状态
      this.isZooming = false
      this.isDragging = false
      this.touchStartPosition1 = { x: 0, y: 0 }
      this.touchStartPosition2 = { x: 0, y: 0 }
      this.initialDistance = 0
      this.initialSize = this.size
      this.dragStartPosition = { x: 0, y: 0 }
    },

    // 惯性滚动
    startInertiaScroll() {
      const friction = 0.95 // 摩擦系数
      const minVelocity = 0.1 // 最小速度阈值

      const animateInertia = () => {
        // 应用速度到位置
        let newX = this.containerTransform.x + this.velocity.x
        let newY = this.containerTransform.y + this.velocity.y

        // 应用边界限制
        const scaledMaxX = this.maxTransform.x * this.size
        const scaledMaxY = this.maxTransform.y * this.size

        newX = Math.max(-scaledMaxX, Math.min(scaledMaxX, newX))
        newY = Math.max(-scaledMaxY, Math.min(scaledMaxY, newY))

        this.containerTransform.x = newX
        this.containerTransform.y = newY

        // 减少速度
        this.velocity.x *= friction
        this.velocity.y *= friction

        // 更新DOM
        this.updateContainerTransform()

        // 继续动画或停止
        if (
          Math.abs(this.velocity.x) > minVelocity ||
          Math.abs(this.velocity.y) > minVelocity
        ) {
          requestAnimationFrame(animateInertia)
        }
      }

      requestAnimationFrame(animateInertia)
    },

    // 更新容器变换 - 现在使用响应式样式，这个方法可以简化
    updateContainerTransform() {
      // 使用响应式计算属性，无需手动更新DOM
      console.log('容器变换更新', this.containerTransform, this.size)
    },
    // 重置缩放和位置到默认状态
    resetZoom() {
      this.size = 0.4
      this.initialSize = 0.4
      this.containerTransform = { x: 0, y: 0 }
      this.updateContainerTransform()
    },

    // 双击重置缩放和位置
    handleDoubleClick() {
      this.resetZoom()
    },

    clickNode(e) {
      return
    },
    stagePickerHandleConfirm(e) {
      this.queryParams.memberSettlePeriodId = e.value[0].value
      this.stageName = e.value[0].label
      this.stageListVisible = false
    },
    statusPickerHandleConfirm(e) {
      this.queryParams.status = e.value[0].value
      this.statusName = e.value[0].label
      this.statusListVisible = false
    },
    childNodePickerHandleConfirm(e) {
      this.queryParams.memberCode = e.value[0].childNode
      this.selectedChildNodeName = e.value[0].childNode
      this.childNodeListVisible = false
      // 选择子点位后自动获取数据
      this.getDataList()
    },
    getChildList() {
      return new Promise((resolve, reject) => {
        arc.getChildList(this.queryParams).then(res => {
          if (res.code === 200) {
            this.childNodeList = res.data
            // 格式化为picker需要的数据格式
            this.childNodeColumns = [res.data]
            this.queryParams.childNode = res.data[0].childNode
            this.selectedChildNodeName = res.data[0].childNode
            resolve()
          }
        })
      })
    },
    getDataList() {
      arc.getAzFramework(this.queryParams).then(res => {
        this.data = res.data[0]
      })
    },
    handleSearch() {
      this.getChildList().then(() => {
        this.getDataList()
      })
    },

    clearAll() {
      this.popShow = false
      this.init()
      this.queryParams = {
        stage: this.stageList[0][0].value,
        status: this.statusList[0][0].value,
      }
      this.handleSearch()
    },
  },
}
</script>
<style lang="scss" scoped>
.ispop_box {
  padding: 27rpx;
  padding-top: 60rpx;
  width: 670rpx;
  font-size: 24rpx;
  color: #333333;

  .pop_top {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .poster1 {
      height: 88rpx;
      width: 88rpx;
    }

    .poster2 {
      width: 88rpx;
      height: 54rpx;
      border-radius: 10rpx;
      margin-left: 20rpx;
    }

    .top_right {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  }

  .pop_center {
    .center_flex {
      display: flex;
      align-items: center;
      margin-top: 20rpx;

      .c1 {
        width: 20%;
      }

      .c2 {
        width: 80%;
        display: flex;
        justify-content: center;
        align-items: center;
        background: #f3f3f3;
        border: 2rpx solid #eeeeee;
        border-radius: 8rpx;
        padding: 10rpx 0;
      }
    }
  }

  .pop_bottom {
    margin: 20rpx 0;
    border-top: 2rpx solid #eeeeee;
    border-top: 2rpx solid #eeeeee;

    .b_flex {
      display: flex;

      .bt1 {
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 22rpx;
        flex: 1;
      }

      .bt2 {
        display: flex;
        justify-content: center;
        align-items: center;
        margin-top: 22rpx;
        flex: 1;
        background: #f3f3f3;
        border: 2rpx solid #eeeeee;
        border-radius: 8rpx;
        padding: 12rpx 0;
        margin: 11rpx 18rpx;
      }
    }
  }

  .btn_box {
    display: flex;
    align-items: center;
    justify-content: space-between;

    .small-btn {
      width: 312rpx;
      height: 72rpx;
      background: #005bac;
      border-radius: 34rpx;
      font-size: 28rpx;
      font-weight: 400;
      color: #ffffff;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .small-text-btn {
      width: 312rpx;
      height: 72rpx;
      border: 1px solid #005bac;
      border-radius: 34rpx;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 28rpx;
      color: #005bac;
    }
  }
}

.operate-btnboxs {
  padding: 29rpx 26rpx;
  background-color: #ffffff;

  .d-c-c {
    display: flex;
    align-items: center;
    justify-content: center;

    .operate-btn {
      width: 64rpx;
      height: 64rpx;
      margin: 5rpx;
      // background: #F2F2F2;
      border-radius: 5rpx;
      padding: 0;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}

.rightPopup {
  width: 645rpx;
  height: 100%;
  overflow: auto;

  .popup_top {
    padding: 25rpx;
    background-color: rgba(176, 196, 222, 0.45);
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 28rpx;
    font-family: Source Han Sans CN;
    font-weight: 400;
    color: #333333;

    .top_red {
      color: #005bac;
    }
  }

  .popup_bottom {
    display: flex;
    align-items: center;
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;

    .bottom_btn {
      flex: 1;
      padding: 20rpx 0;
      text-align: center;
      font-size: 28rpx;
    }

    .thebtn1 {
      background-color: rgba(176, 196, 222, 0.45);
      color: #333333;
    }

    .thebtn2 {
      background-color: #005bac;
      color: #ffffff;
    }
  }

  .typesBox {
    margin-top: 40rpx;

    .typeTitle {
      padding: 0 24rpx;
      font-size: 30rpx;
      font-family: Source Han Sans CN;
      font-weight: bold;
      color: #333333;
    }

    .choiceBox {
      padding: 0 12rpx;
      display: flex;
      margin-top: 17rpx;
      align-items: center;
      flex-wrap: wrap;

      .inputbox {
        font-size: 26rpx;
        width: 100%;
        padding: 20rpx 32rpx;
        border-radius: 20rpx;
        background-color: rgba(176, 196, 222, 0.45);
        display: flex;
        justify-content: space-between;
        align-items: center;
      }

      .flex_btn {
        background-color: rgba(176, 196, 222, 0.45);
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 14rpx 48rpx;
        border-radius: 26rpx;
        font-size: 24rpx;
        font-family: Source Han Sans CN;
        font-weight: 400;
        color: #333333;
        margin: 17rpx 5rpx;
      }

      .timesbtn {
        flex: 1;
      }

      .selectbtn {
        background-color: #005bac;
        color: #ffffff;
      }
    }
  }
}

.seach {
  background: #fff;
  overflow: hidden;
  padding: 20rpx 23rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  border-bottom: 2rpx solid #eee;

  .these {
    border: none;
    padding: 10rpx 0 !important;
  }

  .seach_i {
    padding: 0 20rpx;
    border-radius: 34rpx;
    background: #fff;
    flex: 1;
    background: #f5f6f8;
    margin: 0 20rpx;

    .inputbox {
      font-size: 26rpx;
      width: 100%;
      padding: 15rpx 20rpx;
      border-radius: 34rpx;
      background-color: #f5f6f8;
      display: flex;
      justify-content: space-between;
      align-items: center;
      color: #333333;

      &:active {
        background-color: #e8e9eb;
      }
    }
  }

  .neibox {
    display: flex;
    align-items: center;
    font-size: 26rpx;
    font-family: PingFang SC;
    font-weight: 400;
    color: #999999;
  }

  .seatch_r {
    background: #005bac;
    border-radius: 50%;
    padding: 8rpx;
  }
}

.mainbox {
  padding: 26rpx 22rpx;
  height: 100%;

  .main_bottom {
    width: 100%;
    height: 100%;
    margin-top: 25rpx;
    background-color: #ffffff;
    padding: 38rpx 0;

    border-radius: 20rpx;
  }

  .scoll_main {
    width: 700rpx;

    transform-origin: center center; // 设置变换原点为中心
    cursor: grab; // 显示可拖动光标

    &:active {
      cursor: grabbing; // 拖动时的光标
    }
  }
}
</style>
