<template>
  <view class="bg-gray-100 min-h-screen">
    <!-- Category Tabs -->
    <!-- <scroll-view scroll-x class="bg-white whitespace-nowrap px-15 py-10 sticky top-0 z-10 w-full"
      :show-scrollbar="false">
      <view v-for="(tab, index) in tabs" :key="index"
        class="inline-block px-15 py-5 mr-10 text-sm rounded-full border transition-colors" :class="[
          activeCateId === tab.value
            ? 'bg-orange-100 text-orange-500 border-orange-500'
            : 'bg-white text-gray-600 border-gray-200',
        ]" @click="selectCate(tab.value)">
        {{ tab.name }}
      </view>
    </scroll-view> -->

    <!-- List -->
    <view v-if="loading && list.length === 0" class="loading-container">
      <uni-icons type="spinner-cycle" size="30" color="#999" />
      <text class="loading-text">加载中...</text>
    </view>

    <view v-else-if="!loading && list.length === 0" class="empty-container">
      <empty-data text="暂无文章" />
    </view>

    <view v-else class="p-15">
      <view v-for="(item, index) in list" :key="item._id" class="article-card flex"
        :class="{ 'mb-15': index < list.length - 1 }" @click="goToDetail(item)">
        <image class="flex-shrink-0 cover" :src="item.cover || '/static/home/health-education.png'" mode="aspectFill" />
        <view class="w-0 flex-grow">
          <view class="article-title truncate mb-10">
            {{ item.title || "宣教文章" }}
          </view>
          <view v-if="item.summary" class="article-summary line-clamp-2">
            {{ item.summary }}
          </view>
        </view>
      </view>

      <view v-if="loading && list.length > 0" class="loading-more">
        <uni-icons type="spinner-cycle" size="20" color="#999" />
        <text>加载中...</text>
      </view>

      <view v-if="!loading && list.length >= total" class="no-more">
        没有更多了
      </view>
    </view>
  </view>
</template>

<script setup>
import { computed, ref } from "vue";
import { onLoad, onReachBottom } from "@dcloudio/uni-app";
import dayjs from "dayjs";
import api from "@/utils/api.js";
import EmptyData from "@/components/empty-data.vue";

const corpId = ref("");
const enabledIds = ref([]);
const tabs = ref([{ name: "全部", value: "" }]);
const activeCateId = ref("");

const allArticles = ref([]);
const list = ref([]);
const total = ref(0);
const page = ref(1);
const pageSize = 20;
const loading = ref(false);

const uniqStrings = (items) => {
  const seen = new Set();
  const out = [];
  for (const item of items) {
    const s = typeof item === "string" ? item.trim() : "";
    if (!s || seen.has(s)) continue;
    seen.add(s);
    out.push(s);
  }
  return out;
};

const parseIdsParam = (raw) => {
  if (!raw) return [];
  const text = Array.isArray(raw) ? raw.join(",") : String(raw);
  const decoded = decodeURIComponent(text);
  return uniqStrings(decoded.split(","));
};

const getAllTab = () => ({ name: tabs.value?.[0]?.name || "全部", value: "" });

const getArticleCateIds = (article) => {
  const ids = [];
  if (!article) return ids;

  if (Array.isArray(article.cateIds)) ids.push(...article.cateIds);
  if (typeof article.cateIds === "string") ids.push(article.cateIds);
  if (typeof article.cateId === "string") ids.push(article.cateId);

  if (typeof article.categoryId === "string") ids.push(article.categoryId);
  if (Array.isArray(article.categoryIds)) ids.push(...article.categoryIds);
  if (typeof article.categoryIds === "string") ids.push(article.categoryIds);

  if (Array.isArray(article.cateList)) {
    ids.push(
      ...article.cateList.map((c) => c?._id || c?.id).filter((v) => typeof v === "string")
    );
  }
  if (article.cate && typeof article.cate === "object") {
    const v = article.cate._id || article.cate.id;
    if (typeof v === "string") ids.push(v);
  }
  if (typeof article.cate === "string") ids.push(article.cate);

  return uniqStrings(ids);
};

const filteredArticles = computed(() => {
  const cateId = activeCateId.value;
  if (!cateId) return allArticles.value;
  return allArticles.value.filter((article) => getArticleCateIds(article).includes(cateId));
});

