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

import PlanCard from "@/components/planning/PlanCard.vue";
import { MOCK_PLAN_LIST, PLAN_STATUS_TABS, type PlanItem } from "@/config/planning";

const currentTab = ref(0);
const planList = ref<PlanItem[]>([]);
const isLoading = ref(false);
const hasMore = ref(true);
const currentPage = ref(1);
const pageSize = 4;

const currentTabValue = computed(() => PLAN_STATUS_TABS[currentTab.value].value);

const filteredSource = computed(() => {
  if (currentTabValue.value === "all") return MOCK_PLAN_LIST;
  return MOCK_PLAN_LIST.filter((item) => item.status === currentTabValue.value);
});

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

  isLoading.value = true;

  setTimeout(() => {
    const start = (page - 1) * pageSize;
    const end = start + pageSize;
    const nextList = filteredSource.value.slice(start, end);

    planList.value = reset ? nextList : [...planList.value, ...nextList];
    currentPage.value = page;
    hasMore.value = end < filteredSource.value.length;
    isLoading.value = false;
  }, 400);
};

const changeTab = (index: number) => {
  currentTab.value = index;
  currentPage.value = 1;
  hasMore.value = true;
  loadData(1, true);
};

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

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

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

    <view class="page-header">
      <view>
        <text class="page-title">计划列表</text>
        <text class="page-subtitle">查看正在执行的周期传话计划</text>
      </view>
    </view>

    <view class="plan-tabs">
      <view
        v-for="(tab, index) in PLAN_STATUS_TABS"
        :key="tab.value"
        class="plan-tab"
        :class="{ active: currentTab === index }"
        @tap="changeTab(index)"
      >
        <text>{{ tab.name }}</text>
      </view>
    </view>

    <scroll-view class="plan-scroll" scroll-y @scrolltolower="onLoadMore">
      <view class="plan-list" v-if="planList.length > 0">
        <plan-card v-for="plan in planList" :key="plan.id" :plan="plan" />

        <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">
.planned-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);
}

.page-header,
.plan-tabs,
.plan-scroll {
  position: relative;
  z-index: 1;
}

.page-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;
}

.plan-tabs {
  display: flex;
  margin: 0 24rpx 18rpx;
  padding: 8rpx;
  border-radius: 999rpx;
  background: rgba(255, 255, 255, 0.62);
  border: 1rpx solid rgba(255, 255, 255, 0.86);
  box-shadow: 0 10rpx 26rpx rgba(83, 96, 130, 0.05);
}

.plan-tab {
  flex: 1;
  height: 62rpx;
  line-height: 62rpx;
  text-align: center;
  border-radius: 999rpx;
  color: #7b8493;
  font-size: 24rpx;
  font-weight: 600;
}

.plan-tab.active {
  color: #fff;
  background: linear-gradient(135deg, #ff78a2 0%, #83c6ff 100%);
  box-shadow: 0 10rpx 20rpx rgba(255, 120, 162, 0.18);
}

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

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

.loading-state {
  display: flex;
  align-items: center;
  justify-content: 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>
