<template>
  <el-dialog :model-value="modelValue" @update:model-value="onDialogUpdate" :show-close="false"
    :close-on-click-modal="true" align-center append-to-body class="lottery-dialog" @closed="onClosed">
    <div class="lottery-main">
      <div class="lottery-header">
        <h2 class="lottery-title">积分抽奖</h2>
        <p class="lottery-subtitle">顺时针转动高亮 · 停在哪格就领对应奖励</p>
      </div>

      <div class="lottery-grid">
        <template v-for="(item, idx) in gridItems" :key="idx">
          <!-- 中心抽奖按钮 -->
          <div v-if="item.type === 'draw'" class="lottery-cell lottery-cell--draw"
            :class="{ 'is-disabled': isDrawing || !drawable, 'is-drawed': !drawable }" @click="startDraw">
          </div>
          <!-- 普通积分格 -->
          <div v-else class="lottery-cell" :class="{
            'is-active': activeIndex === idx && isDrawing,
            'is-winner': winnerIndex === idx && !isDrawing,
          }">
            <span class="points-value">{{ item.points }}积分</span>
          </div>
        </template>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { computed, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { draw, getPoints } from "@/service/modular/hospital";
import { useRewardResultStore } from "@/stores/rewardResult";
import iconLottery from "@/assets/image/hospital/ponits/icon-lottery-large.svg";

const props = defineProps({
  modelValue: { type: Boolean, default: false },
  // 是否允许抽奖（外部判断是否已抽过等）
  drawable: { type: Boolean, default: true },
  // 批量任务相关（后端字段未确定，使用 props 传入）
  batchGoal: { type: Number, default: 50 },
  batchCurrent: { type: Number, default: 5 },
});

const emit = defineEmits([
  "update:modelValue",
  "success",
  "failed",
  "viewAccount",
]);

const unwrap = (res) => res?.data ?? res ?? {};

const rewardResultStore = useRewardResultStore();

// ============ 网格布局（中心是抽奖按钮） ============
const gridItems = [
  { type: "points", points: 1 },
  { type: "points", points: 2 },
  { type: "points", points: 3 },
  { type: "points", points: 4 },
  { type: "draw" }, // 中心
  { type: "points", points: 5 },
  { type: "points", points: 6 },
  { type: "points", points: 7 },
  { type: "points", points: 8 },
];

// 可抽奖格子的索引（顺时针顺序，不含中心）
const drawableIndices = [0, 1, 2, 5, 8, 7, 6, 3];

const isDrawing = ref(false);
const activeIndex = ref(-1);
const winnerIndex = ref(-1);
const winningPoints = ref(0);

const wait = (ms) => new Promise((r) => setTimeout(r, ms));

// ============ 找到积分对应的格子索引 ============
const findIndexByPoints = (points) => {
  return gridItems.findIndex(
    (item) => item.type === "points" && item.points === points,
  );
};

// ============ 取最新积分（用于结果区进度条） ============
const fetchLatestPoints = async () => {
  try {
    const res = unwrap(await getPoints());
    return Number(res?.totalPoints) || 0;
  } catch (_) {
    return 0;
  }
};

// ============ 开始抽奖 ============
const startDraw = async () => {
  if (isDrawing.value) return;

  if (!props.drawable) {
    ElMessage.info("今日已抽奖,明天再来吧!");
    return;
  }

  // 重置状态
  isDrawing.value = true;
  winnerIndex.value = -1;
  winningPoints.value = 0;
  activeIndex.value = -1;

  // 启动接口请求
  const apiPromise = draw();
  let apiResult = null;
  let apiError = null;
  apiPromise
    .then((r) => {
      apiResult = unwrap(r);
    })
    .catch((e) => {
      apiError = e;
    });

  const startTime = Date.now();
  const MIN_DURATION = 2000; // 至少 2 秒
  let step = 0;

  // ========== 第一阶段：高速循环,至少 2 秒 ==========
  while (Date.now() - startTime < MIN_DURATION) {
    activeIndex.value = drawableIndices[step % drawableIndices.length];
    step++;
    const elapsed = Date.now() - startTime;
    // 渐进减速
    let delay = 70;
    if (elapsed > 600) delay = 100;
    if (elapsed > 1100) delay = 140;
    if (elapsed > 1600) delay = 180;
    await wait(delay);
  }

  // ========== 第二阶段：等待接口 + 慢速循环 ==========
  let waited = 0;
  while (apiResult === null && apiError === null && waited < 3000) {
    activeIndex.value = drawableIndices[step % drawableIndices.length];
    step++;
    waited += 250;
    await wait(250);
  }

  if (apiError || apiResult === null || apiResult === undefined) {
    isDrawing.value = false;
    ElMessage.error(apiError?.message || "抽奖失败");
    emit("failed", apiError);
    return;
  }

  // 解析中奖分数（兼容多种返回结构）
  const points = Number(
    apiResult.points ?? apiResult.score ?? apiResult ?? 0,
  );

  // 找积分对应的格子
  const targetIdx = findIndexByPoints(points);

  // ========== 第三阶段：从当前位置逐步走到目标 ==========
  let safety = 0;
  while (activeIndex.value !== targetIdx && safety < 20) {
    activeIndex.value = drawableIndices[step % drawableIndices.length];
    step++;
    safety++;
    await wait(150);
  }

  // 命中目标
  activeIndex.value = targetIdx;
  winnerIndex.value = targetIdx;
  winningPoints.value = points;

  // 短暂停顿后:关闭抽奖弹窗 -> 打开全局"奖励结果"弹窗
  await wait(500);
  isDrawing.value = false;

  // 取最新积分用于结果区进度条
  const totalPoints = await fetchLatestPoints();

  // 关闭抽奖弹窗,再开全局结果弹窗(放在外面不会被 overflow 隐藏)
  emit("update:modelValue", false);

  // 下一帧再 open 避免和抽奖弹窗关闭动画叠加
  setTimeout(() => {
    rewardResultStore.open({
      title: "恭喜抽中",
      icon: iconLottery,
      points,
      batchGoal: 500,
      batchCurrent: totalPoints,
      rewardName: "康小虎 AI 吉祥物",
    });
  }, 100);

  emit("success", { points });
};

const onDialogUpdate = (val) => {
  if (!val && isDrawing.value) {
    ElMessage.warning("抽奖进行中,请稍候...");
    return;
  }
  emit("update:modelValue", val);
};

const onClosed = () => {
  // 关闭后重置所有状态
  isDrawing.value = false;
  activeIndex.value = -1;
  winnerIndex.value = -1;
  winningPoints.value = 0;
};
</script>

<style lang="scss">
// 顶层 keyframes（不能嵌套）
@keyframes winnerPulse {
  0% {
    transform: scale(0.95);
  }

  50% {
    transform: scale(1.08);
  }

  100% {
    transform: scale(1);
  }
}

/* ============ 所有样式都嵌套在 .lottery-dialog 下 ============ */
.lottery-dialog {
  // ===== 弹窗外壳 =====
  overflow: hidden !important;
  padding: 0 !important;
  width: 638px !important;
  height: 766px !important;
  background: transparent !important;
  box-shadow: none !important;
  transform: scale(0.75) !important;


  .el-dialog__header {
    display: none;
  }

  .el-dialog__body {
    padding: 0;
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }

  // ===== 抽奖网格视图 =====
  .lottery-main {
    padding: 86px 82px 54px 74px;
    width: 100%;
    height: 100%;
    background: url(@/assets/image/hospital/ponits/card-bg-decoration.svg) no-repeat center center;
    background-size: 100% 100%;
  }

  .lottery-header {
    padding: 18px 2px;
    text-align: center;
    margin-bottom: 28px;
    height: 115px;

    .lottery-title {
      font-weight: 900;
      font-size: 38px;
      color: #FF3950;
    }

    .lottery-subtitle {
      font-weight: 400;
      font-size: 19px;
      color: #666666;
    }
  }

  .lottery-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 7px;
  }

  .lottery-cell {
    aspect-ratio: 1 / 1;
    border-radius: 20px;
    background: #FFFFFF;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: bold;
    font-size: 20px;
    color: #1D2129;
    transition: all 0.18s ease;
    user-select: none;

    &.is-active {
      background: url(@/assets/image/hospital/ponits/reward-purple-frame.svg) no-repeat center center;
      background-size: 100% 100%;
      color: #FFFFFF;
      transform: scale(1.04);
    }

    &.is-winner {
      background: url(@/assets/image/hospital/ponits/reward-purple-frame.svg) no-repeat center 10px;
      background-size: 100% 100%;
      color: #FFFFFF;
      animation: winnerPulse 0.6s ease;
    }

    &--draw {
      background: url(@/assets/image/hospital/ponits/reward-fudai-active.svg) no-repeat;
      background-size: 104% 104%;
      background-position: center 3px;

      &:hover:not(.is-disabled) {
        transform: translateY(-2px);
      }

      &.is-disabled {
        cursor: not-allowed;
        transform: none;
      }

      &.is-drawed {
        background: url(@/assets/image/hospital/ponits/reward-fudai-pending.svg) no-repeat;
        background-size: 104% 104%;
        background-position: center 3px;
      }
    }
  }
}
</style>
