<template>
  <view class="luojigou-board" >
    <view class="board" :style="{scale: adaptatio, transformOrigin: '50% 0%'}" >
      <image class="board-img" :src="boardUrl" />
      <view class="board-header" id="game-label">
        <view class="trumpt" @click="emits('playAudio')">
          <image class="dog" :src="staticImg.trumptDog"   />
          <image
            class="trumpt-icon"
            :src="props.playLoading ? staticImg.trumptGif : staticImg.trumptPng" 
          />
        </view>
        <view class="tip ">
          <scroll-view
            scroll-y
            :style="{height: '72rpx'}"
          >
            {{props.cardDesc ? props.cardDesc : "加載中"}}
          </scroll-view>
        </view>
      </view>
      <view  class="card" >
          <view class="ques" ref="quesRef" id="quesRef" >
            <image :src="props.board.quesUrl" alt="" />
          </view>
          <view class="ans" ref="ansRef" id="ansRef">
            <image :src="props.board.ansUrl" alt="" />
          </view>
      </view>

    </view>

    <view
      class="mark-button" 
      :style="{ 
        width: 357 * rate + 'rpx', 
        height: 466 * rate + 'rpx', 
        top: 102 * rate + 'rpx',
        left: '50%', transform: 'translateX(-50%)'
     }" 
    >
      <view
        v-for="item in props.board.buttons"
        class="movable-image" 
        :style="{
          willChange: 'transform', 
          top: Number(item.y) * rate + 'rpx', 
          left: Number(item.x) * rate + 'rpx',
          width: 46 * rate + 'rpx', 
          height: 46 * rate + 'rpx',
          backgroundColor: item.color,
          borderRadius: '50%'
        }"  
      />
    </view>

    <movable-area 
      v-if="props.cardType !== undefined" 
      class="movable-area" 
      id="movableAreaRef" 
      :style="{ 
        width: 357 * rate + 'rpx', 
        height: 466 * rate + 'rpx',
        top: 102 * rate + 'rpx', 
        left: '50%', 
        transform: 'translateX(-50%)'
      }"
    >
      <movable-view
        v-for="item in buttons"
        :key="item.id"
        :disabled="state.disabled"
        :x="item.x"
        :y="item.y"
        damping="100"
        direction="all"
        class="movable-view"
        :style="{
          zIndex: item.zIndex, 
          width: 46 * rate + 'rpx', 
          height: 46 * rate + 'rpx',
        }"
        @touchend="touchend($event, item)"
        @touchstart="touchStart(item)"
      >
        <image 
          :id="`rock-id-${item.id}`"
          :class="`movable-image `" 
          :style="{willChange: 'transform', transformOrigin: `center bottom`}"  
          :src="item.url" 
        />
        
        <image
          v-if="item.ans"
          class="success-flag"
          :src="staticImg.successFlag"
        />
      </movable-view>
    </movable-area>
  </view>
</template>


<script setup lang="ts" name="luojigou-board" >
import { defineProps, reactive, ref, computed, getCurrentInstance, defineEmits } from 'vue'
import { useStaticImg, useSchedulerOnce, useQueryElInfo, useAdaptationIpadAndPhone } from '@/hooks/index'
import type { CardModeEnum } from '@/enum/constant';
import { useCalcStartStore, useCalcQuantityStore } from '@/store/index';

interface Buttons {
  id: number,
  x: number,
  y: number,
  initX: number,
  initY: number,
  url: string,
  color: API.Color,
  index: number,
  zIndex: number,
  ans: API.Color | null
}

interface IProps {
  cardType: 0 | 1, // 0 四钮题卡 | 1 六钮题卡
  board: API.Board,
  mode: CardModeEnum,
  cardDesc: string,
  playLoading: boolean,
  getExpose: (records: any) => void
}

const staticImg = useStaticImg()

const calcStartStore = useCalcStartStore()

const adaptatio = useAdaptationIpadAndPhone()

const calcQuantityStore = useCalcQuantityStore()

const props = defineProps<IProps>()

const emits = defineEmits(['playAudio', 'submit'])

const state = reactive({
  zIndex: 0, // 暂存zIndex
  disabled: false, // 是否禁用moveview
  correctQuantity: 0, // 正确数量（）
  totalQuantity: 0 // 总数量 （移动按钮数量)
})


const boardUrl = props.cardType == 1 ? staticImg.boardSix : staticImg.boardFour

calcStartStore.total = props.cardType == 1 ? 6 : 4

const ansRef = ref<UniApp.NodeInfo>()
const quesRef = ref<UniApp.NodeInfo>()
const movableAreaRef = ref<UniApp.NodeInfo>()

