<script setup>
import { ref, computed, onBeforeUnmount } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue";
import Avatar from "@/components/Avatar.vue";
import UserUpgrade from "@/components/UserUpgrade.vue";
import { getBattleAPI, getRoomAPI } from "@/apis";
import { getBattleResultTips } from "@/constants";
import audioManager from "@/audioManager";
import useStore from "@/store";
import { storeToRefs } from "pinia";

const store = useStore();
const { user } = storeToRefs(store);
/** 通过 store action 获取段位名称（rank_lvl → 显示文字） */
const { getLvlName } = store;

/** 结算图片资源 CDN 前缀 */
const RESULT_CDN = "https://static.shelingxingqiu.com/shootmini/static/friend-battle-result";

// ---- 数据状态 ----
/** 当前用户是否属于胜利方 */
const ifWin = ref(false);
/** 后端返回的对战数据 */
const data = ref({});
/** 进场覆盖动效层是否显示 */
const showOverlay = ref(false);
/** 自动关闭覆盖层的计时器 */
const overlayTimer = ref(null);
/** 控制经验条是否执行进场动画（弹窗关闭后才置 true，避免动画被遮挡） */
const showExpAnim = ref(false);

// ---- 经验进度条数据（onLoad 中从 teams.players 解析填充）----
/** 本局获得的经验值 */
const expGained = ref(0);
/** 对战结束后当前经验进度值 */
const expCurrent = ref(0);
/** 升级到下一级所需的总经验（兜底 100，防止分母为 0） */
const expTotal = ref(100);
/** 用户当前等级 */
const userLvl = ref(0);

// ---- 计算属性 ----

/**
 * 计算当前用户所在队伍编号
 * @returns {number} 1=蓝队，2=红队
 */
const myTeam = computed(() => {
  const teams = data.value.teams;
  if (teams && teams[1]) {
    if (teams[1].players.some((p) => p.id === user.value.id)) return 1;
  }
  return 2;
});

/** 蓝队（队伍1）玩家列表 */
const blueTeamPlayers = computed(() => data.value.teams?.[1]?.players || []);

/** 红队（队伍2）玩家列表 */
const redTeamPlayers = computed(() => data.value.teams?.[2]?.players || []);

/**
 * 蓝队得分（直接取队伍级 score 字段，与 team-battle.vue 保持一致）
 */
const blueScore = computed(() => data.value.teams?.[1]?.score ?? 0);

/**
 * 红队得分（直接取队伍级 score 字段）
 */
const redScore = computed(() => data.value.teams?.[2]?.score ?? 0);

/**
 * MVP 玩家对象（仅 mode=2/3 时有值）
 * 兼容 mvp 为对象或数组两种格式
 */
const mvpPlayer = computed(() => {
  if (data.value.mode > 1) {
    const mvp = data.value.mvp;
    if (mvp && mvp.id) return mvp;
    if (Array.isArray(mvp) && mvp.length) return mvp[0];
  }
  return null;
});

/**
 * MVP 玩家所在队伍编号（1=蓝队，2=红队）
 * 通过比对 mvpPlayer.id 与 blueTeamPlayers 确定，用于选择背景图（mvp-blue / mvp-red）
 */
const mvpTeam = computed(() => {
  if (!mvpPlayer.value) return 0;
  return blueTeamPlayers.value.some((p) => p.id === mvpPlayer.value.id) ? 1 : 2;
});

/**
 * 激励语图片 URL（在 onLoad 中确定 ifWin 后赋值，避免 Math.random 放在 computed 里产生缓存不一致问题）
 */
const tipImage = ref("");

/**
 * 经验进度条宽度百分比（0~100）
 */
const expPercent = computed(() =>
  Math.min((expCurrent.value / expTotal.value) * 100, 100)
);

/**
 * 是否为大乱斗模式（mode > 3）
 */
const isMeleeMode = computed(() => data.value.mode > 3);