const relatedCateIdSet = computed(() => {
  const set = new Set();
  for (const article of allArticles.value) {
    for (const cateId of getArticleCateIds(article)) set.add(cateId);
  }
  return set;
});

const refreshList = (reset = false) => {
  if (reset) {
    page.value = 1;
    list.value = [];
  }

  const rows = filteredArticles.value || [];
  total.value = rows.length;

  const start = (page.value - 1) * pageSize;
  const end = start + pageSize;
  const slice = rows.slice(start, end);

  if (page.value === 1) list.value = slice;
  else list.value = [...list.value, ...slice];
};

const loadEnabledArticles = async () => {
  if (!corpId.value || enabledIds.value.length === 0) {
    allArticles.value = [];
    tabs.value = [getAllTab()];
    refreshList(true);
    return;
  }
  if (loading.value) return;

  loading.value = true;
  try {
    const ids = enabledIds.value;
    const res = await api("getArticleByIds", { corpId: corpId.value, ids: ids.join(",") });
    const rows = res && Array.isArray(res.list) ? res.list : [];

    const order = new Map(ids.map((id, idx) => [id, idx]));
    allArticles.value = rows
      .map((r) => ({
        ...r,
        time: r?.createTime ? dayjs(r.createTime).format("YYYY-MM-DD") : "",
      }))
      .sort((a, b) => (order.get(a?._id) ?? 1e9) - (order.get(b?._id) ?? 1e9));
  } catch (err) {
    console.error("loadEnabledArticles failed:", err);
    allArticles.value = [];
  } finally {
    loading.value = false;
  }
};

const loadTabs = async () => {
  if (!corpId.value) return;

  const related = relatedCateIdSet.value;
  if (!related.size) {
    tabs.value = [getAllTab()];
    return;
  }

  try {
    const res = await api("getArticleCateList", { corpId: corpId.value });
    const cates = res && Array.isArray(res.list) ? res.list : [];
    const visible = cates.filter((c) => related.has(c?._id));

    tabs.value = [
      getAllTab(),
      ...visible.map((i) => ({ name: i.label || i.name || "", value: i._id })),
    ];
  } catch (err) {
    console.error("loadTabs failed:", err);
    tabs.value = [getAllTab()];
  }
};

const loadCates = async () => {
  if (!corpId.value) return;
  try {
    const res = await api("getArticleCateList", { corpId: corpId.value });
    const cates = res && Array.isArray(res.list) ? res.list : [];
    tabs.value = [
      { name: "全部", value: "" },
      ...cates.map((i) => ({ name: i.label || i.name || "未命名", value: i._id })),
    ];
  } catch (err) {
    console.error("loadCates failed:", err);
  }
};

const loadList = async (reset = false) => {
  if (!corpId.value || loading.value) return;
  if (reset) {
    page.value = 1;
    list.value = [];
    total.value = 0;
  }
  loading.value = true;
  try {
    const params = {
      corpId: corpId.value,
      page: page.value,
      pageSize,
      enable: true,
    };
    if (activeCateId.value) params.cateIds = [activeCateId.value];
    const res = await api("getArticleList", params);
    const rows = res && Array.isArray(res.list) ? res.list : [];
    total.value = Number(res?.total) || 0;
    const mapped = rows.map((r) => ({
      ...r,
      time: r?.createTime ? dayjs(r.createTime).format("YYYY-MM-DD") : "",
    }));
    if (page.value === 1) list.value = mapped;
    else list.value = [...list.value, ...mapped];
  } catch (err) {
    console.error("loadList failed:", err);
  } finally {
    loading.value = false;
  }
};

const selectCate = async (cateId) => {
  if (activeCateId.value === cateId) return;
  activeCateId.value = cateId;
  refreshList(true);
};

function goToDetail(item) {
  if (!item?._id) return;
  uni.navigateTo({ url: `/pages/article/article-detail?id=${item._id}&corpId=${corpId.value}` });
}

onLoad(async (options) => {
  corpId.value = options?.corpId || "";
  enabledIds.value = parseIdsParam(options?.ids);
  activeCateId.value = "";
  await loadEnabledArticles();
  await loadTabs();
  refreshList(true);
});

