<template>
  <view class="page-container">
    <view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
      <view class="nav-content">
        <view class="nav-left" @tap="goBack">
          <text class="back-icon"></text>
        </view>
        <text class="nav-title">PK详情</text>
        <view class="nav-right" @tap="goToPkStation">
          <text class="nav-right-text">PK站</text>
        </view>
      </view>
    </view>

    <view :style="{ height: statusBarHeight + 44 + 'px' }"></view>

    <view class="content-wrap">
      <view v-if="detailData" class="hero-card">
        <view class="hero-badge">PK Detail</view>
        <text class="hero-title">{{ detailData.topicTitle }}</text>
        <text class="hero-desc">{{ insightText }}</text>

        <view class="summary-row">
          <view class="summary-pill" :class="selectedTone ? `summary-pill--${selectedTone}` : ''">
            <text class="summary-pill-label">我的选择</text>
            <text class="summary-pill-value">{{ selectedItemLabel }}</text>
          </view>
          <view class="summary-meta">
            <text class="summary-meta-item">{{ detailData.voteCount }} 人参与</text>
            <text class="summary-dot"></text>
            <text class="summary-meta-item">{{ detailData.votedAtText }}</text>
          </view>
        </view>
      </view>

      <view v-if="detailData" class="battle-card">
        <view class="battle-stage">
          <view class="fighter-card left" :class="{ selected: detailData.selfChooseSide === 'left' }">
            <view class="fighter-badge" v-if="detailData.selfChooseSide === 'left'">我支持</view>
            <image class="fighter-avatar" :src="detailData.left.avatar" mode="aspectFill" />
            <text class="fighter-name">{{ detailData.left.name }}</text>
            <text class="fighter-votes">{{ detailData.leftVoteCount }} 票</text>
          </view>

          <view class="battle-middle">
            <view class="vs-badge">VS</view>
            <text class="battle-middle-text">{{ leadText }}</text>
          </view>

          <view class="fighter-card right" :class="{ selected: detailData.selfChooseSide === 'right' }">
            <view class="fighter-badge fighter-badge--right" v-if="detailData.selfChooseSide === 'right'">我支持</view>
            <image class="fighter-avatar" :src="detailData.right.avatar" mode="aspectFill" />
            <text class="fighter-name">{{ detailData.right.name }}</text>
            <text class="fighter-votes">{{ detailData.rightVoteCount }} 票</text>
          </view>
        </view>

        <view class="support-bar">
          <view class="support-fill left-fill" :style="{ width: `${detailData.leftPercent}%` }"></view>
          <view class="support-fill right-fill" :style="{ width: `${detailData.rightPercent}%` }"></view>
        </view>

        <view class="support-row">
          <text class="support-text left-text">{{ detailData.leftPercent }}% 支持 {{ detailData.left.name }}</text>
          <text class="support-text right-text">{{ detailData.rightPercent }}% 支持 {{ detailData.right.name }}</text>
        </view>
      </view>

      <view v-else class="state-card">
        <text class="state-title">暂时无法查看这场 PK</text>
        <text class="state-desc">这场对决的信息不存在或已失效，请返回列表重新进入。</text>
        <button class="state-btn" @tap="goBack">返回上一页</button>
      </view>

      <CommentSection
        v-if="detailData"
        ref="commentSectionRef"
        variant="pk"
        :request-key="commentRequestKey"
        :visible="!!commentRequestKey"
        :allow-compose="true"
        compose-title="说说你的站队理由"
        :compose-desc="`支持 ${selectedItemLabel} 的观点，会更容易引发讨论`"
        compose-placeholder="写下你的 PK 观点..."
        page-name="pk_detail"
        pill-label="我站"
        :pill-value="selectedItemLabel"
        :pill-tone="selectedTone"
        loading-desc="看看大家如何评价这场对决"
        empty-title="还没有评论"
        empty-desc="来写下你的判断，成为这场 PK 的第一位评论官"
        footer-more-text="查看更多评论"
        :list-handler="fetchPkCommentList"
        :replies-handler="fetchPkCommentReplies"
        :publish-handler="publishPkComment"
        :normalize-comment="normalizePkComment"
        :like-handler="likeComment"
        @need-login="openLoginPopup('请先登录后再参与评论')"
      />
    </view>

    <LoginPopup ref="loginPopupRef" @logind="handleLoginSuccess" />
  </view>
