<template>
  <view class="admin-marketing-integral-product">
    <view class="content-body">
      <!-- 搜索过滤栏 -->
      <view class="filter-card border-shadow">
        <view class="filter-row">
          <view class="filter-item">
            <text class="label-txt">创建时间:</text>
            <view class="date-picker-mock">
              <text class="calendar-ic">📅</text>
              <text class="date-placeholder">开始日期 - 结束日期</text>
            </view>
          </view>
          <view class="filter-item">
            <text class="label-txt">上架状态:</text>
            <picker
              mode="selector"
              :range="statusOptions"
              range-key="label"
              @change="handleStatusChange"
            >
              <view class="select-mock">
                <text class="select-val">{{ currentStatusLabel }}</text>
                <text class="arrow-down">▼</text>
              </view>
            </picker>
          </view>
          <view class="filter-item">
            <text class="label-txt">商品搜索:</text>
            <input class="search-input" placeholder="请输入商品名称, ID" v-model="searchQuery" />
          </view>
          <view class="btn-query" @click="handleSearch">
            <text class="query-txt">查询</text>
          </view>
        </view>
      </view>

      <!-- 主要内容区域 -->
      <view class="table-card border-shadow">
        <view class="card-header">
          <view class="btn-primary-blue" @click="handleAdd">
            <text class="btn-txt">+ 添加积分商品</text>
          </view>
        </view>

        <!-- 表格 -->
        <view class="table-container">
          <view class="table-header-row">
            <view class="th th-id">ID</view>
            <view class="th th-img">商品图片</view>
            <view class="th th-title">活动标题</view>
            <view class="th th-integral">兑换积分</view>
            <view class="th th-limit">限量</view>
            <view class="th th-remain">限量剩余</view>
            <view class="th th-time">创建时间</view>
            <view class="th th-sort">排序</view>
            <view class="th th-status">状态</view>
            <view class="th th-ops">操作</view>
          </view>

          <view class="table-body">
            <!-- 加载中状态 -->
            <view v-if="loading" class="empty-row">
              <text class="empty-txt">加载中...</text>
            </view>
            <!-- 空状态 -->
            <view v-else-if="productList.length === 0" class="empty-row">
              <text class="empty-txt">暂无积分商品</text>
            </view>
            <!-- 数据行 -->
            <view v-else v-for="(item, index) in productList" :key="item.id" class="table-row">
              <view class="td td-id"><text class="td-txt-small td-id-val">{{ item.id }}</text></view>
              <view class="td td-img">
                <image class="product-thumb" :src="item.image" mode="aspectFill"></image>
              </view>
              <view class="td td-title">
                <view class="title-cell">
                  <text class="title-txt line-clamp-2">{{ item.title }}</text>
                  <view v-if="item.productType" class="type-tag">
                    <text class="type-tag-txt">{{ getProductTypeLabel(item.productType) }}</text>
                  </view>
                </view>
              </view>
              <view class="td td-integral"><text class="td-txt">{{ item.integral }}</text></view>
              <view class="td td-limit"><text class="td-txt">{{ item.limit }}</text></view>
              <view class="td td-remain"><text class="td-txt">{{ item.remain }}</text></view>
              <view class="td td-time"><text class="td-txt-small">{{ item.createTime }}</text></view>
              <view class="td td-sort"><text class="td-txt">{{ item.sort }}</text></view>
              <view class="td td-status">
                <view :class="['switch-box', item.status ? 'active' : '']" @click="toggleStatus(index)">
                  <view class="switch-dot"></view>
                </view>
              </view>
              <view class="td td-ops">
                <view class="op-links">
                  <text class="op-link">兑换记录</text>
                  <text class="op-split">|</text>
                  <text class="op-link" @click="handleEdit(item)">编辑</text>
                  <text class="op-split">|</text>
                  <text class="op-link">复制</text>
                  <text class="op-split">|</text>
                  <text class="op-link text-danger">删除</text>
                </view>
              </view>
            </view>
          </view>
        </view>

        <!-- 分页 -->
        <CommonPagination
          v-if="total > 0"
          :total="total"
          :loading="false"
          :currentPage="currentPage"
          :pageSize="pageSize"
          :pageSizeOptionLabels="pageSizeOptionLabels"
          :pageSizeIndex="pageSizeIndex"
          :visiblePages="visiblePages"
          :totalPage="totalPage"
          :jumpPageInput="jumpPageInput"
          @page-size-change="handlePageSizeChange"
          @page-change="handlePageChange"
          @update:jumpPageInput="(val : string) => { jumpPageInput = val }"
          @jump-page="handleJumpPage"
        />
      </view>
    </view>
  </view>
