<template>
  <v-card class="d-flex flex-column align-center" style="height: 100%;">

    <div class="d-flex black align-center justify-center" style="height: 100%; position: relative; overflow: hidden;">
      <div class="contentBox">
        <v-card :width="size.width" :height="size.height" class="content" ref="content">
          <canvas :width="size.width" :height="size.height"
            ref="cover"
            class="cover noMove"
          ></canvas>
          <img class="noMove" :src="src" alt="" :width="size.width" :height="size.height">
        </v-card>

        <div class="contentBox-tool">
          <v-btn
            v-for="tool in tools"
            :key="tool.icon"
            class="ma-2"
            fab
            dark
            small
            @click="tool.handle()"
          >
            <v-icon dark>
              {{ tool.icon }}
            </v-icon>
          </v-btn>
        </div>
      </div>
      <v-card
        v-if="!clear"
        class="contentBox-desc rounded-lg"
        :class="{hide: hidePanel}"
        :elevation="!hidePanel * 15"
        dark
        width="300"
        height="200"
      >
        <div class="arrows d-flex align-center justify-center cursor-pointer" @click="hidePanel = !hidePanel">
          <v-icon :size="hidePanel ? 24 : 36">{{ hidePanel ? 'mdi-card-bulleted' : 'mdi-chevron-left'}}</v-icon>
        </div>
        <v-card-title class="text-h5">
          {{ chooseItem.frametype }}
        </v-card-title>

        <v-card-subtitle>{{ chooseItem.detail_info }}</v-card-subtitle>
        <v-card-text>
          <p>脸型： {{ chooseItem.faceType }}</p>
          <p>品牌： {{ chooseItem.brand }}</p>
          <p>材质： {{ chooseItem.material }}</p>
        </v-card-text>
      </v-card>
      <div v-show="!clear" class="pt-3 example-3d">
        <swiper class="swiper" ref="mySwiper" :options="swiperOption" @slideChange="onSlideChange">
          <swiper-slide v-for="(val, index) in item.items" :key="val.id + '-' + index" class="pa-3 swiper-item" :class="{'active': index === active}">
            <div class="item d-flex flex-column align-center justify-center">
              <div class="d-flex align-center justify-center item-img">
                <img :src="val.pic_url" alt="">
              </div>
            </div>
          </swiper-slide>
          <!-- <div class="swiper-pagination" slot="pagination"></div> -->
        </swiper>
      </div>
    </div>
    <v-overlay :value="loading" opacity="0.5">
      <v-progress-linear
        color="white"
        indeterminate
        rounded
        height="10"
        style="width: 200px;"
      ></v-progress-linear>
    </v-overlay>
  </v-card>
