<!-- Admin 店铺列表管理页 (role=admin 专用)
     数据来源: ml_shops 真实数据，服务端分页，按需请求
-->
<template>
  <view class="shop-list-page">
    <!-- 1. 搜索筛选区 -->
    <view class="search-card">
      <view class="search-row">
        <view class="search-item">
          <text class="label">注册时间：</text>
          <view class="date-range-row">
            <input class="mock-input date-input" v-model="startTime" placeholder="开始 2025-01-01" />
            <text class="date-sep">~</text>
            <input class="mock-input date-input" v-model="endTime" placeholder="结束 2025-12-31" />
          </view>
        </view>
        <view class="search-item">
          <text class="label">店铺状态：</text>
          <picker :range="statusLabels" :value="statusPickerIndex" @change="onStatusChange">
            <view class="mock-select">
              <text>{{ statusLabels[statusPickerIndex] }}</text>
              <text class="arrow">▼</text>
            </view>
          </picker>
        </view>
      </view>
      <view class="search-row mt-16">
        <view class="search-item">
          <text class="label">店铺名称：</text>
          <input class="mock-input" v-model="searchName" placeholder="请输入店铺名称" />
        </view>
        <button class="btn-primary" @click="onSearch">查询</button>
        <button class="btn-white" @click="onReset">重置</button>
      </view>
    </view>

    <!-- 2. 数据表格 -->
    <view class="list-card">
      <!-- 错误提示 -->
      <view v-if="fetchError !== ''" class="error-tip">
        <text class="error-txt">{{ fetchError }}</text>
        <button class="btn-white btn-sm mt-8" @click="loadShops(1)">重试</button>
      </view>

      <!-- 加载中 -->
      <view v-if="loading" class="loading-tip">
        <text class="loading-txt">加载中...</text>
      </view>

      <view class="table-v5">
        <!-- 表头 -->
        <view class="th-row">
          <view class="th col-logo"><text>Logo</text></view>
          <view class="th col-name"><text>店铺名称</text></view>
          <view class="th col-cid"><text>编号</text></view>
          <view class="th col-merchant"><text>商户ID</text></view>
          <view class="th col-contact"><text>联系人/电话</text></view>
          <view class="th col-status"><text>状态</text></view>
          <view class="th col-stats"><text>商品/订单</text></view>
          <view class="th col-rating"><text>评分/评价</text></view>
          <view class="th col-verify"><text>认证</text></view>
          <view class="th col-time"><text>注册时间</text></view>
          <view class="th col-op"><text>操作</text></view>
        </view>

        <!-- 空态 -->
        <view v-if="shopList.length === 0 && !loading && fetchError === ''" class="empty-row">
          <text class="empty-txt">暂无店铺数据</text>
        </view>

        <!-- 数据行 -->
        <view v-for="item in shopList" :key="item.id" class="tr-row">
          <!-- Logo -->
          <view class="td col-logo">
            <image
              v-if="item.shop_logo != null && item.shop_logo !== ''"
              class="shop-logo-img"
              :src="item.shop_logo"
              mode="aspectFill"
            />
            <view v-else class="logo-placeholder">
              <text class="logo-placeholder-txt">无</text>
            </view>
          </view>

          <!-- 店铺名称 -->
          <view class="td col-name">
            <text class="shop-name-txt">{{ item.shop_name !== '' ? item.shop_name : '—' }}</text>
          </view>

          <!-- 编号 -->
          <view class="td col-cid">
            <text class="cid-txt">{{ item.cid > 0 ? item.cid : '—' }}</text>
          </view>

          <!-- 商户ID（截短） -->
          <view class="td col-merchant">
            <text class="merchant-txt">{{ item.merchant_id !== '' ? item.merchant_id.substring(0, 8) + '...' : '—' }}</text>
          </view>

          <!-- 联系人/电话 -->
          <view class="td col-contact">
            <text class="contact-name">{{ item.contact_name != null && item.contact_name !== '' ? item.contact_name : '—' }}</text>
            <text class="contact-phone">{{ item.contact_phone != null && item.contact_phone !== '' ? item.contact_phone : '' }}</text>
          </view>

          <!-- 状态 -->
          <view class="td col-status">
            <text class="status-tag" :class="getStatusClass(item.status)">
              {{ getStatusText(item.status) }}
            </text>
          </view>

          <!-- 商品/订单数 -->
          <view class="td col-stats">
            <text class="stats-txt">{{ item.product_count }} / {{ item.order_count }}</text>
          </view>

          <!-- 评分/评价数 -->
          <view class="td col-rating">
            <text class="rating-txt">{{ formatRating(item.rating_avg) }} ({{ item.rating_count }})</text>
          </view>

          <!-- 认证状态 -->
          <view class="td col-verify">
            <text class="verify-tag" :class="item.verified_at != null && item.verified_at !== '' ? 'verified' : 'unverified'">
              {{ item.verified_at != null && item.verified_at !== '' ? '已认证' : '未认证' }}
            </text>
          </view>

          <!-- 注册时间 -->
          <view class="td col-time">
            <text>{{ formatTime(item.created_at) }}</text>
          </view>

          <!-- 操作列 -->
          <view class="td col-op">
            <text
              v-if="item.status !== 1"
              class="op-link green"
              @click="handleStatusChange(item.id, 1)"
            >启用</text>
            <text
              v-if="item.status === 1"
              class="op-link warn"
              @click="handleStatusChange(item.id, 2)"
            >暂停</text>
            <text
              v-if="item.status !== 3"
              class="op-link red"
              @click="handleStatusChange(item.id, 3)"
            >关闭</text>
          </view>
        </view>
      </view>

      <!-- 分页 -->
      <CommonPagination
        v-if="total > 0"
        :total="total"
        :loading="loading"
        :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>