</template>

<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'
import supa from '@/components/supadb/aksupainstance.uts'

// ──────────────────────────────────────────────
// 数据结构（对应 ml_point_products 真实字段）
// ──────────────────────────────────────────────
interface PointProductItem {
  id: string           // UUID
  image: string        // image_url，为空时用默认占位
  title: string        // name
  productType: string  // product_type：physical/coupon/virtual
  integral: number     // points_required
  originalPrice: string // original_price，格式化后
  limit: number        // stock
  remain: string       // 数据库无此字段，固定显示 '-'
  createTime: string   // created_at，格式化后
  sort: number         // sort_order
  status: boolean      // status === 1
}

// 商品类型标签映射
function getProductTypeLabel(type: string): string {
  if (type === 'physical') return '实物'
  if (type === 'coupon') return '优惠券'
  if (type === 'virtual') return '虚拟'
  return type
}

// 时间格式化：2026-03-05T09:27:20.672132+00:00 → 2026-03-05 17:27:20
function formatDateTime(raw: string): string {
  if (!raw) return '-'
  try {
    const d = new Date(raw)
    const pad = (n: number): string => n < 10 ? '0' + n : '' + n
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
  } catch (_) {
    return raw
  }
}

// 将数据库原始行映射为页面展示对象（统一转换层）
function mapPointProduct(row: UTSJSONObject): PointProductItem {
  const rawPrice = row.get('original_price')
  const priceNum = rawPrice != null ? Number(rawPrice) : 0
  return {
    id: (row.get('id') as string) ?? '-',
    image: (row.get('image_url') as string) || '/static/image/default-product.png',
    title: (row.get('name') as string) || '未命名商品',
    productType: (row.get('product_type') as string) || '',
    integral: row.get('points_required') != null ? Number(row.get('points_required')) : 0,
    originalPrice: priceNum > 0 ? '¥' + priceNum.toFixed(2) : '-',
    limit: row.get('stock') != null ? Number(row.get('stock')) : 0,
    remain: '-',        // 数据库暂无剩余库存字段
    createTime: formatDateTime((row.get('created_at') as string) ?? ''),
    sort: row.get('sort_order') != null ? Number(row.get('sort_order')) : 0,
    status: Number(row.get('status')) === 1,
  }
}

// ──────────────────────────────────────────────
// 搜索条件状态
// ──────────────────────────────────────────────
const searchQuery = ref('')       // 商品名称搜索
const statusFilter = ref(-1)      // -1 = 全部；1 = 上架；0 = 下架

// 状态下拉选项
const statusOptions = [
  { label: '全部', value: -1 },
  { label: '上架', value: 1 },
  { label: '下架', value: 0 },
]
const currentStatusLabel = computed(() => {
  const found = statusOptions.find((o) => o.value === statusFilter.value)
  return found != null ? found.label : '请选择'
})
const handleStatusChange = (e: any) => {
  const idx = Number(e.detail.value)
  statusFilter.value = statusOptions[idx]?.value ?? -1
}

// ──────────────────────────────────────────────
// 列表 & 分页状态
// ──────────────────────────────────────────────
const productList = ref<PointProductItem[]>([])
const total = ref(0)
const loading = ref(false)