/**
 * 大乱斗排行榜列表（从接口 teams["0"].players + resultList 构建）
 * - 以 teams["0"].players 为全量玩家基础（包含未射击的玩家）
 * - 从 resultList 中按 userId 匹配获取得分；未命中则 totalRing 为 0
 * - 按 totalRing 降序排列后注入 rank
 * @returns {{ id, rank, avatar, name, lvlName, totalRing, isSelf }[]}
 */
const meleeRankList = computed(() => {
  const resultList = data.value.resultList || [];
  const teamPlayers = data.value.teams?.[0]?.players || [];
  if (!teamPlayers.length) return [];

  // 以 players 为基础，merge resultList 得分数据
  const list = teamPlayers.map((p) => {
    const resultItem = resultList.find((r) => r.userId === p.id) || {};
    return {
      id: p.id,
      avatar: p.avatar || "",
      name: p.name || "",
      // rank_lvl 字段可能缺失，缺失时显示空字符串，避免 getLvlName(undefined) 返回错误段位名
      lvlName: p.rank_lvl != null ? getLvlName(p.rank_lvl) : "",
      totalRing: resultItem.totalRing ?? 0,
      isSelf: String(p.id) === String(user.value.id),
    };
  });

  // 按总环数降序排列，环数相同时按 id 升序保证顺序稳定
  list.sort((a, b) => b.totalRing - a.totalRing || a.id - b.id);

  // 注入名次（从1开始）
  return list.map((item, index) => ({ ...item, rank: index + 1 }));
});

/**
 * 获取前三名行背景装饰 SVG 路径
 * @param {number} rank 名次（1/2/3）
 * @returns {string} 静态资源路径
 */
function getMeleeRankBgSrc(rank) {
  const names = ["one", "two", "three"];
  return `../static/friend-battle-result/rank-${names[rank - 1]}.svg`;
}

/**
 * 获取前三名头像光环颜色
 * @param {number} rank 名次（1=金,2=银,3=铜）
 * @returns {string|undefined} 边框颜色，4+名返回 undefined
 */
function getMeleeAvatarBorderColor(rank) {
  const colors = ['#FFD947', '#D2D2D2', '#FFA515'];
  return colors[rank - 1];
}

// ---- 生命周期 ----

onLoad(async (options) => {
  if (!options.battleId) return;

  const result = await getBattleAPI(options.battleId);
  data.value = result;

  // 从 teams 各队伍的 players 中找到当前用户，解析经验进度条所需字段
  // 后端字段：exp（本局经验）/ currentExp（当前经验）/ upgradeExp（升级所需经验）/ level（当前等级）
  const myIdStr = String(user.value.id);
  for (const team of Object.values(result.teams || {})) {
    const p = (team.players || []).find((pl) => String(pl.id) === myIdStr);
    if (p) {
      expGained.value  = p.exp         ?? 0;
      expCurrent.value = p.currentExp  ?? 0;
      expTotal.value   = p.upgradeExp  ?? 100;
      userLvl.value    = p.level       ?? 0;
      break;
    }
  }

  // 判断当前用户是否在胜利队伍中
  // 优先使用接口返回的 winTeam 字段；若缺失则以队伍得分高低作为兜底判断
  const myId = String(user.value.id);
  if (result.winTeam != null && result.teams) {
    // 使用 String() 类型统一，防止后端返回字符串 ID 与 store 中数字 ID 严格不等
    const winPlayers = result.teams[result.winTeam]?.players || [];
    ifWin.value = winPlayers.some((p) => String(p.id) === myId);
  } else if (result.teams) {
    // 兜底：winTeam 未返回时，比较双方分数；当前用户所在队分数 >= 对方则视为胜利
    const team1Players = result.teams[1]?.players || [];
    const inTeam1 = team1Players.some((p) => String(p.id) === myId);
    const score1 = result.teams[1]?.score ?? 0;
    const score2 = result.teams[2]?.score ?? 0;
    ifWin.value = inTeam1 ? score1 > score2 : score2 > score1;
  }

  // 确保 ifWin 已定后再生成激励语图片，防止 Math.random 在 computed 缓存时用到旧的 ifWin 值
  tipImage.value = getBattleResultTips(result.way, result.mode, { win: ifWin.value });

  // 播放胜利/失败音效
  if (result.mode <= 3) {
    audioManager.play(ifWin.value ? "胜利" : "失败");
  }

  // 数据加载完成后延迟 1 秒再显示激励弹窗，避免进场时画面太杂
  setTimeout(() => {
    showOverlay.value = true;
    // 弹窗显示后 2.5 秒自动关闭
    overlayTimer.value = setTimeout(() => {
      closeOverlay();
    }, 2500);
  }, 1000);
});

