<template>
  <view class="admin-page">
    <view class="admin-sections">
      <!-- 筛选面板 -->
      <view class="admin-card filter-card">
        <view class="filter-row">
        <view class="filter-item">
          <text class="label">用户搜索：</text>
          <view class="input-group">
            <view class="compact-select">
              <text>请选择</text>
              <text class="arrow">▼</text>
            </view>
            <input class="filter-input" placeholder="请输入用户" />
          </view>
        </view>
        
        <view class="filter-item">
          <text class="label">用户等级：</text>
          <view class="filter-select">
            <text class="select-placeholder">请选择用户等级</text>
            <text class="arrow">▼</text>
          </view>
        </view>

        <view class="filter-item">
          <text class="label">用户分组：</text>
          <view class="filter-select">
            <text class="select-placeholder">请选择用户分组</text>
            <text class="arrow">▼</text>
          </view>
        </view>

        <view class="filter-btns">
          <button class="btn primary" @click="onSearch">搜索</button>
          <button class="btn" @click="onReset">重置</button>
          <text class="expand-btn">展开 ∨</text>
        </view>
      </view>
    </view>

    <!-- 内容卡片 -->
    <view class="admin-card content-card">
      <!-- 平台切换 Tabs -->
      <view class="tabs-row">
        <view 
          v-for="(tab, index) in tabs" 
          :key="index"
          class="tab-item"
          :class="{ active: activeTab === index }"
          @click="activeTab = index"
        >
          <text>{{ tab }}</text>
        </view>
      </view>

      <!-- 操作按钮行 -->
      <view class="action-bar">
        <button class="btn primary small" @click="onAddUser">添加用户</button>
        <button class="btn ghost small">发送优惠券</button>
        <button class="btn ghost small">发送图文消息</button>
        <button class="btn ghost small">批量设置分组</button>
        <button class="btn ghost small">批量设置标签</button>
        <button class="btn ghost small">导出</button>
      </view>

      <!-- 用户列表表格 -->
      <view class="table-container">
        <!-- 表头 -->
        <view class="table-header">
          <view class="col col-check"><checkbox :checked="isAllChecked" /></view>
          <view class="col col-expand"></view>
          <view class="col col-id"><text>用户ID</text></view>
          <view class="col col-avatar"><text>头像</text></view>
          <view class="col col-name"><text>姓名</text></view>
          <view class="col col-member"><text>付费会员</text></view>
          <view class="col col-level"><text>用户等级</text></view>
          <view class="col col-group"><text>分组</text></view>
          <view class="col col-spread"><text>分销等级</text></view>
          <view class="col col-phone"><text>手机号</text></view>
          <view class="col col-type"><text>用户类型</text></view>
          <view class="col col-balance sortable">
            <text>余额</text>
            <text class="sort-icon">↕</text>
          </view>
          <view class="col col-ops"><text>操作</text></view>
        </view>

        <!-- 表格内容 -->
        <view class="table-body">
          <!-- 加载中 -->
          <view v-if="loading" class="empty-state-row">
            <text class="empty-text">加载中...</text>
          </view>
          <!-- 错误状态 -->
          <view v-else-if="fetchError !== ''" class="empty-state-row">
            <text class="empty-text">{{ fetchError }}</text>
            <button class="btn small" @click="fetchUsers">重试</button>
          </view>
          <!-- 无数据 -->
          <view v-else-if="pagedList.length === 0" class="empty-state-row">
            <text class="empty-text">暂无用户数据</text>
          </view>
          <view v-for="user in pagedList" :key="user.id" class="table-row" 
            :style="{ zIndex: activeDropdownId === user.id ? 1000 : 1 }"
          >
            <view class="col col-check"><checkbox :checked="user.checked" /></view>
            <view class="col col-expand"><text class="expand-arrow">›</text></view>
            <view class="col col-id"><text>{{ user.id }}</text></view>
            <view class="col col-avatar">
              <image class="avatar-img" :src="user.avatar" mode="aspectFill" />
            </view>
            <view class="col col-name">
              <text class="name-text">{{ user.nickname }}</text>
            </view>
            <view class="col col-member">
              <text :class="user.isMember === '是' ? 'status-yes' : 'status-no'">{{ user.isMember }}</text>
            </view>
            <view class="col col-level"><text>{{ user.level }}</text></view>
            <view class="col col-group"><text>{{ user.group }}</text></view>
            <view class="col col-spread"><text>{{ user.spreadLevel }}</text></view>
            <view class="col col-phone"><text>{{ user.phone }}</text></view>
            <view class="col col-type"><text>{{ user.userType }}</text></view>
            <view class="col col-balance"><text>{{ user.balance }}</text></view>
            <view class="col col-ops">
              <text class="op-link" @click.stop="onDetail(user)">详情</text>
              <view class="op-divider">|</view>
              <view class="more-hover-container" 
                @mouseover="activeDropdownId = user.id" 
                @mouseleave="activeDropdownId = null"
                @click.stop="activeDropdownId = (activeDropdownId === user.id ? null : user.id)"
              >
                <view class="more-trigger pointer">
                  <text class="op-link">更多</text>
                  <text class="arrow">∨</text>
                </view>
                <view class="dropdown-list-box" v-if="activeDropdownId === user.id">
                  <view class="dropdown-arrow-top"></view>
                  <view class="dropdown-menu-list">
                    <text class="menu-item" @click.stop="uni.showToast({title:'修改余额', icon:'none'})">修改余额</text>
                    <text class="menu-item" @click.stop="uni.showToast({title:'修改积分', icon:'none'})">修改积分</text>
                    <text class="menu-item" @click.stop="uni.showToast({title:'赠送会员', icon:'none'})">赠送会员</text>
                    <text class="menu-item" @click.stop="uni.showToast({title:'设置分组', icon:'none'})">设置分组</text>
                    <text class="menu-item" @click.stop="uni.showToast({title:'设置标签', icon:'none'})">设置标签</text>
                    <text class="menu-item" @click.stop="uni.showToast({title:'修改上级推广人', icon:'none'})">修改上级推广人</text>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
      </view>

      <!-- 分页 -->
      <CommonPagination
        v-if="true"
        :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.value = 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 { supabase } from '@/components/supadb/aksupainstance.uts'