useQueryElInfo('#quesRef', (nodeInfo) => quesRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)
useQueryElInfo('#ansRef', (nodeInfo) => ansRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)
useQueryElInfo('#movableAreaRef', (nodeInfo) => movableAreaRef.value = nodeInfo as UniApp.NodeInfo, getCurrentInstance()!)

const baseRatio = adaptatio

const rate = baseRatio * 2

const { windowWidth, windowHeight } = uni.getSystemInfoSync()

const unit = windowWidth / windowHeight > 0.6 ? 1 : 0.5

const ansItemHeight = computed(() => Math.floor(ansRef.value?.height! / copies))

const TPos = (x: number, y: number) => {
  
  return { x: x - movableAreaRef.value?.left! - 23 * rate * unit , y: y - movableAreaRef.value?.top! - 23 * rate * unit }
  
}

const getButtonIndex = (_y: number) =>  Math.floor(_y / ansItemHeight.value)

const getButtonPosByIndex = (index: number) => {

  const x = ansRef.value?.width! + quesRef.value?.width! 
 
  const y = ansItemHeight.value * index + ansItemHeight.value / 2 - 23 * rate * unit

  return { x, y }
}

// 几钮模板
const copies = props.cardType === 0 ? 4 : 6

const VSpace = props.cardType === 0 ? 23 * rate * unit + 46 * rate * unit : 6 * rate * unit + 46 * rate * unit

const Y = 435 * rate

const getX = (index: number) => index * VSpace + 13 * rate * unit

// 注意一下四钮 用哪几个颜色的按钮
let buttons = reactive<Buttons[]>([
  {id: 0, ans: null, x: getX(0), y: Y * rate, initX: getX(0), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.red, color: 'red' },
  {id: 1, ans: null, x: getX(1), y: Y * rate, initX: getX(1), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.blue, color: 'blue' },
  {id: 2, ans: null, x: getX(2), y: Y * rate, initX: getX(2), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.green, color: 'green' },
  {id: 3, ans: null, x: getX(3), y: Y * rate, initX: getX(3), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.orange, color: 'orange' },
  {id: 4, ans: null, x: getX(4), y: Y * rate, initX: getX(4), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.yellow, color: "yellow" },
  {id: 5, ans: null, x: getX(5), y: Y * rate, initX: getX(5), initY: Y * rate,  zIndex: 0, index: -1, url: staticImg.purple, color: 'purple' },
])

buttons.splice(props.cardType == 1 ?  buttons.length : buttons.length - 2, buttons.length)

// 让按钮回到原位
const disPatchButtonGoInitPos = (index: number) => {
    
  useSchedulerOnce(() => {
    buttons[index].x = buttons[index].initX + Math.random()
    buttons[index].y = buttons[index].initY + Math.random()
    buttons[index].index = -1
    buttons[index].ans = null
  })

  useSchedulerOnce(() => {
    state.disabled = false
  }, 200)

}

const touchStart = (item: Buttons) => {
  useSchedulerOnce(() => {
    state.zIndex ++
    item.zIndex = state.zIndex
  })
}

// 按钮脱手
const touchend = (ev: TouchEvent, item: Buttons) => {

  if (state.disabled) return

  const { x: itemX, y: itemY } = TPos(ev.changedTouches[0].pageX, ev.changedTouches[0].pageY)

  console.log("itemY:", itemY);
  

  // 返回原点 (没有放在答案区， 按钮回到初始位置)
  if (itemX < quesRef.value?.width! || itemY > ansRef.value?.height! ) {
    disPatchButtonGoInitPos(item.id)
  } else  {
  
    const index = getButtonIndex(itemY)

    console.log('index:', index);
    
    
    const { x: targetX, y: targetY } = getButtonPosByIndex(index)
    
    //  直接点击答案区的按钮，答案区按钮回到初始位置
    if (item.x == targetX && item.y == targetY) {
      disPatchButtonGoInitPos(item.id)
    } else {

      // 两个按钮都在答案区， 直接进行按钮之间的交换
      const isHasIndex = buttons.findIndex(button => button.index == index && button.id !== item.id ) 
      
      if (isHasIndex >= 0) { // 答案区的目标区域存在按钮
     
        if (item.index == -1) { // 答案区的目标区域存在按钮 操作按钮是从待操作区域移过来的 目标按钮回到原位
          disPatchButtonGoInitPos(isHasIndex)
        } else {  // 答案区的目标区域存在按钮 操作按钮是和目标按钮互换位置
          useSchedulerOnce(() => {
            const oldPos = getButtonPosByIndex(item.index)
            buttons[isHasIndex].x = oldPos.x
            buttons[isHasIndex].y = oldPos.y
            buttons[isHasIndex].index = item.index
          })
        }
      }

      // 将按钮放置到答案区对应的位置
      useSchedulerOnce(() => {
        item.x = targetX
        item.y = targetY
        item.index = index
      })

      checkAns(index, item)

    }
  }
}