onBeforeUnmount(() => {
  if (overlayTimer.value) clearTimeout(overlayTimer.value);
});

// ---- 方法 ----

/**
 * 关闭进场覆盖动效层（点击任意位置或超时均可触发）
 */
function closeOverlay() {
  showOverlay.value = false;
  if (overlayTimer.value) {
    clearTimeout(overlayTimer.value);
    overlayTimer.value = null;
  }
  // 弹窗关闭后启动经验条进场动画
  showExpAnim.value = true;
}

/**
 * 底部按钮文案：好友约战显示“返回房间”，排位赛等其他模式显示“返回”
 */
const exitBtnText = computed(() => data.value.way === 1 ? '返回房间' : '返回');

/**
 * 点击底部按钮跳转
 * - 好友约战（way=1）：先调接口确认用户仍在房间
 *   - 已被踢出或房间不存在 → toast 提示并 reLaunch 到首页
 *   - 仍在房间 → 跳回对战房间
 * - 其他模式（排位赛等）：跳转到排位赛首页
 */
async function exit() {
  if (data.value.way === 1) {
    try {
      const roomInfo = await getRoomAPI(data.value.roomId);
      const members = roomInfo?.members || [];
      const myIdStr = String(user.value.id);
      // 判断当前用户是否仍在房间成员列表中
      const stillInRoom = members.some(
        (m) => String(m.userInfo?.id) === myIdStr
      );
      if (!stillInRoom) {
        uni.showToast({ title: '您已经不在当前房间', icon: 'none' });
        setTimeout(() => {
          uni.reLaunch({ url: '/pages/index' });
        }, 1500);
        return;
      }
    } catch {
      // 接口异常（如房间已解散）同样视为已不在房间
      uni.showToast({ title: '您已经离开了房间', icon: 'none' });
      setTimeout(() => {
        uni.reLaunch({ url: '/pages/index' });
      }, 1500);
      return;
    }
    uni.redirectTo({
      url: `/pages/battle-room?roomNumber=${data.value.roomId}&fromResult=1`,
    });
  } else {
    uni.redirectTo({
      url: '/pages/ranking',
    });
  }
}

/**
 * 跳转到完整弓箭数据页（match-detail）
 */
function checkBowData() {
  uni.navigateTo({
    url: `/pages/match-detail?battleId=${data.value.matchId}`,
  });
}

/**
 * 点击导航栏返回按钮
 */
function goBack() {
  uni.navigateBack();
}
</script>