</template>

<script setup>
import { computed, ref } from "vue";
import { onLoad, onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
import { getStatusBarHeight } from "@/utils/system";
import { fetchCommentList, fetchCommentReplyList, publishComment, likeComment } from "@/api/pk";
import { FILE_BASE_URL } from "@/utils/constants";
import { formatDate } from "@/utils/date";
import CommentSection from "@/components/CommentSection/CommentSection.vue";
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
import { useUserStore } from "@/stores/user";

const DETAIL_CACHE_PREFIX = "pk_detail_cache_";

const userStore = useUserStore();
const statusBarHeight = ref(getStatusBarHeight() || 44);
const loginPopupRef = ref(null);
const commentSectionRef = ref(null);
const detailData = ref(null);
const pkId = ref("");

const isLoggedIn = computed(() => !!userStore.token || !!userStore.userInfo?.nickName);
const selectedTone = computed(() => {
  if (!detailData.value?.selfChooseSide) return "";
  return detailData.value.selfChooseSide === "left" ? "left" : "right";
});
const selectedItemLabel = computed(() => {
  if (!detailData.value) return "";
  return detailData.value.selfChooseName || "未记录";
});
const commentRequestKey = computed(() => {
  if (!detailData.value?.id || !detailData.value?.selfChooseItemId) return "";
  return `${detailData.value.id}_${detailData.value.selfChooseItemId}`;
});
const leadText = computed(() => {
  if (!detailData.value) return "";
  const leftPercent = Number(detailData.value.leftPercent || 0);
  const rightPercent = Number(detailData.value.rightPercent || 0);
  const leader = leftPercent >= rightPercent ? detailData.value.left.name : detailData.value.right.name;
  const leaderPercent = leftPercent >= rightPercent ? leftPercent : rightPercent;
  return `${leader} 当前 ${leaderPercent}% 领先`;
});
const insightText = computed(() => {
  if (!detailData.value) return "这是一场你参与过的 PK 对决";
  const myChoice = detailData.value.selfChooseName || "你的选择";
  const myLeading =
    (detailData.value.selfChooseSide === "left" && detailData.value.leftPercent >= detailData.value.rightPercent) ||
    (detailData.value.selfChooseSide === "right" && detailData.value.rightPercent >= detailData.value.leftPercent);
  return myLeading
    ? `你支持的 ${myChoice} 当前占优，来看看评论区大家的判断是否和你一致。`
    : `你支持的 ${myChoice} 暂时落后，看看评论区里有没有和你同样坚定的声音。`;
});

const buildAvatarUrl = (avatar) => {
  if (!avatar) return "https://api.dicebear.com/7.x/avataaars/svg?seed=fallback";
  const normalizedAvatar = String(avatar).trim();
  return normalizedAvatar.startsWith("http") ? normalizedAvatar : `${FILE_BASE_URL}${normalizedAvatar}`;
};

const clampPercent = (value) => {
  const number = Number(value);
  if (!Number.isFinite(number)) return 0;
  return Math.max(0, Math.min(100, Math.round(number)));
};

const normalizePercentPair = (item = {}) => {
  let leftPercent = clampPercent(item.leftPercent);
  let rightPercent = clampPercent(item.rightPercent);

  if (!leftPercent && !rightPercent) {
    const leftVotes = Number(item.leftVoteCount || 0);
    const rightVotes = Number(item.rightVoteCount || 0);
    const totalVotes = leftVotes + rightVotes;
    if (totalVotes > 0) {
      leftPercent = Math.round((leftVotes / totalVotes) * 100);
      rightPercent = 100 - leftPercent;
    } else {
      leftPercent = 50;
      rightPercent = 50;
    }
  } else if (!leftPercent) {
    leftPercent = 100 - rightPercent;
  } else if (!rightPercent) {
    rightPercent = 100 - leftPercent;
  }

  const total = leftPercent + rightPercent;
  if (total && total !== 100) {
    leftPercent = Math.round((leftPercent / total) * 100);
    rightPercent = 100 - leftPercent;
  }

  return { leftPercent, rightPercent };
};

const normalizeDetail = (item = {}) => {
  const { leftPercent, rightPercent } = normalizePercentPair(item);
  const selfChooseSide =
    item.selfChooseSide ||
    (item.selfChooseItemId && item.selfChooseItemId === item.leftItemId
      ? "left"
      : item.selfChooseItemId && item.selfChooseItemId === item.rightItemId
        ? "right"
        : "");
  const selfChooseName =
    selfChooseSide === "right"
      ? (item.rightItemName || "右侧对象")
      : selfChooseSide === "left"
        ? (item.leftItemName || "左侧对象")
        : "未记录";

  return {
    id: item.id || "",
    topicId: item.topicId || "",
    topicTitle: item.topicTitle || "未知话题",
    voteCount: Number(item.voteCount || 0),
    leftVoteCount: Number(item.leftVoteCount || 0),
    rightVoteCount: Number(item.rightVoteCount || 0),
    selfChooseItemId: item.selfChooseItemId || "",
    selfChooseSide,
    selfChooseName,
    leftPercent,
    rightPercent,
    votedAt: item.votedAt || "",
    votedAtText: formatDate(item.votedAt, "YYYY-MM-DD HH:mm") || "刚刚参与",
    left: {
      id: item.leftItemId || "",
      name: item.leftItemName || "左侧对象",
      avatar: buildAvatarUrl(item.leftItemAvatar),
    },
    right: {
      id: item.rightItemId || "",
      name: item.rightItemName || "右侧对象",
      avatar: buildAvatarUrl(item.rightItemAvatar),
    },
  };
};

const resolveChoiceMeta = (chooseItemId) => {
  if (!chooseItemId || !detailData.value) {
    return { choiceLabel: "", choiceTone: "" };
  }
  if (chooseItemId === detailData.value.left.id) {
    return { choiceLabel: `支持 ${detailData.value.left.name}`, choiceTone: "left" };
  }
  if (chooseItemId === detailData.value.right.id) {
    return { choiceLabel: `支持 ${detailData.value.right.name}`, choiceTone: "right" };
  }
  return { choiceLabel: "已站队", choiceTone: "" };
};

const normalizePkComment = (item = {}, rootComment = null) => {
  const user = item.user || {};
  const replyToUser = item.replyToUser || {};
  const choiceMeta = resolveChoiceMeta(item.chooseItemId);

  return {
    id: item.id,
    rootCommentId: item.rootCommentId || rootComment?.id || null,
    parentCommentId: item.parentCommentId || rootComment?.id || null,
    replyToCommentId: item.replyToCommentId || null,
    name: user.nickname || "匿名用户",
    avatar: buildAvatarUrl(user.avatar),
    time: formatDate(item.createdAt) || "刚刚",
    content: item.content || "",
    likes: Number(item.likeCount || 0),
    isLiked: !!item.isLiked,
    userAction: "",
    replyCount: Number(item.replyCount || 0),
    replyToName: replyToUser.nickname || "",
    choiceLabel: choiceMeta.choiceLabel,
    choiceTone: choiceMeta.choiceTone,
    chooseItemId: item.chooseItemId || "",
    repliesLoading: false,
    repliesLoaded: false,
    repliesHasMore: false,
    repliesPage: 1,
    replies: [],
  };
};

const openLoginPopup = (message = "请先登录后再操作") => {
  loginPopupRef.value?.open();
  if (message) {
    uni.showToast({ title: message, icon: "none" });
  }
};

const goBack = () => {
  uni.navigateBack();
};

const goToPkStation = () => {
  uni.switchTab({
    url: "/pages/pk/index",
  });
};

const fetchPkCommentList = ({ page, orderBy }) => {
  return fetchCommentList({
    pkId: pkId.value,
    page,
    orderBy,
  });
};

const fetchPkCommentReplies = ({ rootCommentId, page }) => {
  return fetchCommentReplyList({
    pkId: pkId.value,
    rootCommentId,
    page,
  });
};

const publishPkComment = ({ content, replyTarget, mode }) => {
  return publishComment({
    pkId: pkId.value,
    chooseItemId: detailData.value?.selfChooseItemId,
    content,
    parentCommentId: mode === "reply" ? replyTarget?.parentCommentId : undefined,
    replyToCommentId: mode === "reply" ? replyTarget?.replyToCommentId : undefined,
  });
};

const hydrateDetail = (options = {}) => {
  const cacheKey = options.cacheKey || `${DETAIL_CACHE_PREFIX}${options.pkId || ""}`;
  const cached = cacheKey ? uni.getStorageSync(cacheKey) : null;
  if (cached && typeof cached === "object") {
    detailData.value = normalizeDetail(cached);
    pkId.value = detailData.value.id;
    return;
  }

  if (options.payload) {
    try {
      const parsed = JSON.parse(decodeURIComponent(options.payload));
      detailData.value = normalizeDetail(parsed);
      pkId.value = detailData.value.id;
    } catch (error) {
      detailData.value = null;
    }
  }
};

const handleLoginSuccess = async () => {
  await commentSectionRef.value?.refreshComments?.();
};

onLoad((options) => {
  pkId.value = options.pkId || "";
  hydrateDetail(options);
});

onPullDownRefresh(async () => {
  await commentSectionRef.value?.refreshComments?.();
  uni.stopPullDownRefresh();
});

onReachBottom(() => {
  commentSectionRef.value?.loadMoreComments?.();
});
</script>

<style lang="scss" scoped>
.page-container {
  min-height: 100vh;
  background:
    radial-gradient(circle at top, rgba(111, 90, 255, 0.14), transparent 32%),
    linear-gradient(180deg, #f7f8ff 0%, #f7f8fc 44%, #ffffff 100%);
}

.nav-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: rgba(247, 248, 255, 0.88);
  backdrop-filter: blur(24rpx);
}

.nav-content {
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28rpx 0 24rpx;
}

.nav-left,
.nav-right {
  min-width: 84rpx;
  display: flex;
  align-items: center;
}

.nav-right {
  justify-content: flex-end;
}

.back-icon {
  width: 40rpx;
  height: 40rpx;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23202433' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='19' y1='12' x2='5' y2='12'%3E%3C/line%3E%3Cpolyline points='12 19 5 12 12 5'%3E%3C/polyline%3E%3C/svg%3E");
  background-size: cover;
}

.nav-title {
  font-size: 34rpx;
  font-weight: 800;
  color: #202433;
}

.nav-right-text {
  font-size: 24rpx;
  color: #5c43f5;
  font-weight: 700;
}

.content-wrap {
  padding: 24rpx 32rpx 40rpx;
}

.hero-card,
.battle-card,
.state-card {
  background: rgba(255, 255, 255, 0.94);
  border: 2rpx solid rgba(229, 232, 246, 0.92);
  border-radius: 32rpx;
  box-shadow: 0 18rpx 42rpx rgba(87, 92, 145, 0.08);
}

.hero-card {
  padding: 32rpx;
  margin-bottom: 24rpx;
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  height: 44rpx;
  padding: 0 18rpx;
  border-radius: 999rpx;
  background: rgba(92, 67, 245, 0.1);
  color: #5c43f5;
  font-size: 22rpx;
  font-weight: 700;
  margin-bottom: 18rpx;
}

.hero-title {
  display: block;
  font-size: 40rpx;
  font-weight: 800;
  color: #1f2432;
  margin-bottom: 12rpx;
  line-height: 1.4;
}

.hero-desc {
  display: block;
  font-size: 25rpx;
  color: #7b8191;
  line-height: 1.7;
  margin-bottom: 24rpx;
}

.summary-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20rpx;
}