// 判断答案 (学习计划适用逻辑)
const checkAns = (index: number, itemData: Buttons) => {
  const targetData = props.board.ansList
  console.log(targetData, index, itemData);
  
  // 移动到了正确位置
  if (targetData[index].color === itemData.color) {
    itemData.ans = targetData[index].color
    calcQuantityStore.correctQuantity++
  } else { // 移动到了錯誤位置

    calcStartStore.wrongCount++

    itemData.ans = null

    const rockNode = document.getElementById(`rock-id-${itemData.id}`)

    rockNode?.classList.add('rock-button-ani')

    state.disabled = true

    useSchedulerOnce(() => {
      disPatchButtonGoInitPos(itemData.id)
      
      rockNode?.classList.remove('rock-button-ani')
    }, 1000)
  }
  
  calcQuantityStore.totalQuantity++

  // 全部正确后触发提交答案的emit

  const ansLen = buttons.filter( button => button.ans).length

  if ( ansLen === ( props.cardType === 0 ? 4 : 6 )) {
    emits('submit')
  }
}

</script>

<style lang="less" scoped >
.luojigou-board {
  width: 714rpx;
  height: 1234rpx;
  position: relative;
  display: flex;
  justify-content: center;
  .board {
      width: 714rpx;
      height: 1234rpx;
      position: relative;
      .board-img {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
      }
      .board-header {
        width: 100%;
        height: 148rpx;
        position: relative;
        top: 7rpx;
        z-index: 12;
        .trumpt {
          width: 96rpx;
          height: 96rpx;
          position: relative;
          top: 44rpx;
          left: 54rpx;
          .dog {
            width: 96rpx;
            height: 96rpx;
            position: absolute;
            z-index: 1;
          }
          .trumpt-icon {
            width: 40rpx;
            height: 40rpx;
            position: absolute;
            z-index: 2;
            right: -12rpx;
            bottom: -6rpx;
          }
        }
        .tip {
          width: 490rpx;
          height: 72rpx;
          font-size: 24rpx;
          font-family: PingFangSC-Medium, PingFang SC;
          font-weight: 500;
          color: #ffffff;
          position: absolute;
          top: 50rpx;
          left: 176rpx;
        }
      }
      .card {
        width: 606rpx;
        height: 772rpx;
        border-radius: 40rpx;
        overflow: hidden;
        display: flex;
        justify-content: space-between;
        position: absolute;
        top: 206rpx;
        left: 26rpx;
        z-index: 2;
      }
      .ques {
        width: 450rpx;
        height: 772rpx;
        border-right: 2rpx solid #006CAA;
        image {
          width: 100%;
          height: 100%;
          display: block;
        }
      }
      .ans {
        width: 170rpx;
        height: 100%;
        display: flex;
        flex-direction: column;
        border-top-right-radius: 40rpx;
        border-bottom-right-radius: 40rpx;
        overflow: hidden;
        background-color: #fff;
        image {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
      }

      .ans .ans-item:last-child {
        border-bottom: none
      }
      .buttons {
        position: relative;
        top: 200rpx;
        left: 20rpx;
        width: 680rpx;
        height: 1000rpx;
        image {
          position: absolute;
          left: 0;
          top: 0;
        }
      }
  }


  .mark-button {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    .movable-image {
      position: absolute;
      width: 92rpx;
      height: 92rpx;
      display: block;
    }
  }
  

  .movable-area {
    width: 714rpx;
    height: 984rpx;
    background-color: transparent;
    position: absolute;
    top: 192rpx;
    left: 50%;
    transform: translateX(-50%);
    touch-action: none;
    left: 0px;
    z-index: 30;
    -moz-transform: none;
    -webkit-transform: none;
    -o-transform: none;
    -ms-transform: none;
    transform: none;
    .movable-view {
      width: 92rpx;
      height: 92rpx;
      touch-action: none;
      .movable-image {
        width: 100%;
        height: 100%;
        transition: width 0.2s;
        z-index: 1;
      }
      
      .success-flag {
        width: 36rpx;
        height: 26rpx;
        display: block;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        z-index: 2;
      }
    }
  }

  .opra {
    width: 100vw;
    height: 1216rpx;
    background: url('../../assets/boardBg.png');
    display: flex;
    justify-content: center;
    padding-top: 46rpx;
  }
}


.rock-button-ani {
  animation: rock 1s;
}

@keyframes rock {
  0% {
    rotate: 0deg;
  }
  25% {
   
    rotate: -10deg;
  }
  50% {
    rotate: 10deg;
  }
  75% {
    rotate: -10deg;
  }
  100% {
    rotate: 0deg;
  }
}

</style>