<template>
  <view class="page">
    <!-- ===== 主体可滚动内容区（由 Container 接管）===== -->
    <Container
      :bgType="data.mode > 3 ? -1 : 0"
      bgColor="#000000"
      :onBack="goBack"
    >

      <!-- ----- Banner 区：game 胜负展示图（仅 NvN 对抗模式）----- -->
      <view v-if="!isMeleeMode" class="banner-section">
        <!-- 根据胜负动态展示 game-win / game-lose（切图尺寸不同，用 style 分别设宽和叠层距） -->
        <image
          class="banner-result scale-in"
          :src="ifWin ? `${RESULT_CDN}/game-win.png` : `${RESULT_CDN}/game-lose.png`"
          :style="ifWin
            ? { width: '362rpx', marginBottom: '-32rpx' }
            : { width: '378rpx', marginBottom: '-40rpx' }"
          mode="widthFix"
        />
      </view>

      <!-- ----- VS 对战信息区（仅 NvN 对抗模式）----- -->
      <view v-if="!isMeleeMode" class="vs-section">
        <!-- 红蓝背景切图 -->
        <image class="vs-bg-img" :src="`${RESULT_CDN}/vs-bg.png`" mode="aspectFill" />

        <!-- 双方玩家头像行 -->
        <view class="vs-players-row">
          <!-- 蓝队 -->
          <view class="team-players team-players-blue">
            <view v-for="p in blueTeamPlayers" :key="p.id" class="player-item">
              <Avatar :src="p.avatar" :size="34" borderColor="#8FB4FD" />
              <text class="player-name player-name-blue">{{ p.name }}</text>
            </view>
          </view>

          <!-- 红队 -->
          <view class="team-players team-players-red">
            <view v-for="p in redTeamPlayers" :key="p.id" class="player-item">
              <Avatar :src="p.avatar" :size="34" borderColor="#E67470" />
              <text class="player-name player-name-red">{{ p.name }}</text>
            </view>
          </view>
        </view>

        <!-- 得分行（蓝队得分 + 红队得分） -->
        <view class="vs-scores-row">
          <view class="score-tag-blue">
            <text class="score-label">蓝方得分</text>
            <text class="score-num score-num-blue">{{ blueScore }}</text>
          </view>
          <!-- 红队得分：分数在内侧（左），标签在外侧（右），配合 justify-content: flex-end 靠右对齐，与蓝队形成镜像对称 -->
          <view class="score-tag-red">
            <text class="score-num score-num-red">{{ redScore }}</text>
            <text class="score-label">红方得分</text>
          </view>
        </view>
      </view>

      <!-- ----- MVP 卡片（仅 NvN mode = 2/3）----- -->
      <view
        v-if="mvpPlayer && !isMeleeMode"
        class="mvp-card"
        :class="mvpTeam === 1 ? 'mvp-card-blue' : 'mvp-card-red'"
      >
        <!-- 背景图：蓝队用 mvp-blue.png，红队用 mvp-red.png（平行四边形渐变切图） -->
        <image
          class="mvp-bg"
          :src="mvpTeam === 1 ? '../static/mvp-blue.png' : '../static/mvp-red.png'"
          mode="scaleToFill"
        />
        <!-- 左：MVP 标题图 + 斩获环数 -->
        <view class="mvp-info">
          <image class="mvp-badge" src="../static/mvp-tip.png" mode="widthFix" />
          <view class="mvp-rings">
            斩获<text class="mvp-rings-num">{{ mvpPlayer.totalRing }}</text>环
          </view>
        </view>
        <!-- 右：MVP 头像 + 名字，边框颜色跟随 MVP 所在队伍 -->
        <view class="mvp-player">
          <Avatar
            :src="mvpPlayer.avatar"
            :size="53"
            :borderColor="mvpTeam === 1 ? '#5FADFF' : '#FF6060'"
          />
          <text class="mvp-name">{{ mvpPlayer.name }}</text>
        </view>
      </view>

      <!-- ----- 大乱斗战绩排行（mode > 3）----- -->
      <view v-if="isMeleeMode" class="melee-section">
        <!-- 本场战绩标题：装饰横线 + 标题图 + 装饰横线 -->
        <view class="melee-title">
          <view class="melee-title-line" />
          <image class="melee-title-img" src="../static/battle-result.png" mode="scaleToFill" />
          <view class="melee-title-line" />
        </view>

        <!-- 排行榜滚动列表（显示 6.5 条，第 7 条半显示提示可滚动）-->
        <scroll-view class="melee-rank-scroll" scroll-y>
          <view
            v-for="(item, index) in meleeRankList"
            :key="item.id"
            :class="['rank-item', item.isSelf ? 'rank-item-self' : '', index % 2 !== 0 ? 'rank-item-light' : '']"
          >
            <!-- 前三名左侧渐变背景装饰（绝对定位于内容层之下）-->
            <image
              v-if="item.rank <= 3"
              class="rank-bg-deco"
              :src="getMeleeRankBgSrc(item.rank)"
              mode="scaleToFill"
            />

            <!-- 行内容区域（z-index 高于背景装饰）-->
            <view class="rank-item-content">
              <!-- 名次徽章：1-3 使用 champ 图标，4+ 灰色圆形数字 -->
              <view class="rank-badge-wrap">
                <image
                  v-if="item.rank <= 3"
                  class="rank-badge-img"
                  :src="`../static/champ${item.rank}.png`"
                  mode="aspectFit"
                />
                <view v-else class="rank-badge-default">
                  <text class="rank-badge-num">{{ item.rank }}</text>
                </view>
              </view>

              <!-- 圆形头像（前三名根据名次展示对应光环颜色）-->
              <Avatar :src="item.avatar" :size="44" :borderColor="getMeleeAvatarBorderColor(item.rank)" />

              <!-- 昵称 + 段位 -->
              <view class="rank-player-info">
                <text class="rank-player-name">{{ item.name }}</text>
                <text class="rank-player-lvl">{{ item.lvlName }}</text>
              </view>

              <!-- 总环数 -->
              <view class="rank-score">
                <text class="rank-score-num">{{ item.totalRing }}</text>
                <text class="rank-score-unit">环</text>
              </view>
            </view>
          </view>
        </scroll-view>
      </view>

      <!-- ----- 查看完整成绩链接 ----- -->
      <text class="view-full-btn" @click="checkBowData">查看完整成绩</text>

      <!-- ----- 经验进度条区域 ----- -->
      <view class="exp-section">
        <text class="exp-gained">+{{ expGained }}经验</text>
        <view class="exp-bar-row">
          <text class="exp-lv">LV.{{ userLvl }}</text>
          <view class="exp-bar-bg">
            <view
              class="exp-bar-fg"
              :style="{ width: showExpAnim ? expPercent + '%' : '0%' }"
            />
          </view>
          <text class="exp-progress">{{ expCurrent }} / {{ expTotal }}</text>
        </view>
      </view>

      <!-- 底部安全区占位 -->
      <view class="safe-area-bottom" />
    </Container>

    <!-- ===== 底部：返回房间按鈕（对抗模式与大乱斗模式样式不同）===== -->
    <view class="bottom-bar">
      <view
        :class="['btn-return', data.mode > 3 ? 'btn-return-melee' : 'btn-return-battle']"
        @click="exit"
      >{{ exitBtnText }}</view>
    </view>

    <!-- ===== 进场覆盖动效层（初始显示，点击或2.5s后消失）===== -->
    <view
      v-if="showOverlay"
      class="overlay"
      @click="closeOverlay"
    >
      <!-- 胜负/game-over 被摭图：大乱斗模式展示 game-over.png，对抗模式展示 you-win.png/you-lost.png -->
      <image
        :class="['overlay-trophy', isMeleeMode ? 'overlay-trophy-melee' : '']"
        :src="isMeleeMode ? `${RESULT_CDN}/game-over.png` : (ifWin ? `${RESULT_CDN}/you-win.png` : `${RESULT_CDN}/you-lost.png`)"
        mode="widthFix"
      />

      <!-- 激励语图片（仅 NvN 对抗模式展示，大乱斗模式不展示）-->
      <image
        v-if="tipImage && !isMeleeMode"
        class="overlay-tip"
        :src="tipImage"
        mode="widthFix"
      />
    </view>

    <!-- 升级/段位提升动效组件 -->
    <UserUpgrade />
  </view>
