<template>
  <view class="news-list-container">
    <!-- 列表 -->
    <view v-if="list.length > 0" class="list">
      <view v-for="item in list" :key="item.id" class="news-item" @click="handleItemClick(item)">
        <view v-if="item.coverImage" class="img-wrap">
          <image class="cover-img" :src="imgUrl + item.coverImage" mode="aspectFill" />
        </view>
        <view class="info">
          <view class="title">{{ item.title }}</view>
          <view class="subtitle">{{ item.subTitle }}</view>
          <view class="meta">
            <text class="date">{{ formatDate(item.deliveryTime) }}</text>
          </view>
        </view>
      </view>
    </view>

    <!-- 空状态 -->
    <view v-else-if="!loading && finished" class="empty">
      <cwg-empty-state />
    </view>
    <view class="table-loading-mask">
      <uni-loading v-if="loading" />
    </view>

    <!-- 加载更多状态 -->
    <view v-if="loadingMore" class="load-more">
      <text v-t11="'common.loading'" />
    </view>
    <view v-else-if="finished && list.length > 0" class="load-more">
      <text v-t11="'common.noMore'" />
    </view>
  </view>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import Config from '@/config/index'
const { locale } = useI18n()

const props = defineProps({
  fetchData: { type: Function, required: true },
  queryParams: { type: Object, default: () => ({}) },
  pageSize: { type: Number, default: 10 },
  type: { type: Number, default: 0 },
  immediate: { type: Boolean, default: true },
})
const imgUrl = computed(() => props.queryParams.tag !== 3 ? Config.Host80 : Config.Host05)

const list = ref([])
const page = ref(1)
const loading = ref(false)
const loadingMore = ref(false)
const finished = ref(false)
const total = ref(0)

const formatDate = (dateStr) => {
  if (!dateStr) return ''
  return dateStr.slice(0, 10).replace('T', ' ')
}

const load = async () => {
  list.value = []
  if (loading.value) return
  loading.value = true
  finished.value = false
  page.value = 1

  try {
    const res = await props.fetchData({
      lang: locale.value == 'vn' ? 'vi' : locale.value,
      page: { current: page.value, row: props.queryParams?.pageSize || props.pageSize },
      ...props.queryParams
    })
    if (res.code === 200) {
      list.value = res.data || []
      total.value = res.page?.rowTotal || 0
      finished.value = list.value.length >= total.value
    } else {
      throw new Error(res.msg || '请求失败')
    }
  } catch (err) {
    console.error('加载失败', err)
    uni.showToast({ title: err.message || '加载失败', icon: 'none' })
  } finally {
    loading.value = false
  }
}

const loadMore = async () => {
  if (loadingMore.value || finished.value) return
  loadingMore.value = true
  try {
    const nextPage = page.value + 1
    const params = {
      lang: locale.value,
      page: { current: nextPage, row: props.queryParams?.pageSize || props.pageSize },
      ...props.queryParams
    }
    const res = await props.fetchData(params)
    if (res.code === 200) {
      const newList = res.data || []
      if (newList.length > 0) {
        list.value.push(...newList)
        page.value = nextPage
      }
      const totalRows = res.page?.rowTotal || total.value
      finished.value = list.value.length >= totalRows
    } else {
      throw new Error(res.msg || '请求失败')
    }
  } catch (err) {
    uni.showToast({ title: err.message || '加载更多失败', icon: 'none' })
  } finally {
    loadingMore.value = false
  }
}

const handleItemClick = (item) => {
  uni.navigateTo({ url: `/pages/analytics/detail?type=${props.type}&id=${item.id}` })
}

const lang = computed(() => uni.getLocale())
watch(lang, () => {
  load()
}, { immediate: true })

defineExpose({ load, loadMore })
</script>

<style lang="scss" scoped>
@import "@/uni.scss";

.news-list-container {
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;

  .list {
    display: grid;
    grid-row-gap: px2rpx(20);
    grid-column-gap: px2rpx(16);
    grid-template-columns: repeat(3, 1fr);

    @media screen and (max-width: 768px) {
      grid-template-columns: 1fr;
    }

    width: 100%;
    box-sizing: border-box;
  }

  .news-item {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
    padding: px2rpx(16);
    gap: px2rpx(12);
    background: #fff;
    border-radius: px2rpx(12);
    overflow: hidden;
    box-shadow:
      0 2rpx 8rpx rgba(0, 0, 0, 0.04),
      0 1rpx 2rpx rgba(0, 0, 0, 0.06);
    box-sizing: border-box;
    transition: all 0.3s ease;
    border: 1rpx solid rgba(0, 0, 0, 0.03);

    &:active {
      transform: scale(0.98);
      box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.08);
    }

    /* #ifdef H5 */
    &:hover {
      transform: translateY(-4rpx);
      box-shadow:
        0 8rpx 24rpx rgba(0, 0, 0, 0.08),
        0 4rpx 8rpx rgba(0, 0, 0, 0.06);
    }

    &:hover .img-wrap .cover-img {
      transform: scale(1.05);
    }

    /* #endif */

    .img-wrap {
      width: 100%;
      height: px2rpx(220);
      border-radius: px2rpx(8);
      overflow: hidden;
      flex-shrink: 0;
      position: relative;
      background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%);
    }

    .cover-img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .info {
      flex: 1;
      width: 100%;
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      min-height: px2rpx(120);
    }

    .title {
      font-size: px2rpx(17);
      font-weight: 600;
      color: var(--bs-emphasis-color);
      line-height: 1.5;
      margin-bottom: px2rpx(8);
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      overflow: hidden;
      letter-spacing: 0.3rpx;
    }

    .subtitle {
      font-size: px2rpx(14);
      color: #666666;
      line-height: 1.6;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      overflow: hidden;
      margin-bottom: px2rpx(10);
    }

    .meta {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      font-size: px2rpx(12);
      color: #999999;
      padding-top: px2rpx(8);
      border-top: 1rpx solid #f0f0f0;
    }
  }
}

.load-more {
  text-align: center;
  padding: px2rpx(10);
  font-size: px2rpx(14);
  color: var(--bs-heading-color);
}

.empty {
  text-align: center;
  padding: 100rpx 0;
  color: var(--bs-heading-color);
  font-size: px2rpx(14);
}
</style>