</template>
<script>
// import { debounce } from 'lodash'
import programType from '@/utils/program'
import { swiper, swiperSlide } from 'vue-awesome-swiper'
import 'swiper/dist/css/swiper.css'
import { isMobile } from '@/utils'
export default {
  name: 'm-try',
  components: {
    swiper,
    swiperSlide
  },
  props: {
    src: {
      type: String,
      default: ''
    },
    item: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      hidePanel: false,
      loading: false,
      isMobile: isMobile(),
      clear: false,
      active: 0,
      canMove: false,
      moveObj: {
        startX: null,
        startY: null,
        left: null,
        top: null
      },
      swiperOption: {
        effect: 'coverflow',
        grabCursor: true,
        centeredSlides: true,
        slidesPerView: 'auto',
        coverflowEffect: {
          rotate: 50,
          stretch: 0,
          depth: 100,
          modifier: 1,
          slideShadows: false
        }
      },
      canvasCtx: null,
      imgEntity: new Image(),
      imgProps: {
        x: 0,
        y: 0,
        width: 10,
        height: 10,
        angle: 0,
        scale: 1
      }
    }
  },
  inject: ['size'],
  computed: {
    chooseItem () {
      const obj = this.item.items[this.active] ?? {}
      obj.faceType = programType.find(e => e.value === obj.facetype)?.face ?? ''
      return obj
    },
    tryGlassesSize () {
      const x1 = this.item.facial_points.cheek_left_3.x
      const y1 = this.item.facial_points.cheek_left_3.y
      const x2 = this.item.facial_points.cheek_right_3.x
      const y2 = this.item.facial_points.cheek_right_3.y
      return {
        width: x2 - x1,
        deg: this.calculateAngle(x1, y1, x2, y2),
        center: this.item.facial_points.nose_bridge_1
      }
    },
    tools () {
      return [
        {
          icon: this.clear ? 'mdi-eye-outline' : 'mdi-eye-off-outline',
          handle: this.onClear
        },
        {
          icon: 'mdi-plus',
          handle: this.onPlus
        },
        {
          icon: 'mdi-minus',
          handle: this.onMinus
        },
        {
          icon: 'mdi-reload',
          handle: this.onReset
        },
        {
          icon: 'mdi-swap-horizontal',
          handle: this.onChange
        },
        {
          icon: 'mdi-camera-flip-outline',
          handle: this.onRetake
        }
      ]
    },
    coordinate () {
      return {
        left: this.item.facial_points.cheek_left_3,
        right: this.item.facial_points.cheek_right_3,
        bridge: this.item.facial_points.nose_bridge_1
      }
    }
  },
  mounted () {
    this.$nextTick(async () => {
      if (this.isMobile) {
        this.$refs.cover.addEventListener('touchstart', this.onTouchStart)
        this.$refs.cover.addEventListener('touchend', this.onTouchEnd)
        this.$refs.cover.addEventListener('touchmove', this.onTouchMove)
        this.$refs.cover.addEventListener('touchleave', this.onTouchEnd)
      } else {
        this.$refs.cover.addEventListener('mousedown', this.onTouchStart)
        this.$refs.cover.addEventListener('mouseup', this.onTouchEnd)
        this.$refs.cover.addEventListener('mousemove', this.onTouchMove)
        this.$refs.cover.addEventListener('mouseleave', this.onTouchEnd)
      }
      this.canvasCtx = this.$refs.cover.getContext('2d')
      try {
        await this.loadingImg()
        this.onReset()
      } catch (error) {
        this.loading = false
        this.$emit('error', '加载失败')
      }
    })
  },
  beforeDestroy () {
    if (this.isMobile) {
      this.$refs.cover.removeEventListener('touchstart', this.onTouchStart)
      this.$refs.cover.removeEventListener('touchend', this.onTouchEnd)
      this.$refs.cover.removeEventListener('touchmove', this.onTouchMove)
      this.$refs.cover.removeEventListener('touchleave', this.onTouchEnd)
      return
    }
    this.$refs.cover.removeEventListener('mousedown', this.onTouchStart)
    this.$refs.cover.removeEventListener('mouseup', this.onTouchEnd)
    this.$refs.cover.removeEventListener('mousemove', this.onTouchMove)
    this.$refs.cover.removeEventListener('mouseleave', this.onTouchEnd)
  },
  methods: {
    loadingImg () {
      return new Promise((resolve, reject) => {
        this.imgEntity.src = this.chooseItem.pic_url // 替换为您的 PNG 图片路径
        this.imgEntity.onload = () => {
          resolve()
        }
        this.imgEntity.onerror = (error) => {
          reject(error)
        }
      })
    },
    draw () {
      const ctx = this.canvasCtx
      const img = this.imgEntity
      const canvas = this.$refs.cover
      const { x, y, width, height, angle } = this.imgProps
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      ctx.save()
      ctx.translate(x + width / 2, y + height / 2) // 旋转中心点
      ctx.rotate(angle * Math.PI / 180)
      ctx.drawImage(
        img,
        -width / 2, // 左上角 x 坐标
        -height / 2, // 左上角 y 坐标
        width,
        height
      )

      // 绘制描边
      // ctx.strokeStyle = 'red' // 可以根据需要更改颜色
      // ctx.lineWidth = 5 // 设置描边的宽度
      // ctx.strokeRect(-this.imgProps.width / 2, // 左上角 x 坐标
      //   -this.imgProps.height / 2, // 左上角 y 坐标
      //   this.imgProps.width,
      //   this.imgProps.height)

      ctx.restore()
      this.loading = false
    },
    onPlus () {
      if (this.imgProps.scale > 1.4) {
        return
      }
      const RATE = 0.05
      Object.assign(this.imgProps, {
        x: this.imgProps.x - this.imgProps.width * RATE / 2,
        y: this.imgProps.y - this.imgProps.height * RATE / 2,
        scale: this.imgProps.scale + RATE,
        width: this.imgProps.width * (1 + RATE),
        height: this.imgProps.height * (1 + RATE)
      })
      this.draw()
    },
    onMinus () {
      if (this.imgProps.scale < 0.6) {
        return
      }
      const RATE = 0.05
      Object.assign(this.imgProps, {
        x: this.imgProps.x + this.imgProps.width * RATE / 2,
        y: this.imgProps.y + this.imgProps.height * RATE / 2,
        scale: this.imgProps.scale - RATE,
        width: this.imgProps.width * (1 - RATE),
        height: this.imgProps.height * (1 - RATE)
      })
      this.draw()
    },
    // 清屏
    onClear () {
      this.clear = !this.clear
    },
    // 切换脸型
    onChange () {
      this.$emit('feature')
    },
    // 重拍
    onRetake () {
      this.$emit('retake')
    },
    // 重置眼镜
    onReset () {
      this.imgProps.scale = 1
      this.imgProps.angle = this.tryGlassesSize.deg
      this.imgProps.width = this.tryGlassesSize.width
      const { height, width } = this.imgEntity
      this.imgProps.height = this.imgProps.width / width * height
      this.imgProps.x = this.tryGlassesSize.center.x - this.imgProps.width / 2
      this.imgProps.y = this.tryGlassesSize.center.y - this.imgProps.height / 2
      this.draw()
    },
    calculateAngle (x1, y1, x2, y2) {
    // 计算斜率
      const slope = (y2 - y1) / (x2 - x1)

      // 计算弧度
      const radians = Math.atan(slope)

      // 将弧度转换为度
      const degrees = radians * (180 / Math.PI)

      return degrees
    },
    async onSlideChange () {
      if (this.loading) {
        return
      }
      this.loading = true
      this.active = this.$refs.mySwiper.swiper.activeIndex
      await this.loadingImg()
      this.draw()
    },
    onTouchMove (v) {
      if (!this.canMove) {
        return
      }
      const clientX = this.isMobile ? v.touches[0].clientX : v.clientX
      const clientY = this.isMobile ? v.touches[0].clientY : v.clientY
      // 计算点位移动距离
      const moveX = clientX - this.moveObj.startX
      const moveY = clientY - this.moveObj.startY
      // 计算点位移动后的位置
      const left = this.moveObj.left + moveX
      const top = this.moveObj.top + moveY
      // 更新点位位置
      this.imgProps.x = left
      this.imgProps.y = top
      this.draw()
      // this.$refs.cover.style.left = left + 'px'
      // this.$refs.cover.style.top = top + 'px'
    },
    onTouchStart (e) {
      // 获取 Canvas 元素的边界信息
      const rect = this.$refs.cover.getBoundingClientRect()
      let mouseX, mouseY
      // 根据设备类型计算坐标
      if (this.isMobile) {
        mouseX = e.touches[0].clientX - rect.left
        mouseY = e.touches[0].clientY - rect.top
      } else {
        mouseX = e.offsetX
        mouseY = e.offsetY
      }
      if (!this.isMouseOnImage(mouseX, mouseY)) {
        return
      }

      this.canMove = true
      // const { left, top } = this.$refs.content.$el.getBoundingClientRect()
      const startX = this.isMobile ? e.touches[0].clientX : e.clientX
      const startY = this.isMobile ? e.touches[0].clientY : e.clientY

      this.moveObj = {
        startX,
        startY,
        left: this.imgProps.x,
        top: this.imgProps.y
      }
    },
    onTouchEnd (e) {
      this.canMove = false
      Object.assign(this.moveObj, {
        startX: null,
        startY: null,
        left: null,
        top: null
      })
    },
    // 计算点位是否在图片上
    isMouseOnImage (mouseX, mouseY) {
      const { x, y, width, height, angle } = this.imgProps
      // 计算图片中心点坐标
      const centerX = x + width / 2
      const centerY = y + height / 2

      // 将坐标转换为相对于中心点的坐标
      const localX = mouseX - centerX
      const localY = mouseY - centerY

      // 将旋转角度转换为弧度，并计算反向旋转（用于坐标转换）
      const radians = angle * Math.PI / 180
      const cos = Math.cos(-radians) // 反向旋转
      const sin = Math.sin(-radians)

      // 应用旋转矩阵，将坐标转换到未旋转的坐标系
      const rotatedX = localX * cos - localY * sin
      const rotatedY = localX * sin + localY * cos

      // 计算图片未旋转时的边界范围（半宽和半高）
      const halfWidth = width / 2
      const halfHeight = height / 2

      // 判断转换后的坐标是否在图片范围内
      return (
        Math.abs(rotatedX) <= halfWidth &&
        Math.abs(rotatedY) <= halfHeight
      )
    }
  }
}
</script>
<style lang="scss" scoped>
.full {
  width: 100%;
  height: 100%;
}
.item {
  border-radius: 200px;
  height: 200px;
  width: 200px;
  position: relative;
  img {
    width: 100%;
  }
}
.example-3d {
  // background: rgba(0,0,0,.5);
  width: 100%;
  height: 200px;
  padding-top: 50px;
  // padding-bottom: 50px;
  // background: #FFF;
  position: absolute;
  bottom: 0;
}