.summary-pill {
  display: inline-flex;
  align-items: center;
  gap: 8rpx;
  padding: 12rpx 18rpx;
  border-radius: 999rpx;
  background: rgba(92, 67, 245, 0.1);
}

.summary-pill--right {
  background: rgba(255, 141, 95, 0.12);
}

.summary-pill-label {
  font-size: 22rpx;
  color: #8a90a0;
}

.summary-pill-value {
  font-size: 24rpx;
  font-weight: 700;
  color: #4d44f1;
}

.summary-pill--right .summary-pill-value {
  color: #ff7a45;
}

.summary-meta {
  display: flex;
  align-items: center;
  gap: 12rpx;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.summary-meta-item {
  font-size: 22rpx;
  color: #8a90a0;
}

.summary-dot {
  width: 8rpx;
  height: 8rpx;
  border-radius: 50%;
  background: #d1d5db;
}

.battle-card {
  padding: 28rpx;
  margin-bottom: 24rpx;
}

.battle-stage {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12rpx;
  margin-bottom: 22rpx;
}

.fighter-card {
  position: relative;
  width: 224rpx;
  min-height: 276rpx;
  border-radius: 28rpx;
  padding: 30rpx 18rpx 24rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #fafbff 0%, #ffffff 100%);
  border: 2rpx solid transparent;
  box-sizing: border-box;
}

.fighter-card.left {
  border-color: rgba(92, 67, 245, 0.18);
}

.fighter-card.right {
  border-color: rgba(255, 153, 102, 0.2);
}

.fighter-card.selected {
  transform: translateY(-4rpx);
  box-shadow: 0 14rpx 28rpx rgba(92, 67, 245, 0.12);
}

.fighter-badge {
  position: absolute;
  top: 16rpx;
  left: 16rpx;
  padding: 8rpx 14rpx;
  border-radius: 999rpx;
  background: rgba(92, 67, 245, 0.12);
  color: #5c43f5;
  font-size: 20rpx;
  font-weight: 700;
}

.fighter-badge--right {
  background: rgba(255, 141, 95, 0.14);
  color: #ff7a45;
}

.fighter-avatar {
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  border: 6rpx solid #fff;
  box-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.08);
  margin-bottom: 18rpx;
}