const activeTab = ref(0)
const tabs = ['全部', '微信公众号', '微信小程序', 'H5', 'PC', 'APP']
const isAllChecked = ref(false)
const activeDropdownId = ref<string | null>(null)

// ========== 用户展示行类型 ==========
type UserRow = {
  id: string
  avatar: string
  nickname: string
  isMember: string
  level: string
  group: string
  spreadLevel: string
  phone: string
  userType: string
  balance: string
  checked: boolean
}

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

// ========== 字段映射函数 ==========
function formatLevelDisplay(levelNum: number | null): string {
  if (levelNum == null || levelNum <= 1) return '无'
  return 'Lv.' + levelNum
}

function formatUserType(regSource: string | null, role: string | null): string {
  if (regSource === 'web') return 'PC/H5'
  if (regSource === 'mobile') return 'APP'
  if (regSource === 'wechat' || regSource === 'weixin') return '微信'
  if (role === 'admin') return '管理员'
  if (role === 'merchant') return '商家'
  if (role === 'delivery') return '配送员'
  return '用户'
}

function mapDbRow(row: UTSJSONObject): UserRow {
  const id = row.getString('id') ?? ''
  const avatarUrl = row.getString('avatar_url') ?? ''
  const username = row.getString('username') ?? ''
  const emailStr = row.getString('email') ?? ''
  // 昵称：优先 username，兜底取邮箱前缀，再兜底 '—'
  let nickname = '—'
  if (username !== '') {
    nickname = username
  } else if (emailStr !== '') {
    const atIdx = emailStr.indexOf('@')
    nickname = atIdx > 0 ? emailStr.substring(0, atIdx) : emailStr
  }
  const phone = row.getString('phone') ?? ''
  const regSource = row.getString('registration_source')
  const role = row.getString('role')
  const levelNum = row.getNumber('user_level')
  const avatarFinal = avatarUrl !== '' ? avatarUrl : '/static/logo.png'
  return {
    id: id,
    avatar: avatarFinal,
    nickname: nickname,
    isMember: '—',     // ak_users 无付费会员字段
    level: formatLevelDisplay(levelNum),
    group: '—',        // ak_users 无分组字段
    spreadLevel: '—',  // ak_users 无分销等级字段
    phone: phone,
    userType: formatUserType(regSource, role),
    balance: '—',      // ak_users 无余额字段（total_spent 为消费额，语义不同）
    checked: false
  } as UserRow
}