const currentPage = ref(1)
const pageSize = ref(15)
let jumpPageInput = ''
const pageSizeOptions = [10, 15, 20, 30, 50]
const pageSizeOptionLabels = computed(() => pageSizeOptions.map((n: number) => `${n}条/页`))
const pageSizeIndex = computed(() => {
  const idx = pageSizeOptions.indexOf(pageSize.value)
  return idx >= 0 ? idx : 0
})
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const visiblePages = computed(() => {
  const t = totalPage.value
  const cur = currentPage.value
  if (t <= 7) return Array.from({ length: t }, (_: any, i: number) => i + 1)
  if (cur <= 4) return [1, 2, 3, 4, 5, -1, t]
  if (cur >= t - 3) return [1, -1, t - 4, t - 3, t - 2, t - 1, t]
  return [1, -1, cur - 1, cur, cur + 1, -1, t]
})

// ──────────────────────────────────────────────
// 核心：服务端分页查询（只请求当前页）
// ──────────────────────────────────────────────
async function fetchProducts() {
  if (loading.value) return
  loading.value = true
  try {
    const query = supa
      .from('ml_point_products')
      .select('id, name, image_url, product_type, points_required, original_price, stock, status, sort_order, created_at')

    // 状态筛选
    if (statusFilter.value === 1) {
      query.eq('status', 1)
    } else if (statusFilter.value === 0) {
      query.neq('status', 1)
    }

    // 商品名称模糊搜索
    if (searchQuery.value.trim() !== '') {
      query.ilike('name', '%' + searchQuery.value.trim() + '%')
    }

    const { data, error, total: serverTotal } = await query
      .order('sort_order', { ascending: true })
      .limit(pageSize.value)
      .page(currentPage.value)
      .execute()

    if (error) {
      uni.showToast({ title: '加载失败: ' + (error as UTSJSONObject).getString('message'), icon: 'none' })
      return
    }

    if (data != null) {
      const rows = data as Array<UTSJSONObject>
      productList.value = rows.map((row: UTSJSONObject): PointProductItem => mapPointProduct(row))
      total.value = serverTotal > 0 ? serverTotal : rows.length
    } else {
      productList.value = []
      total.value = 0
    }
  } catch (err: any) {
    console.error('[PointProducts] 加载失败:', err)
    uni.showToast({ title: '加载失败: ' + (err.message || '请检查网络'), icon: 'none' })
  } finally {
    loading.value = false
  }
}

// ──────────────────────────────────────────────
// 状态切换（同步写回数据库）
// ──────────────────────────────────────────────
async function toggleStatus(index: number) {
  const item = productList.value[index]
  const newStatus = item.status ? 0 : 1
  try {
    const { error } = await supa
      .from('ml_point_products')
      .update({ status: newStatus } as UTSJSONObject)
      .eq('id', item.id)
      .execute()
    if (error) {
      uni.showToast({ title: '状态更新失败', icon: 'none' })
      return
    }
    productList.value[index].status = !item.status
  } catch (err: any) {
    console.error('[PointProducts] 状态更新失败:', err)
    uni.showToast({ title: '操作失败', icon: 'none' })
  }
}

// ──────────────────────────────────────────────
// 搜索 / 翻页 / 切换 pageSize
// ──────────────────────────────────────────────
const handleSearch = () => {
  currentPage.value = 1
  fetchProducts()
}
const handleAdd = () => { console.log('Adding...') }
const handleEdit = (item: PointProductItem) => { console.log('Editing...', item.id) }

const handlePageChange = (p: number) => {
  currentPage.value = p
  fetchProducts()
}
const handlePageSizeChange = (e: any) => {
  const idx = Number(e.detail.value)
  pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[0]
  currentPage.value = 1
  fetchProducts()
}
const handleJumpPage = () => {
  const p = parseInt(jumpPageInput)
  if (!isNaN(p) && p >= 1 && p <= totalPage.value) {
    currentPage.value = p
    fetchProducts()
  }
}

// ──────────────────────────────────────────────
// 生命周期
// ──────────────────────────────────────────────
onMounted(() => {
  fetchProducts()
})
</script>

<style scoped lang="scss">
.admin-marketing-integral-product {
  padding: 0;
  background-color: transparent;
  min-height: auto;
}