</template>

<style scoped>
/* ============================
   全局页面容器
   ============================ */
.page {
  width: 750rpx;
  position: relative;
}



/* ============================
   Banner 区：game 胜负图
   ============================ */
.banner-section {
  position: relative;
  z-index: 10;          /* 高于 vs-section，确保 game 图层级在上 */
  width: 750rpx;
  height: 300rpx;
  display: flex;
  align-items: flex-end; /* 图片裴底对齐 vs-section 顶边 */
  justify-content: center;
  overflow: visible;    /* 允许 6rpx 叠入 vs-section */
  margin-top: 20rpx;
}

/* game 胜负展示图（宽度和叠层距由 :style 动态赋値：胜 362rpx/-32rpx，负 378rpx/-40rpx） */
.banner-result {
  position: relative;
  z-index: 1;
}

/* 弹入缩放动画 */
@keyframes scale-in {
  0% { transform: scale(0.3); opacity: 0; }
  70% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); }
}

.scale-in {
  animation: scale-in 0.5s ease-out forwards;
}

/* ============================
   VS 对战信息区
   全宽背景条 246rpx 高，参考设计稿 375×123pt
   ============================ */
.vs-section {
  position: relative;
  width: 750rpx;
  height: 246rpx;
  overflow: hidden;
}

