<template>
  <page-layer>
    <template #aside>
      <div style="width: 300px;height: 100%;
            background-size: 100% 100%;
            background-repeat: no-repeat;
            background-image: url('http://webhis.thyy.cn:8080/resource/image/happyAside.jpg')">
        <div style="height: 1px"></div>

        <div style="background-color: rgba(255,255,255,0.7); margin: 16px; padding: 2px; border-radius: 8px">
          <div style="margin: 12px 0 12px 10px; font-size: 18px; color: #014841; font-weight: bold">
            奖项设置
            <span class="reset-pool" @click="initLotteryPool">重置为初始状态</span>
          </div>
          <div style="margin-left: 12px">
            <div v-for="item in lotteryPool" :key="item.code">
              <div style="display: flex; line-height: 32px; font-size: 16px">
                <div style="width: 65px; color: black; font-weight: bold">{{ item.name }}：</div>
                <div style="width: 40px; color: #007bd9; font-weight: bold">{{ item.amount }} 份</div>
                <div style="width: calc(100% - 120px); text-align: right">
                  <el-button circle icon="Edit" @click="editRule(item)"></el-button>
                  <el-checkbox v-model="item.showWinner" @change="refreshHistory"
                               style="margin-left: 8px">名单</el-checkbox>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div style="width: 300px; text-align: center; margin-top: 20px">
          <div style="color: white;text-align: left;padding-left: 50px;margin-bottom: 12px">
            <el-checkbox v-model="continuous">连续抽奖</el-checkbox>
          </div>
          <el-button style="width: 200px" size="large" :disabled="duringLottery"
                     type="danger" icon="Star" @click="startLottery">开始抽奖
          </el-button>

          <el-scrollbar ref="wonUserRef" height="510px" style="margin-top: 20px">
            <div v-for="user in historyWonUsers" style="line-height: 30px; font-size: 16px">
              <span style="color: white">{{user.codeRs}} - {{user.name}}：</span>
              <span style="color: white; font-weight: bold">{{user.wonName}}</span>
            </div>
          </el-scrollbar>

        </div>
      </div>
    </template>
    <template #main>
      <div style="position:relative;width: 100%; height: 100%;
        overflow-y: hidden;
        background-size: 100% 100%;
        background-repeat: no-repeat;
        background-image: url('http://webhis.thyy.cn:8080/resource/image/happyNewYear.jpg')">
        <div style="height: 19%;width: 100%;display: flex;align-items: end;
              justify-content: center;color: white;font-size: 56px;font-weight: bold">
          当前奖项：{{ currentLotteryName }}
        </div>
        <div style="height: 60%; width: 100%; display: flex;align-items: center;
              justify-content: center;color: white;font-size: 152px;font-weight: bold">
          <span id="winner-div">{{ currentUserName }}</span>
        </div>
        <div style="position: absolute; top:0;right:0;bottom: 0">
          <canvas id="canvas"></canvas>
        </div>
      </div>
    </template>
  </page-layer>
</template>
<script setup>
import PageLayer from "@/layout/PageLayer.vue";
import {ElMessageBox} from "element-plus";
import {selectLotteryUsers, chooseWinner, recordLotteryResult, selectWonUsers} from "@/api/single-page/lottery";

const continuous = ref(false)
const lotteryPool = ref([])
const lotteryUsers = ref([])
const duringLottery = ref(false)

const winner = reactive({
  index: -1,
  lotteryCode: '',
  userCodeRs: '',
  userName: ''
})

const currentLotteryName = ref('三等奖')
const currentUserName = ref('等待抽奖')

function initLotteryPool() {
  lotteryPool.value = [
    {code: 0, name: '特等奖', amount: 0, round: 0, showWinner: false},
    {code: 1, name: '一等奖', amount: 0, round: 0, showWinner: false},
    {code: 2, name: '二等奖', amount: 0, round: 0, showWinner: false},
    {code: 3, name: '三等奖', amount: 0, round: 0, showWinner: false},
  ]
  localStorage.setItem('lotteryPool', JSON.stringify(lotteryPool.value))
}