.border-shadow {
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.content-body {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* 过滤栏 */
.filter-card {
  padding: 24px;
}

.filter-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 24px;
}

.filter-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.label-txt { font-size: 14px; color: #606266; white-space: nowrap; }

.date-picker-mock {
  width: 280px;
  height: 32px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 0 12px;
  gap: 8px;
}
.calendar-ic { font-size: 14px; color: #c0c4cc; }
.date-placeholder { font-size: 13px; color: #c0c4cc; }

.select-mock {
  width: 180px;
  height: 32px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0 12px;
}
.select-val { font-size: 14px; color: #606266; }
.arrow-down { font-size: 10px; color: #c0c4cc; }

.search-input {
  width: 220px;
  height: 32px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 0 12px;
  font-size: 13px;
}

.btn-query {
  background-color: #2d8cf0;
  padding: 0 20px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  cursor: pointer;
}
.query-txt { color: #fff; font-size: 14px; }

/* 表格卡片 */
.table-card {
  background-color: #fff;
}

.card-header { padding: 20px; }

.btn-primary-blue {
  background-color: #2d8cf0;
  padding: 8px 16px;
  border-radius: 4px;
  display: inline-flex;
}
.btn-txt { color: #fff; font-size: 14px; }

.table-container { padding: 0 20px 20px; }

.table-header-row {
  display: flex;
  flex-direction: row;
  background-color: #f8f8f9;
  border-bottom: 1px solid #e8eaec;
}

.th {
  padding: 12px 10px;
  font-size: 14px;
  color: #515a6e;
  font-weight: bold;
  display: flex;
  align-items: center;
}

.table-row {
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #e8eaec;
  align-items: center;
}

.td {
  padding: 12px 10px;
  display: flex;
  align-items: center;
}

.td-txt { font-size: 14px; color: #515a6e; }
.td-txt-small { font-size: 13px; color: #515a6e; }

/* 列表各列宽度控制 */
/* .th-id, .td-id 宽度在下方覆盖为 160px（UUID 展示需要） */
.th-img, .td-img { width: 80px; }
.th-title, .td-title { flex: 1; min-width: 200px; }
.th-integral, .td-integral { width: 100px; }
.th-limit, .td-limit { width: 80px; }
.th-remain, .td-remain { width: 100px; }
.th-time, .td-time { width: 160px; }
.th-sort, .td-sort { width: 80px; }
.th-status, .td-status { width: 80px; }
.th-ops, .td-ops { width: 220px; justify-content: flex-end; }

.product-thumb {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background-color: #f5f5f5;
}

.title-txt { font-size: 13px; color: #333; line-height: 1.5; }
.line-clamp-2 {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

/* Switch 开关 */
.switch-box {
  width: 44px;
  height: 22px;
  background-color: #dcdfe6;
  border-radius: 11px;
  position: relative;
  transition: background-color 0.3s;
  cursor: pointer;
}
.switch-box.active { background-color: #2d8cf0; }
.switch-dot {
  width: 18px;
  height: 18px;
  background-color: #fff;
  border-radius: 9px;
  position: absolute;
  top: 2px;
  left: 2px;
  transition: transform 0.3s;
}
.switch-box.active .switch-dot { transform: translateX(22px); }

.op-links { display: flex; flex-direction: row; align-items: center; }
.op-link { color: #2d8cf0; font-size: 13px; cursor: pointer; margin: 0 5px; }
.op-split { color: #e8eaec; margin: 0 5px; }
.text-danger { color: #ed4014; }

/* 分页区域已迁至 CommonPagination 组件 */

/* ID 列：UUID 需要更多宽度 */
.th-id, .td-id { width: 160px; }
.td-id-val { font-size: 11px; color: #aaa; word-break: break-all; }

/* 商品标题单元格：名称 + 类型标签 */
.title-cell {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.type-tag {
  display: inline-flex;
  align-items: center;
  background-color: #ecf5ff;
  border-radius: 3px;
  padding: 1px 6px;
  align-self: flex-start;
}
.type-tag-txt { font-size: 11px; color: #409eff; }

/* 空状态 / 加载中行 */
.empty-row {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 48px 0;
  width: 100%;
}
.empty-txt { font-size: 14px; color: #999; }

</style>

