<template>
  <view class="rive-ani" id="rive-ani" v-if="state.comVisable" >

    <view class="coin-max-tip"  v-if="state.maxTipVisible" :style="{backgroundImage: `url(${staticImg.blockRect})`, top: navbarInfo.top}" >
      已达上限
    </view>

    <view class="coin-total" :style="{top: navbarInfo.top }" >
      <span>{{wisdomCoinStore.total || 0}}</span>
      <view class="coin-logo" id="coin-logo" :animation="state.heartbeatAni" >
        <img :src="staticImg.coinTotal" alt="">
      </view>
    </view>
    <view class="coin-ani" id="coin-ani" v-if="state.visible"  >
        <view
          class="coin-item"
          v-for="item in state.cointCount" 
          :key="item"
          :animation="state.animation[item - 1]"
          :id="`coin-item-${item}`"
        >
          <img  :src="staticImg.coinAni" alt=""   >
        </view>
      <view class="coin-count" id="coin-count"   >+ {{state.cointCount}}</view>
    </view>
  </view>
</template>


<script setup lang="ts" name="rive " >
import { onMounted, ref, reactive, getCurrentInstance, defineExpose, nextTick} from 'vue'
import { Rive } from "@rive-app/canvas"
import { useStaticImg, useQueryElInfo, useSchedulerOnce, useNavbarInfo } from '@/hooks/index'
import { useWisdomCoinStore } from '@/store'
import { AudioController } from '@/controller/AudioController';

enum AniEnum {
  'one',
  'two',
  'three',
  'four',
  'five',
  'six'
}

/**
 * 动画逻辑
 * 1. 得几颗星就控制rive动画给几颗星
 * 2. 然后rive动画渐隐
 * 3. 出现金币 +n 的字样
 * 4. 金币飞到右上角金币框
 */
interface State {
  rive: Rive,
  animation: any,
  visible: boolean,
  heartbeatAni: any,
  cointCount: number,
  comVisable: boolean,
  cardType: 0 | 1,
  maxTipVisible: boolean
}

const state = reactive<Partial<State>>({
  animation: [],
  visible: false,
  heartbeatAni: null,
  cointCount: 0,
  comVisable: false,
  cardType: 0,
  maxTipVisible: false
})

const staticImg = useStaticImg()

const wisdomCoinStore = useWisdomCoinStore()

const navbarInfo = useNavbarInfo()

const coinLoginRef = ref()

let rive: Rive

let _resolve: any

const initHeartbeatAni = () => {

  var animation = uni.createAnimation({
    timingFunction: "linear",
    transformOrigin: "0% 0%"
  });

  return animation.scale(1.1, 1.1).step({duration: 100}).scale(1, 1).step({duration: 100}).export()

}

// 1. 初始化rive动画
const initRive = () => {

  const canvas = document.createElement('canvas')
  // const scale = window.devicePixelRatio;
  const scale = 1;

  canvas.width = 375 * scale;
  canvas.height = 375 * scale;
  
  canvas.id = 'rive-canvas'

  canvas.style.position = 'absolute'
  
  document.getElementById('rive-ani')?.appendChild(canvas)
  
  rive = new Rive({
    src: "https://res-game.luojigou.vip/coin1234.riv",
    canvas: canvas,
    autoplay: false,
    stateMachines: "bumpy",
    artboard: state.cardType === 0 ? 'si-xing' : 'six-xing',
    onLoad: () => {
      
      rive.resizeToCanvas()

      console.log(rive);

      rive.play(AniEnum[state.cointCount! - 1])
      
      for (let i = 0; i < state.cointCount!; i++) {
       
        useSchedulerOnce( () => {
          AudioController.playCoinLight()
        }, 1200 + i * 100)

      }
    
      
    },
    onStop: () => {
      fadeOutRive()
      useSchedulerOnce(() => {
        state.visible = true
        useSchedulerOnce(() => document.getElementById('coin-count')!.style.display = 'none', 1200)
        useSchedulerOnce(() => goBezier(), 1400)
      }, 1000)
      
    }
  });

}