.swiper {
  height: 100%;
  width: 100%;

  .swiper-slide {
    border-radius: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    width: 200px;
    height: 150px;
    text-align: center;
    font-weight: bold;
    font-size: 14px;
    background-position: center;
    background-size: cover;
    color: #FFF;
    // box-shadow: 0px 0px 8px 4px #888888;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    background-color: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(5px);
    translate: .5s;
    &.active {
      background-color: rgba(255, 255, 255, 1);
      backdrop-filter: blur(20px);
      // box-shadow: 0 4px 6px rgba(0, 0, 0, 0.5);
      // width: 250px;
      // height: 200px;
    }
  }
}
.noMove {
  -webkit-user-drag: none;  /* Safari 和 Chrome */
  -moz-user-drag: none;     /* Firefox */
  -o-user-drag: none;       /* Opera */
  user-drag: none;          /* 非标准 */
}
.content {
  position: relative;
  overflow: hidden;
  .point, .cover {
    position: absolute;
  }
  .point {
    z-index: 1;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: red;
  }

}
.cursor-pointer {
  cursor: pointer;
}

.contentBox {
  position: relative;
  &-desc {
    background-color: rgba(69, 69, 69, .5);
    backdrop-filter: blur(10px);
    position: absolute;
    left: 0;
    top: 0;
    $height: 100px;
    $width: 50px;
    .arrows {
      width: $width;
      height: $height;
      position: absolute;
      top: 50%;
      right: 0;
      margin-top: $height / -2;
      border-radius: 100px 0 0 100px !important;
      box-shadow: inset 5px 0 10px 0px rgba(0, 0, 0, .75);
    }
    &.hide {
      transform: translate(-100%, 0);
      // translate: 3s;
      .arrows {
        height: $height / 2;
        right: -$width;
        border-radius: 0 100px 100px 0 !important;
        box-shadow: 2px 0px 5px 0px rgb(247 247 247);
        background-color: rgba(0, 0, 0, .75);
        backdrop-filter: blur(20px);
      }
    }
  }
  &-tool {
    width: 50px;
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
    right: 20px;
  }
}
</style>