let carouselInterval = null

function moveToWinner() {
  let offset = continuous.value ? 1000 : 4500;
  let timer = 0;
  carouselInterval = setInterval(() => {
    timer += 100
    if (timer >= offset) {
      winnerExposed()
      return
    }
    let index = Math.floor(Math.random() * lotteryUsers.value.length);
    let tempUser = lotteryUsers.value[index]
    currentUserName.value = tempUser.codeRs + ' - ' + tempUser.name
    if (tempUser.codeRs === winner.userCodeRs && timer >= offset) {
      winnerExposed()
    }
  }, 100)
}

function winnerExposed() {
  recordLotteryResult(winner).then(() => {
    currentUserName.value = winner.userCodeRs + ' - ' + winner.userName
    duringLottery.value = false;
    clearInterval(carouselInterval)
    refreshHistory()
    startFirework()
    const element = document.getElementById('winner-div')
    element.style.transitionDuration = '.5s'
    element.style.transitionTimingFunction = 'ease-in-out'
    element.style.transformOrigin = 'center center'

    element.style.transform = `scale(1.3, 1.3)`;

    // 完成后重置样式
    setTimeout(() => {
      element.style.removeProperty('transition-duration');
      element.style.removeProperty('transition-timing-function');
      element.style.removeProperty('transform-origin');
      element.style.removeProperty('transform');

      if (continuous.value) {
        setTimeout(() => {
          startLottery()
        }, 400);
      }
    }, 600);
  })

}

function startLottery() {
  duringLottery.value = true
  getWinnableLottery().then(item => {
    chooseWinner(item).then(res => {
      winner.lotteryCode = item.code
      winner.userCodeRs = res.codeRs
      winner.userName = res.name
      moveToWinner()
    })
  }).catch(() => {
    duringLottery.value = false
  })
}

function getWinnableLottery() {
  return new Promise((resolve, reject) => {
    for (let i = lotteryPool.value.length - 1; i >= 0; i--) {
      const item = lotteryPool.value[i]
      if (item.amount === 1) {
        continuous.value = false
      }
      if (item.amount > 0) {
        item.amount -= 1
        item.round += 1
        item.showWinner = true
        currentLotteryName.value = item.name
        localStorage.setItem('lotteryPool', JSON.stringify(lotteryPool.value))
        resolve(item)
        return
      } else {
        item.showWinner = false
      }
    }
    reject()
  })
}

function editRule(item) {
  ElMessageBox.prompt(`设置${item.name}数量：`, '提示', {
    type: "warning",
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    inputPattern: /^100$|^(\d|[1-9]\d)$/,
    inputErrorMessage: '请输入 0至100 的整数',
  }).then(({value}) => {
    item.amount = Number.parseInt(value)
    localStorage.setItem('lotteryPool', JSON.stringify(lotteryPool.value))
  })
}

const historyWonUsers = ref([])
function refreshHistory () {
  const params = []
  lotteryPool.value.forEach(item => {
    if (item.showWinner) {
      params.push(item.code)
    }
  })
  selectWonUsers(params).then(res => {
    historyWonUsers.value = res
    if (res.length > 17) {
      scrollIfExceedLength(res.length - 17)
    }
  })
}

const wonUserRef = ref(null)
let scrollInterval = null

let target = 0;
function scrollIfExceedLength(len) {
  let height = len * 30;
  clearInterval(scrollInterval)
  nextTick(() => {
    const wrap = wonUserRef.value.wrapRef;
    scrollInterval = setInterval(() => {
      target += 1
      if (target > (height + 15)) {
        target = -1
      } else {
        wrap.scrollTop = target
      }
    }, 50)
  })
}

onDeactivated(() => {
  clearInterval(scrollInterval)
})

onMounted(() => {
  let storage = localStorage.getItem('lotteryPool')
  if (storage) {
    lotteryPool.value = JSON.parse(storage);
  } else {
    initLotteryPool()
  }
  selectLotteryUsers().then(res => {
    lotteryUsers.value = res
    initFireworkCanvas()
    refreshHistory()
  })
})