// ========== 数据请求 ==========
// ⚠️ 前置条件：需在 Supabase 添加 admin 读取全部用户的 RLS 策略：
// CREATE POLICY "ak_users_admin_read_all" ON public.ak_users
// FOR SELECT TO authenticated
// USING ((auth.jwt() -> 'app_metadata' ->> 'role') = 'admin' OR auth.uid() = id);
//
// ✅ 使用 limit+offset URL 参数代替 Range 头，彻底避免 PostgREST 416 问题
const fetchUsers = async (page: number = 1, ps: number = pageSize.value) => {
  if (loading.value) return  // 防止并发重复请求
  loading.value = true
  fetchError.value = ''
  try {
    // offset 注入到 filter 字符串，PostgREST 将其识别为 SQL OFFSET，不发 Range 头
    const offset = (page - 1) * ps
    const offsetFilter = offset > 0 ? `offset=${offset}` : null
    const res = await supabase.select(
      'ak_users',
      offsetFilter,
      {
        columns: 'id, username, email, phone, avatar_url, role, registration_source, user_level, created_at',
        limit: ps,
        order: 'created_at.desc',
        count: 'exact'   // 触发 Prefer: count=exact → 响应带 Content-Range 总行数
      }
    )
    if (res.status >= 200 && res.status < 300 && res.data != null) {
      userList.value = (res.data as UTSJSONObject[]).map((row: UTSJSONObject): UserRow => mapDbRow(row))
      // 从 Content-Range 响应头解析真实总行数（格式：0-14/total）
      let totalCount = 0
      const hdrs = res.headers
      if (hdrs != null) {
        let cr: string | null = null
        if (typeof (hdrs as any).get === 'function') {
          cr = (hdrs as any).get('content-range') as string | null
        }
        if (cr == null) {
          cr = (hdrs as UTSJSONObject)['content-range'] as string | null
        }
        if (cr != null) {
          const m = /\/(\d+)$/.exec(cr)
          if (m != null) totalCount = parseInt(m[1] ?? '0')
        }
      }
      // content-range 解析失败时：以 offset + 当前页条数 作保守兜底
      if (totalCount === 0) {
        totalCount = offset + (Array.isArray(res.data) ? (res.data as UTSJSONObject[]).length : 0)
      }
      total.value = totalCount
    } else {
      fetchError.value = '加载用户列表失败，请检查网络或 RLS 权限配置'
    }
  } catch (e) {
    fetchError.value = '请求异常，请稍后重试'
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  fetchUsers(1, pageSize.value)
})

// ========== PAGINATION STATE ==========
const currentPage = ref(1)
const pageSize = ref(15)
const jumpPageInput = ref('')
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 total = ref(0)  // 来自服务端 content-range 真实总行数
const totalPage = computed(() => Math.max(1, Math.ceil(total.value / pageSize.value)))
const pagedList = computed(() => userList.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
  currentPage.value = p
  fetchUsers(p, pageSize.value)
}
const handlePageSizeChange = (e: any) => {
  const idx = Number(e.detail.value)
  pageSize.value = pageSizeOptions[idx] ?? pageSizeOptions[0]
  currentPage.value = 1
  fetchUsers(1, pageSize.value)
}
const handleJumpPage = () => {
  const p = parseInt(jumpPageInput.value)
  if (!isNaN(p) && p >= 1 && p <= totalPage.value) {
    currentPage.value = p
    fetchUsers(p, pageSize.value)
  }
}
// ========== END PAGINATION STATE ==========

function onSearch() {
  uni.showToast({ title: '搜索中...', icon: 'none' })
}

function onReset() {
  uni.showToast({ title: '已重置', icon: 'none' })
}

function onAddUser() {
  uni.showToast({ title: '添加用户', icon: 'none' })
}

function onDetail(user: any) {
  uni.showToast({ title: '查看用户: ' + user.id, icon: 'none' })
}
</script>

<style scoped lang="scss">
.admin-page {
  /* 使用 Layout 的背景和内边距 */
  min-height: 100vh;
}

/* 筛选卡片 */
.filter-card {
  padding: var(--admin-card-padding);
}

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

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

.label {
  font-size: 14px;
  color: #333;
  width: 70px;
}

.input-group {
  display: flex;
  flex-direction: row;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  height: 32px;
  width: 260px;
}