.fighter-name {
  font-size: 30rpx;
  color: #1f2432;
  font-weight: 800;
  text-align: center;
  margin-bottom: 10rpx;
}

.fighter-votes {
  font-size: 22rpx;
  color: #858b9b;
}

.battle-middle {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.vs-badge {
  width: 90rpx;
  height: 90rpx;
  border-radius: 50%;
  background: linear-gradient(135deg, #6a5bff, #4d44f1);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 28rpx;
  font-weight: 900;
  box-shadow: 0 16rpx 30rpx rgba(92, 67, 245, 0.24);
  margin-bottom: 16rpx;
}

.battle-middle-text {
  font-size: 22rpx;
  color: #8a90a0;
  text-align: center;
}

.support-bar {
  height: 18rpx;
  border-radius: 999rpx;
  overflow: hidden;
  display: flex;
  background: #eceff8;
  margin-bottom: 16rpx;
}

.support-fill {
  height: 100%;
}

.left-fill {
  background: linear-gradient(90deg, #6557ff, #4d44f1);
}

.right-fill {
  background: linear-gradient(90deg, #ffb15f, #ff8d5f);
}

.support-row {
  display: flex;
  justify-content: space-between;
  gap: 20rpx;
}

.support-text {
  font-size: 24rpx;
  font-weight: 700;
}

.left-text {
  color: #5c43f5;
}

.right-text {
  color: #ff8d5f;
  text-align: right;
}

.state-card {
  padding: 64rpx 40rpx;
  text-align: center;
  margin-bottom: 24rpx;
}

.state-title {
  display: block;
  font-size: 32rpx;
  color: #232734;
  font-weight: 800;
  margin-bottom: 14rpx;
}

.state-desc {
  display: block;
  font-size: 25rpx;
  color: #8a90a0;
  line-height: 1.7;
  margin-bottom: 28rpx;
}

.state-btn {
  width: 240rpx;
  height: 84rpx;
  line-height: 84rpx;
  border-radius: 999rpx;
  background: #111827;
  color: #fff;
  font-size: 28rpx;
  font-weight: 700;
}

.state-btn::after {
  border: none;
}
</style>