</template>

<script setup lang="uts">
import { ref, computed, onMounted } from 'vue'
import CommonPagination from '@/components/CommonPagination/CommonPagination.uvue'
import {
  fetchAdminShops,
  updateAdminShopStatus,
  type AdminShopItem
} from '@/services/admin/shopManageService.uts'

// ========== 搜索筛选状态 ==========
const searchName = ref('')
const startTime = ref('')
const endTime = ref('')
// index 0 → 全部(null), 1 → 正常(1), 2 → 暂停(2), 3 → 关闭(3)
const statusLabels = ['全部', '正常营业', '暂停营业', '已关闭']
const statusPickerIndex = ref(0)

function onStatusChange(e : any) {
  statusPickerIndex.value = Number(e.detail.value)
}

// ========== 数据状态 ==========
const loading = ref(false)
const fetchError = ref('')
const shopList = ref<AdminShopItem[]>([])

// ========== 数据加载（服务端分页，点第几页才请求第几页） ==========
async function loadShops(page : number) {
  if (loading.value) return
  loading.value = true
  fetchError.value = ''
  try {
    // statusPickerIndex: 0=全部, 1~3=对应 status 值
    const selectedStatus : number | null = statusPickerIndex.value === 0 ? null : statusPickerIndex.value
    const result = await fetchAdminShops({
      searchName: searchName.value !== '' ? searchName.value : null,
      status: selectedStatus,
      startTime: startTime.value !== '' ? startTime.value : null,
      endTime: endTime.value !== '' ? endTime.value : null,
      page: page,
      pageSize: pageSize.value
    })
    shopList.value = result.items
    total.value = result.total
    currentPage.value = page
  } catch (e) {
    fetchError.value = '加载失败，请稍后重试'
    console.error('[shop-manage] 加载店铺列表失败:', e)
  } finally {
    loading.value = false
  }
}

function onSearch() {
  loadShops(1)
}

function onReset() {
  searchName.value = ''
  startTime.value = ''
  endTime.value = ''
  statusPickerIndex.value = 0
  loadShops(1)
}

onMounted(() => {
  loadShops(1)
})

// ========== 字段格式化 ==========
function formatTime(t : string | null) : string {
  if (t == null || t === '') return '—'
  return t.replace('T', ' ').substring(0, 16)
}

function formatRating(val : number) : string {
  if (val == null || val === 0) return '—'
  return val.toFixed(1)
}

// status: 1=正常营业 2=暂停营业 3=已关闭
function getStatusText(status : number) : string {
  if (status === 1) return '正常营业'
  if (status === 2) return '暂停营业'
  if (status === 3) return '已关闭'
  return '未知'
}

function getStatusClass(status : number) : string {
  if (status === 1) return 'normal'
  if (status === 2) return 'pause'
  if (status === 3) return 'closed'
  return 'unknown'
}

// ========== 操作：变更店铺状态 ==========
function handleStatusChange(id : string, targetStatus : number) {
  let msg = ''
  if (targetStatus === 1) msg = '确定要启用该店铺吗？'
  else if (targetStatus === 2) msg = '确定要暂停该店铺营业吗？'
  else if (targetStatus === 3) msg = '确定要关闭该店铺吗？此操作不可自动恢复。'

  uni.showModal({
    title: '操作确认',
    content: msg,
    success: async (res : any) => {
      if (res.confirm === true) {
        const ok = await updateAdminShopStatus(id, targetStatus)
        if (ok) {
          const label = targetStatus === 1 ? '已启用' : targetStatus === 2 ? '已暂停' : '已关闭'
          uni.showToast({ title: label, icon: 'success' })
          loadShops(currentPage.value)
        } else {
          uni.showToast({ title: '操作失败，请重试', icon: 'none' })
        }
      }
    }
  })
}

