<script setup lang="ts">
import { onMounted, ref } from "vue";

import ReplyCard from "@/components/reply/ReplyCard.vue";
import { MOCK_REPLY_LIST, REPLY_PAGE_SIZE, serializeReply, type ReplyItem } from "@/config/reply";

const replyList = ref<ReplyItem[]>([]);
const currentPage = ref(1);
const isLoading = ref(false);
const refreshing = ref(false);
const hasMore = ref(true);

const loadData = (page = 1, reset = false) => {
  if (isLoading.value) return;

  isLoading.value = true;

  setTimeout(() => {
    const start = (page - 1) * REPLY_PAGE_SIZE;
    const end = start + REPLY_PAGE_SIZE;
    const nextList = MOCK_REPLY_LIST.slice(start, end);

    replyList.value = reset ? nextList : [...replyList.value, ...nextList];
    currentPage.value = page;
    hasMore.value = end < MOCK_REPLY_LIST.length;
    isLoading.value = false;
    refreshing.value = false;
  }, 450);
};

const onRefresh = () => {
  refreshing.value = true;
  loadData(1, true);
};

const onLoadMore = () => {
  if (!isLoading.value && hasMore.value) {
    loadData(currentPage.value + 1);
  }
};

const openReply = (reply: ReplyItem) => {
  if (reply.unread) {
    reply.unread = false;
  }

  uni.navigateTo({
    url: `/pages/reply/detail?reply=${serializeReply(reply)}`,
  });
};

onMounted(() => {
  loadData(1, true);
});
</script>

<template>
  <view class="reply-page">
    <view class="dream-bg dream-bg-one"></view>
    <view class="dream-bg dream-bg-two"></view>

    <view class="reply-header">
      <view>
        <text class="page-title">收到回复</text>
        <text class="page-subtitle">对方的回应会安静地收在这里</text>
      </view>
    </view>

    <scroll-view
      class="reply-scroll"
      scroll-y
      refresher-enabled
      :refresher-triggered="refreshing"
      @refresherrefresh="onRefresh"
      @scrolltolower="onLoadMore"
    >
      <view class="reply-list" v-if="replyList.length > 0">
        <reply-card v-for="reply in replyList" :key="reply.id" :reply="reply" @open="openReply" />

        <view v-if="isLoading" class="loading-state">
          <view class="loading-dot"></view>
          <view class="loading-dot"></view>
          <view class="loading-dot"></view>
        </view>

        <view v-if="!hasMore && !isLoading" class="no-more">
          <view class="no-more-line"></view>
          <text class="no-more-text">已经到底了</text>
          <view class="no-more-line"></view>
        </view>
      </view>

      <view class="empty-state" v-else-if="!isLoading">
        <view class="empty-card">
          <view class="empty-icon">信</view>
          <text class="empty-title">还没有收到回复</text>
          <text class="empty-desc">对方回复后，会在这里第一时间展示</text>
        </view>
      </view>

      <view v-else class="loading-state first-loading">
        <view class="loading-dot"></view>
        <view class="loading-dot"></view>
        <view class="loading-dot"></view>
      </view>
    </scroll-view>
  </view>
</template>

<style scoped lang="scss">
.reply-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
  box-sizing: border-box;
  background:
    linear-gradient(180deg, rgba(255, 244, 250, 0.98) 0%, rgba(239, 248, 255, 0.96) 48%, #f7f8fb 100%),
    linear-gradient(135deg, rgba(255, 204, 225, 0.22), rgba(199, 233, 255, 0.24));
  position: relative;
  overflow: hidden;
}

.dream-bg {
  position: fixed;
  border-radius: 50%;
  pointer-events: none;
  z-index: 0;
}

.dream-bg-one {
  width: 360rpx;
  height: 360rpx;
  right: -150rpx;
  top: 110rpx;
  background: rgba(255, 193, 215, 0.23);
}

.dream-bg-two {
  width: 330rpx;
  height: 330rpx;
  left: -140rpx;
  top: 650rpx;
  background: rgba(171, 218, 255, 0.21);
}

.reply-header,
.reply-scroll {
  position: relative;
  z-index: 1;
}

.reply-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 32rpx 28rpx 18rpx;
}

.page-title,
.page-subtitle,
.empty-title,
.empty-desc {
  display: block;
}

.page-title {
  color: #20273a;
  font-size: 44rpx;
  font-weight: 700;
  line-height: 1.2;
}

.page-subtitle {
  margin-top: 10rpx;
  color: #687286;
  font-size: 25rpx;
  line-height: 1.45;
}

.reply-scroll {
  flex: 1;
  height: 0;
}

.reply-list {
  padding: 0 24rpx 32rpx;
}

.loading-state {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 38rpx 0;
}

.first-loading {
  min-height: 50vh;
}

.loading-dot {
  width: 14rpx;
  height: 14rpx;
  margin: 0 7rpx;
  border-radius: 50%;
  background: linear-gradient(135deg, #ff92b6, #8bcfff);
  animation: loadingDot 1.4s infinite ease-in-out both;
}

.loading-dot:nth-child(1) {
  animation-delay: -0.32s;
}

.loading-dot:nth-child(2) {
  animation-delay: -0.16s;
}

@keyframes loadingDot {
  0%,
  80%,
  100% {
    transform: scale(0);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

.no-more {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24rpx 0 34rpx;
}

.no-more-line {
  width: 120rpx;
  height: 1rpx;
  background: linear-gradient(90deg, transparent, rgba(153, 170, 190, 0.35));
}

.no-more-line:last-child {
  background: linear-gradient(90deg, rgba(153, 170, 190, 0.35), transparent);
}

.no-more-text {
  margin: 0 18rpx;
  color: #9aa3b2;
  font-size: 22rpx;
}

.empty-state {
  padding: 70rpx 24rpx;
}

.empty-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 68rpx 34rpx;
  border-radius: 28rpx;
  background: rgba(255, 255, 255, 0.74);
  border: 1rpx solid rgba(255, 255, 255, 0.9);
  box-shadow: 0 18rpx 42rpx rgba(93, 107, 139, 0.08);
}

.empty-icon {
  width: 96rpx;
  height: 96rpx;
  line-height: 96rpx;
  margin-bottom: 24rpx;
  border-radius: 50%;
  text-align: center;
  color: #fff;
  font-size: 34rpx;
  font-weight: 700;
  background: linear-gradient(135deg, #ff78a2 0%, #83c6ff 100%);
}

.empty-title {
  color: #263044;
  font-size: 32rpx;
  font-weight: 700;
}

.empty-desc {
  margin-top: 10rpx;
  color: #8c96a8;
  font-size: 24rpx;
}
</style>