const createAnimationStep = (animation: UniApp.Animation, count: number) => {

  for (let i = 0; i < count; i++) {
    state.animation.push(animation.step({duration: 400 + i * 200}).export())
    useSchedulerOnce(() => {
      if (wisdomCoinStore.remainderWisdomCoin <= 0) {
        state.maxTipVisible = true
      } else {
        wisdomCoinStore.total ++
        wisdomCoinStore.remainderWisdomCoin--
      }
      
      document.getElementById(`coin-item-${i + 1}`)!.style.display = 'none'
      state.heartbeatAni = initHeartbeatAni()
    }, 400 + i * 200)
  }

}

// 2. rive动画渐隐消失
const fadeOutRive = () => {
  const riveCanvas = document.getElementById('rive-canvas')!
  riveCanvas.style.opacity = '0'
  riveCanvas.style.transition = '1s'
}

const goBezier = () => {
  
  var animation = uni.createAnimation({
    timingFunction: "linear",
    transformOrigin: "0% 0%"
  });

  animation
  .top(coinLoginRef.value.top )
  .left(coinLoginRef.value.left)
  .scale(0.25, 0.25)

  createAnimationStep(animation, state.cointCount!)

  useSchedulerOnce(() => {
    _resolve()
    state.comVisable = false
    state.visible = false
    document.getElementById('coin-count')!.style.display = 'block'
  }, 1200 + state.cointCount! * 600)

}

const start = async (starCount: number, cardType: 0 | 1) => {

  state.comVisable = true
  state.cointCount = starCount
  state.cardType = cardType

  if (cardType === 0) {
    starCount <= 2 ? AudioController.playFail() : AudioController.playPass()
  } else {
    starCount <= 3 ? AudioController.playFail() : AudioController.playPass()
  }

  useSchedulerOnce(initRive)


  if (wisdomCoinStore.remainderWisdomCoin == 0) {
    state.maxTipVisible = true
  }


  
  nextTick(() => useQueryElInfo('#coin-logo', (res) => coinLoginRef.value = res, getCurrentInstance()!, false))

  return new Promise((resolve) => {
    _resolve = resolve
  })

}

defineExpose({
  start: start
})

onMounted(() => {

})



</script>


<style lang="less" scoped >
.rive-ani {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 200;
  background-color: rgba(0,0,0, .6);
  display: flex;
  align-items: center;
  justify-content: center;
  .coin-max-tip {
    width: 88px;
    height: 33px;
    background-size: 100%;
    position: absolute;
    right: 120px;
    display: flex;
    align-items: center;
    background-repeat: no-repeat;
    font-size: 14px;
    font-family: PingFangSC-Semibold, PingFang SC;
    font-weight: 600;
    color: #FEFBFB;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 2px;
  }
  .coin-total {
    height: 36px;
    background: #414141;
    border-radius: 19px;
    position: absolute;
    right: 26px;
    display: flex;
    align-items: center;
    padding: 0 8px;
    box-sizing: border-box;
    .coin-logo {
      margin-left: 6px;
      img {
        width: 20px;
        height: 20px;
        display: block;
      }
    }
    
    span {
      font-size: 18px;
      font-family: PingFangSC-Semibold, PingFang SC;
      font-weight: 600;
      color: #FEFBFB;
      
      display: block;
    }
  }
  .coin-ani {
    width: 100vw;
    height: 100vh;
    position: absolute;
    top: 0%;
    left: 0%;
    display: flex;
    align-items: center;
    justify-content: center;
    .coin-item {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      animation: jelly 0.5s;
      transform-origin: top center;
    }
    @keyframes jelly {
      0% {
        scale: 0;
      }
      100% {
        scale: 1;
      }      
    }
    img {
      width: 152rpx;
      height: 152rpx;
    }
    .coin-count {
      font-size: 56rpx;
      font-family: PingFangSC-Semibold, PingFang SC;
      font-weight: 600;
      color: #FF8024;
      margin-left: 250rpx;
      margin-bottom: 20rpx;
    }
  }
}

.uni-canvas-canvas {
  width: 1000px !important;
}

</style>