/* 红蓝背景切图 */
.vs-bg-img {
  position: absolute;
  inset: 0;
  width: 750rpx;
  height: 246rpx;
}

/* 玩家头像行：padding-top 补偿 banner 图叠入 vs-section 导致的视觉偏上 */
.vs-players-row {
  position: relative;
  z-index: 2;
  width: 750rpx;
  height: 180rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 30rpx 24rpx 0;
  box-sizing: border-box;
}

.team-players {
  display: flex;
  align-items: flex-start;
  gap: 12rpx;
  flex: 1;
}

.team-players-blue {
  justify-content: center;
}

.team-players-red {
  justify-content: center;
}

.player-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8rpx;
}

.player-name {
  font-size: 22rpx;
  font-weight: 400;
  color: #BBCBFF;
  width: 74rpx;
  height: 30rpx;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- 得分行 ---- */
.vs-scores-row {
  position: relative;
  z-index: 2;
  width: 750rpx;
  height: 66rpx; /* 33px → 66rpx */
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.score-tag-blue {
  display: flex;
  align-items: center;
  gap: 12rpx;
  width: 216rpx;
  height: 54rpx;
  background: linear-gradient(270deg, rgba(116,197,255,0) 0%, rgba(0,92,159,0.64) 100%);
  padding: 0 20rpx;
  box-sizing: border-box;
}

.score-tag-red {
  display: flex;
  align-items: center;
  justify-content: flex-end; /* 内容靠右对齐，使标签贴近外侧渐变区 */
  gap: 12rpx;
  width: 216rpx;
  height: 54rpx;
  /* 从中心侧（左）透明渐变到外侧（右）红色，与蓝队镜像对称 */
  background: linear-gradient(90deg, rgba(193,4,1,0) 0%, rgba(193,4,1,0.64) 100%);
  padding: 0 20rpx;
  box-sizing: border-box;
}

.score-label {
  font-size: 20rpx;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.6);
}

.score-num {
  font-size: 48rpx;
  font-weight: 400;
  line-height: 1;
}

.score-num-blue {
  color: #62CBFF;
}

.score-num-red {
  color: #E86B72;
}

/* ============================
   MVP 卡片
   设计尺寸：700×230rpx（横幅风格，背景由切图决定）
   ============================ */
.mvp-card {
  width: 574rpx;
  height: 264rpx;
  margin: 40rpx auto 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 56rpx;
  box-sizing: border-box;
  position: relative;
  overflow: hidden;
}

/* 蓝队 MVP（背景色透明，颜色由 mvp-blue.png 决定）*/
.mvp-card-blue,
/* 红队 MVP（背景色透明，颜色由 mvp-red.png 决定）*/
.mvp-card-red {
  background: transparent;
}

/* 背景切图：绝对定位全铺，产生平行四边形渐变效果 */
.mvp-bg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.mvp-info {
  display: flex;
  flex-direction: column;
  gap: 4rpx;
  position: relative;
  z-index: 1;
}

.mvp-badge {
  width: 228rpx; /* 114px → 228rpx */
}

.mvp-rings {
  font-size: 30rpx;
  color: #fff;
  display: flex;
  align-items: baseline;
  align-self: flex-end;
  transform: rotate(-5deg);
  transform-origin: right center;
}

/* 环数数值：40rpx 加粗，金色，由父级统一倾斜 */
.mvp-rings-num {
  color: #fed847;
  font-size: 40rpx;
  font-weight: 700;
  display: inline-block;
  line-height: 1;
  margin: 0 4rpx;
}

.mvp-player {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8rpx;
  position: relative;
  z-index: 1;
  transform: translateY(-22rpx);
}

.mvp-name {
  font-size: 24rpx;
  color: #fff;
  max-width: 120rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================
   查看完整成绩链接
   ============================ */
.view-full-btn {
  display: block;
  width: 100%;
  text-align: center;
  color: #4DA6FF;
  font-size: 28rpx;
  margin-top: 48rpx;
  padding: 12rpx 0;
}

/* ============================
   经验进度条区域
   ============================ */
.exp-section {
  width: 100%;
  padding: 32rpx 48rpx 0;
  box-sizing: border-box;
}

.exp-gained {
  display: block;
  text-align: center;
  color: #FAE6BC;
  font-size: 20rpx;
  font-weight: 400;
  margin-bottom: 12rpx;
}

.exp-bar-row {
  display: flex;
  align-items: center;
  gap: 16rpx;
}

.exp-lv {
  font-size: 22rpx;
  color: #ffffff;
  font-weight: 400;
  flex-shrink: 0;
}

.exp-bar-bg {
  flex: 1;
  height: 10rpx;
  background: #454545;
  border-radius: 5rpx;
  overflow: hidden;
}

.exp-bar-fg {
  height: 100%;
  background: linear-gradient(90deg, #DD7B13 0%, #DD7B13 75%, rgba(244, 255, 176, 0.84) 100%);
  border-radius: 5rpx;
  transition: width 0.8s ease-out;
  /* 发光效果：近似 rgba(244,255,176,0.84) + blur 7.7px 叠加层 */
  box-shadow: 0 0 14rpx rgba(244, 255, 176, 0.84);
}

.exp-progress {
  font-size: 18rpx;
  font-weight: 400;
  color: #C3C3C3;
  flex-shrink: 0;
}

/* ============================
   底部安全区占位
   iPhone X 底部约 34pt → 68rpx
   ============================ */
.safe-area-bottom {
  height: 68rpx;
}

/* ============================
   底部返回房间按钮（固定定位）
   设计：全宽减32px边距=343pt → 686rpx，高50pt → 100rpx
   ============================ */
.bottom-bar {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 750rpx;
  padding: 20rpx 0;
  padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
  box-sizing: border-box;
  background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, transparent 100%);
  display: flex;
  justify-content: center;
  z-index: 50;
}

/* 返回房间按鈕公共样式 */
.btn-return {
  background: #FED847;
  font-weight: 500;
  color: #000000;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 对抗模式（mode <= 3）按鈕 */
.btn-return-battle {
  width: 694rpx;
  height: 88rpx;
  border-radius: 16rpx;
  font-size: 30rpx;
}

/* 大乱斗模式（mode > 3）按鈕 */
.btn-return-melee {
  width: 232rpx;
  height: 70rpx;
  border-radius: 44rpx;
  font-size: 28rpx;
}

/* ============================
   进场覆盖动效层
   ============================ */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  /* rgba 写法等价于 background:#000 + opacity:0.5，且不影响子元素不透明度 */
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  animation: overlay-in 0.3s ease-out;
  /* 两类被摭图片都是 750×666/668rpx 全宽，去除水平 padding */
  padding: 0;
  box-sizing: border-box;
}

@keyframes overlay-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* 胜利/失败奖杯图片（750×666rpx 全宽展示）*/
.overlay-trophy {
  width: 750rpx;
  height: 666rpx;
  animation: trophy-bounce-in 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* 大乱斗结束图：高度覆盖为 668rpx */
.overlay-trophy-melee {
  height: 668rpx;
  height: 668rpx;
}

@keyframes trophy-bounce-in {
  0% { transform: scale(0.3) translateY(-80rpx); opacity: 0; }
  60% { transform: scale(1.1) translateY(10rpx); opacity: 1; }
  100% { transform: scale(1) translateY(0); }
}

/* 覆盖层激励语图片（向上移入奖杯图底部空白区） */
.overlay-tip {
  width: 600rpx;
  margin-top: -145rpx;
  margin-bottom: 20rpx;
}

/* 提示文字 */
.overlay-hint {
  font-size: 24rpx;
  color: rgba(255, 255, 255, 0.5);
  margin-top: 24rpx;
}

/* ============================
   大乱斗战绩区域
   ============================ */
.melee-section {
  width: 750rpx;
  /* 左右各 60rpx，使列表项宽度 = 750 - 120 = 630rpx */
  padding: 0 60rpx;
  box-sizing: border-box;
  margin-top: 48rpx;
  /* view-full-btn 有 margin-top: 48rpx，叠加后共 50rpx 间距 */
  margin-bottom: 2rpx;
}

/* 标题行：装饰横线 + 标题图 + 装饰横线 */
.melee-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16rpx;
  margin-bottom: 50rpx;
}

/* 两侧装饰横线 */
.melee-title-line {
  width: 120rpx;
  height: 2rpx;
  background: #ffffff;
  opacity: 0.2;
  flex-shrink: 0;
}

/* 本场战绩标题图（180×44rpx）*/
.melee-title-img {
  width: 180rpx;
  height: 44rpx;
  flex-shrink: 0;
}

/*
  排行榜滚动容器高度计算：
  条目无间距，6.5 条 × 116rpx = 754rpx，第 7 条上半部分可见提示用户可滚动
*/
.melee-rank-scroll {
  height: 754rpx;
}

/* 单条排行记录 */
.rank-item {
  display: flex;
  align-items: center;
  height: 116rpx;
  background: rgba(35, 33, 30, 0.85);
  /* 相对定位，使背景装饰图可绝对定位于行内 */
  position: relative;
  overflow: hidden;
}

/* 当前用户所在行：内嵌阴影高亮，不影响尺寸与相邻条目间距 */
.rank-item-self {
  box-shadow: inset 0 0 0 2rpx #ff4d4d;
}

/* 斑马色块侸数行（rank 1/3/5...）：白色 5% 透明底 */
.rank-item-light {
  background: rgba(255, 255, 255, 0.05);
}

/* 前三名行背景装饰图（SVG 设计尺寸 156×58@2x = 312×116rpx，左对齐绝对定位）*/
.rank-bg-deco {
  display: block; /* 消除 image 默认 inline-block 行高撑开导致的条目间缝隙 */
  position: absolute;
  left: 0;
  top: 0;
  width: 312rpx;
  height: 116rpx;
  z-index: 0;
}

/* 行内容区域：flex 水平排布，层叠高于背景装饰 */
.rank-item-content {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0 20rpx;
  box-sizing: border-box;
  gap: 16rpx;
  position: relative;
  z-index: 1;
}

/* 名次徽章容器（统一尺寸，内部放 champ 图标或灰色圆形）*/
.rank-badge-wrap {
  width: 52rpx;
  height: 52rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* 徽章右侧叠加 gap(16) + margin(18) = 34rpx 到头像 */
  margin-right: 18rpx;
}

/* 1-3 名：champ 图标，与容器等尺寸 */
.rank-badge-img {
  width: 52rpx;
  height: 52rpx;
}

/* 4+ 名：灰色圆形底托 */
.rank-badge-default {
  width: 52rpx;
  height: 52rpx;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.12);
  display: flex;
  align-items: center;
  justify-content: center;
}

.rank-badge-num {
  font-size: 26rpx;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.7);
}

/* 玩家信息：昵称 + 段位（flex 自适应伸展）*/
.rank-player-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4rpx;
  min-width: 0;
}

.rank-player-name {
  font-size: 28rpx;
  color: #ffffff;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rank-player-lvl {
  font-size: 22rpx;
  color: rgba(255, 255, 255, 0.5);
}

/* 总环数（靠右对齐，与用户信息区对比）*/
.rank-score {
  display: flex;
  align-items: center;
  gap: 8rpx;
  flex-shrink: 0;
}

.rank-score-num {
  font-size: 26rpx;
  font-weight: 400;
  color: #ffffff;
  line-height: 1;
}

.rank-score-unit {
  font-size: 22rpx;
  font-weight: 400;
  color: rgba(255, 255, 255, 0.5);
  line-height: 1;
}
</style>