let canvas, canvasContext, w, h, particles = [], probability = 0.04,
    xPoint, yPoint;
const fireworkRunnable = ref(false)

function initFireworkCanvas() {
  canvas = document.getElementById("canvas");
  canvasContext = canvas.getContext("2d");
  resizeCanvas();
}

function resizeCanvas() {
  if (canvas) {
    w = canvas.width = window.innerWidth;
    h = canvas.height = window.innerHeight;
  }
}

function startFirework() {
  fireworkRunnable.value = true
  window.requestAnimationFrame(updateWorld);
  setTimeout(() => {
    fireworkRunnable.value = false
    canvasContext.clearRect(0, 0, canvas.width, canvas.height);
  }, 4000)
}

function updateWorld() {
  if (fireworkRunnable.value) {
    update();
    paint();
    window.requestAnimationFrame(updateWorld);
  }
}

function update() {
  if (particles.length < 500 && Math.random() < probability) {
    createFirework();
  }
  let alive = [];
  for (let i = 0; i < particles.length; i++) {
    if (particles[i].move()) {
      alive.push(particles[i]);
    }
  }
  particles = alive;
  canvasContext.clearRect(0, 0, canvas.width, canvas.height);
}

function paint() {
  canvasContext.globalCompositeOperation = 'source-over';
  canvasContext.fillStyle = "transparent";

  canvasContext.fillRect(0, 0, w, h);
  canvasContext.globalCompositeOperation = 'lighter';
  for (let i = 0; i < particles.length; i++) {
    particles[i].draw(canvasContext);
  }
}

function createFirework() {
  xPoint = Math.random() * (w - 200) + 100;
  yPoint = Math.random() * (h - 200) + 100;
  let nFire = Math.floor(Math.random() * 100) + 100;

  let c1 = 'rgb(255,' + Math.floor((Math.random() * 255)) + ',' + Math.floor((Math.random() * 255)) + ')';
  let c2 = 'rgb(' + Math.floor((Math.random() * 255)) +  ',255,' + Math.floor((Math.random() * 255)) + ')';
  let c3 = 'rgb(' + Math.floor((Math.random() * 255)) + ',' + Math.floor((Math.random() * 255)) + ',255)';
  let c=[c1,c2,c3]

  for (let i = 0; i < nFire; i++) {
    let particle = new Particle();
    particle.color = c[Math.floor(Math.random() * 3)];
    let vy = Math.sqrt(25 - particle.vx * particle.vx);
    if (Math.abs(particle.vy) > vy) {
      particle.vy = particle.vy > 0 ? vy : -vy;
    }
    particles.push(particle);
  }
}

function Particle() {
  this.w = this.h = Math.random() * 6 + 1;
  this.x = xPoint - this.w / 2;
  this.y = yPoint - this.h / 2;
  this.vx = (Math.random() - 0.5) * 10;
  this.vy = (Math.random() - 0.5) * 10;
  this.alpha = Math.random() * .5 + .5;
  this.color = '';
}

Particle.prototype = {
  gravity: 0.05,
  move: function () {
    this.x += this.vx;
    this.vy += this.gravity;
    this.y += this.vy;
    this.alpha -= 0.01;
    return !(this.x <= -this.w || this.x >= screen.width ||
        this.y >= screen.height ||
        this.alpha <= 0);
  },
  draw: function (c) {
    c.save();
    c.beginPath();
    c.translate(this.x + this.w / 2, this.y + this.h / 2);
    c.arc(0, 0, this.w, 0, Math.PI * 2);
    c.fillStyle = this.color;
    c.globalAlpha = this.alpha;
    c.closePath();
    c.fill();
    c.restore();
  }
}


</script>

<style scoped>
:deep(.el-upload-dragger) {
  background-color: transparent;
}

.reset-pool {
  color: red;
  font-size: 12px
}
.reset-pool:hover {
  cursor: pointer;
  text-decoration: underline;
}

.show-history {
  color: #c2c2c2;
}
.show-history:hover {
  cursor: pointer;
  text-decoration: underline;
}

:deep(.el-checkbox) {
  color: white;
}
</style>