.compact-select {
  display: flex;
  flex-direction: row;
  align-items: center;
  padding: 0 12px;
  border-right: 1px solid #d9d9d9;
  background: #fafafa;
  text { font-size: 14px; color: #666; }
  .arrow { font-size: 10px; margin-left: 4px; color: #bfbfbf; }
}

.filter-input {
  flex: 1;
  height: 30px;
  padding: 0 12px;
  font-size: 14px;
}

.filter-select {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
  height: 32px;
  width: 220px;
  padding: 0 12px;
  background: #fff;
}

.select-placeholder { font-size: 14px; color: #bfbfbf; }
.arrow { font-size: 10px; color: #bfbfbf; }

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

.btn {
  height: 32px;
  padding: 0 16px;
  font-size: 14px;
  border-radius: 2px;
  border: 1px solid #d9d9d9;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  margin: 0;
}

.btn.primary {
  background: #2f54eb;
  border-color: #2f54eb;
  color: #fff;
}

.btn.ghost {
  color: #2f54eb;
  border-color: #2f54eb;
  background: #fff;
}

.btn.small {
  height: 28px;
  padding: 0 12px;
  font-size: 13px;
}

.expand-btn {
  font-size: 14px;
  color: #2f54eb;
  cursor: pointer;
}

/* 内容卡片 */
.content-card {
  padding: 0;
  overflow: visible; /* 必须 visible 以显示下拉菜单 */
}

/* Tabs */
.tabs-row {
  display: flex;
  flex-direction: row;
  padding: 0 24px;
  border-bottom: 1px solid #f0f0f0;
}

.tab-item {
  padding: 16px 20px;
  cursor: pointer;
  position: relative;
  text { font-size: 15px; color: #666; }

  &.active {
    text { color: #2f54eb; font-weight: 500; }
    &::after {
      content: '';
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      height: 2px;
      background: #2f54eb;
    }
  }
}

/* 操作栏 */
.action-bar {
  padding: 16px 24px;
  display: flex;
  flex-direction: row;
  gap: 12px;
}

/* 表格 */
.table-container {
  padding: 0 24px 24px;
  overflow: visible;
}

.table-header {
  display: flex;
  flex-direction: row;
  background: #f8faff;
  border-bottom: 1px solid #f0f0f0;
  padding: 12px 0;
}

.table-row {
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #f0f0f0;
  padding: 16px 0;
  align-items: center;
  position: relative;
  overflow: visible;
  
  &:hover {
    background: #fafafa;
  }
}

.col {
  padding: 0 8px;
  display: flex;
  align-items: center;
  font-size: 14px;
  color: #333;
}

.col-check { width: 40px; justify-content: center; }
.col-expand { width: 30px; justify-content: center; }
.col-id { width: 80px; }
.col-avatar { width: 80px; justify-content: center; }
.col-name { width: 140px; }
.col-member { width: 90px; justify-content: center; }
.col-level { width: 90px; justify-content: center; }
.col-group { width: 110px; justify-content: center; }
.col-spread { width: 110px; justify-content: center; }
.col-phone { width: 130px; }
.col-type { width: 90px; }
.col-balance { width: 110px; }
.col-ops { 
  display: flex;
  flex-direction: row;
  width: 130px; 
  justify-content: flex-end; 
  padding-right: 16px; 
  align-items: center;
}

.more-hover-container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 32px;
  min-width: 46px; /* 增加点击和悬停范围 */
  padding: 0 4px;
  cursor: pointer;
}

.more-trigger {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 2px;
  pointer-events: none; /* 确保事件冒泡到 container */
  .arrow { font-size: 10px; color: #2f54eb; margin-left: 2px; }
}

.dropdown-list-box {
  position: absolute;
  top: 30px;
  right: -5px; /* 稍微向左移动一点 */
  width: 140px; /* 增加宽度以容纳长文字 */
  padding-top: 10px; /* 增加缓冲区防止鼠标移出 */
  z-index: 9999;
}

.dropdown-arrow-top {
  position: absolute;
  top: 2px;
  right: 25px;
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 6px solid #fff;
}

.dropdown-menu-list {
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  display: flex;
  flex-direction: column;
  padding: 6px 0;
}

.menu-item {
  padding: 10px 16px;
  font-size: 14px;
  color: #606266;
  text-align: center;
  line-height: 1.4;
  &:hover {
    background-color: #f5f7fa;
    color: #2f54eb;
  }
}

.danger-item {
  &:hover {
    color: #ff4d4f !important;
  }
}

.pointer { cursor: pointer; }

.table-header .col {
  color: #5c5c5c;
  font-weight: 500;
}

.sort-icon {
  font-size: 12px;
  margin-left: 4px;
  color: #bfbfbf;
}

.expand-arrow {
  color: #bfbfbf;
  font-size: 18px;
}

.avatar-img {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  background: #f5f5f5;
}

.name-text {
  font-weight: 400;
}

.status-yes { color: #52c41a; }
.status-no { color: #ff4d4f; }

.op-link {
  color: #2f54eb;
  cursor: pointer;
  font-size: 14px;
}

.op-divider {
  color: #e8e8e8;
  font-size: 12px;
  margin: 0 8px;
}

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

.empty-state-row {
  padding: 40px 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  width: 100%;
}

.empty-text {
  font-size: 14px;
  color: #999;
  text-align: center;
}
</style>