onReachBottom(() => {
  if (loading.value) return;
  if (list.value.length >= total.value) return;
  page.value += 1;
  refreshList(false);
});
</script>

<style scoped>
.min-h-screen {
  min-height: 100vh;
}

.bg-gray-100 {
  background-color: #f7f8fa;
}

.bg-white {
  background-color: #ffffff;
}

.p-15 {
  padding: 30rpx;
}

.px-15 {
  padding-left: 30rpx;
  padding-right: 30rpx;
}

.py-10 {
  padding-top: 20rpx;
  padding-bottom: 20rpx;
}

.py-5 {
  padding-top: 10rpx;
  padding-bottom: 10rpx;
}

.px-5 {
  padding-left: 10rpx;
  padding-right: 10rpx;
}

.mr-10 {
  margin-right: 20rpx;
}

.mr-5 {
  margin-right: 10rpx;
}

.ml-2 {
  margin-left: 10rpx;
}

.mr-2 {
  margin-right: 10rpx;
}

.mb-15 {
  margin-bottom: 20rpx;
}

.mb-10 {
  margin-bottom: 20rpx;
}

.mt-1 {
  margin-top: 6rpx;
}

.flex {
  display: flex;
}

.items-start {
  align-items: flex-start;
}

.items-center {
  align-items: center;
}

.justify-between {
  justify-content: space-between;
}

.flex-1 {
  flex: 1;
}

.flex-grow {
  flex-grow: 1;
}

.flex-shrink-0 {
  flex-shrink: 0;
}

.w-0 {
  width: 0;
}

.relative {
  position: relative;
}

.border {
  border-width: 1px;
  border-style: solid;
}

.rounded-full {
  border-radius: 9999px;
}

.rounded {
  border-radius: 8rpx;
}

.rounded-lg {
  border-radius: 12rpx;
}

.shadow-sm {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.text-xs {
  font-size: 24rpx;
}

.text-sm {
  font-size: 30rpx;
}

.text-base {
  font-size: 34rpx;
}

.font-bold {
  font-weight: 600;
}

.leading-normal {
  line-height: 1.4;
}

.text-orange-500 {
  color: #f29e38;
}

.bg-orange-100 {
  background-color: #fff8eb;
}

.border-orange-500 {
  border-color: #f29e38;
}

.text-gray-600 {
  color: #333333;
}

.text-gray-400 {
  color: #999999;
}

.text-gray-800 {
  color: #1a1a1a;
}

.border-gray-200 {
  border-color: #e5e5e5;
}

.text-green-600 {
  color: #4b8d5f;
}

.border-green-600 {
  border-color: #4b8d5f;
}

.sticky {
  position: sticky;
}

.top-0 {
  top: 0;
}

.z-10 {
  z-index: 10;
}

.w-full {
  width: 100%;
}

.whitespace-nowrap {
  white-space: nowrap;
}

.inline-block {
  display: inline-block;
}

.tag-box {
  border-radius: 4rpx;
  line-height: 1.2;
}

.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.article-card {
  background: white;
  border-radius: 16rpx;
  box-shadow: 0 8rpx 10rpx 0 rgba(60, 169, 145, 0.06);
  transition: all 0.3s;
  min-height: 188rpx;
  padding: 20rpx;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
}

.article-card:active {
  transform: translateY(-2rpx);
  box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
}

.cover {
  width: 200rpx;
  height: 112rpx;
  border-radius: 12rpx;
  margin-right: 20rpx;
  object-fit: cover;
}

.article-title {
  color: #333333;
  font-size: 34rpx;
  font-weight: 500;
  line-height: normal;
}

.article-summary {
  max-width: 402rpx;
  color: #666666;
  text-align: justify;
  font-size: 30rpx;
  font-weight: 400;
  line-height: normal;
}

.line-clamp-2 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  line-height: 1.5;
}

.loading-container,
.empty-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 100rpx 0;
}

.loading-text {
  margin-top: 20rpx;
  font-size: 30rpx;
  color: #999;
}

.loading-more,
.no-more {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 30rpx 0;
  font-size: 26rpx;
  color: #999;
  gap: 10rpx;
}
</style>