// ========== 分页状态（服务端分页） ==========
const currentPage = ref(1)
const pageSize = ref(20)
const jumpPageInput = ref('')
const pageSizeOptions = [10, 20, 30, 50]
const pageSizeOptionLabels = computed(() => pageSizeOptions.map((n : number) => `${n}条/页`))
const pageSizeIndex = computed(() => { const idx = pageSizeOptions.indexOf(pageSize.value); return idx >= 0 ? idx : 1 })
const total = ref(0)
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const visiblePages = computed((): number[] => {
  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]
})
const handlePageChange = (p : number) => {
  if (p < 1 || p > totalPage.value) return
  loadShops(p)
}
const handlePageSizeChange = (e : any) => {
  const idx = Number(e.detail.value)
  pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[1]
  loadShops(1)
}
const handleJumpPage = () => {
  const p = parseInt(jumpPageInput.value)
  if (!isNaN(p) && p >= 1 && p <= totalPage.value) {
    loadShops(p)
  }
}
// ========== END PAGINATION STATE ==========
</script>

<style scoped lang="scss">
.shop-list-page {
  padding: 0;
  background-color: transparent;
  min-height: auto;
}

/* 搜索区 */
.search-card {
  background: #fff;
  padding: var(--admin-card-padding, 16px 24px);
  border-radius: 4px;
  margin-bottom: var(--admin-section-gap, 16px);
}
.search-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}
.mt-16 { margin-top: 16px; }
.mt-8 { margin-top: 8px; }

.search-item {
  display: flex;
  flex-direction: row;
  align-items: center;
  .label { font-size: 14px; color: #606266; white-space: nowrap; }
}

.date-range-row {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  .date-sep { font-size: 13px; color: #606266; }
}

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

.btn-primary {
  height: 32px; padding: 0 16px; background: #1890ff; color: #fff;
  border: none; border-radius: 4px; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
.btn-white {
  height: 32px; padding: 0 16px; background: #fff; color: #606266;
  border: 1px solid #dcdfe6; border-radius: 4px; font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}
.btn-sm { height: 28px; padding: 0 12px; font-size: 12px; }

/* 错误/加载提示 */
.error-tip {
  padding: 16px 24px;
  display: flex; flex-direction: column; align-items: center;
}
.error-txt { font-size: 13px; color: #f56c6c; }
.loading-tip {
  padding: 32px; display: flex; align-items: center; justify-content: center;
}
.loading-txt { font-size: 14px; color: #999; }

/* 列表卡片 */
.list-card {
  background: #fff;
  border-radius: 4px;
  overflow: hidden;
}

/* 表格 */
.table-v5 {
  width: 100%;
  overflow-x: auto;
}
.th-row, .tr-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  border-bottom: 1px solid #f0f0f0;
  min-width: 1200px;
}
.th-row {
  background: #fafafa;
  font-weight: 600;
}
.th, .td {
  padding: 12px 8px;
  font-size: 13px;
  color: #515a6e;
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.th { color: #666; font-size: 12px; }
.tr-row:hover { background: #f5f7fa; }

/* 列宽 */
.col-logo    { width: 56px; justify-content: center; }
.col-name    { width: 160px; }
.col-cid     { width: 60px; justify-content: center; }
.col-merchant{ width: 110px; }
.col-contact { width: 140px; flex-direction: column; align-items: flex-start; }
.col-status  { width: 90px; justify-content: center; }
.col-stats   { width: 90px; justify-content: center; }
.col-rating  { width: 100px; justify-content: center; }
.col-verify  { width: 70px; justify-content: center; }
.col-time    { width: 140px; }
.col-op      { 
  flex: 1; 
  gap: 12px; 
  min-width: 100px; 
  display: flex; 
  flex-direction: row;  
}

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

/* Logo 图片 */
.shop-logo-img {
  width: 36px; height: 36px; border-radius: 4px; object-fit: cover;
}
.logo-placeholder {
  width: 36px; height: 36px; border-radius: 4px;
  background: #f0f0f0;
  display: flex; align-items: center; justify-content: center;
}
.logo-placeholder-txt { font-size: 10px; color: #bbb; }

/* 文本样式 */
.shop-name-txt { font-size: 13px; color: #303133; font-weight: 500; }
.cid-txt       { font-size: 12px; color: #909399; }
.merchant-txt  { font-size: 12px; color: #909399; font-family: monospace; }
.contact-name  { font-size: 13px; color: #303133; }
.contact-phone { font-size: 12px; color: #909399; }
.stats-txt     { font-size: 13px; color: #515a6e; }
.rating-txt    { font-size: 13px; color: #515a6e; }

/* 状态标签 */
.status-tag {
  padding: 2px 8px; border-radius: 3px; font-size: 12px;
  &.normal  { background: #f0f9eb; color: #67c23a; }
  &.pause   { background: #fdf6ec; color: #e6a23c; }
  &.closed  { background: #fef0f0; color: #f56c6c; }
  &.unknown { background: #f4f4f5; color: #909399; }
}

/* 认证标签 */
.verify-tag {
  padding: 2px 6px; border-radius: 3px; font-size: 12px;
  &.verified   { background: #e6f7ff; color: #1890ff; }
  &.unverified { background: #f4f4f5; color: #909399; }
}

/* 操作链接 */
.op-link {
  font-size: 13px; cursor: pointer;
  &.green { color: #67c23a; }
  &.warn  { color: #e6a23c; }
  &.red   { color: #f56c6c; }
}
</style>
