<template>
  <div class="member-management">
    <el-card>
      <template #header>
        <div class="card-header">
          <div class="search-section">
            <el-input
              v-model="searchKeyword"
              placeholder="搜索会员编号/昵称/手机号"
              clearable
              style="width: 280px"
              @clear="handleSearch"
              @keyup.enter="handleSearch"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
            <el-button type="primary" @click="handleSearch">
              搜索
            </el-button>
          </div>
          <div class="sort-section">
            <el-button @click="handleResetSort" :type="sortField === 'createdAt' && sortOrder === 'desc' ? 'primary' : 'default'">
              <el-icon><Clock /></el-icon>
              最近注册
            </el-button>
          </div>
        </div>
      </template>
      <el-table
        v-loading="loading"
        :data="dataSource"
        style="width: 100%"
        @sort-change="handleSortChange"
      >
        <el-table-column prop="id" label="ID" width="80" sortable="custom" />
        <el-table-column label="头像" width="80">
          <template #default="{ row }">
            <el-avatar v-if="row.avatar" :src="row.avatar" :size="40" />
            <el-avatar v-else :size="40">
              <el-icon><UserFilled /></el-icon>
            </el-avatar>
          </template>
        </el-table-column>
        <el-table-column prop="memberNo" label="会员编号" width="140" sortable="custom">
          <template #default="{ row }">
            {{ row.memberNo || '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="nickname" label="昵称" min-width="120">
          <template #default="{ row }">
            {{ row.nickname || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="手机号" width="140">
          <template #default="{ row }">
            {{ formatPhone(row.phone) }}
          </template>
        </el-table-column>
        <el-table-column label="性别" width="70">
          <template #default="{ row }">
            {{ row.genderDesc || genderMap[row.gender as number] || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="注册时间" width="170" prop="createdAt" sortable="custom">
          <template #default="{ row }">
            {{ row.createdAt ? formatDateTime(row.createdAt) : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="240" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleDetail(row)">
              详情
            </el-button>
            <el-button type="primary" link size="small" @click="handleEdit(row)">
              编辑
            </el-button>
            <el-button type="warning" link size="small" @click="handleEditPhone(row)">
              修改手机号
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        v-model:current-page="pagination.current"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[10, 20, 50, 100]"
        :total="pagination.total"
        layout="total, sizes, prev, pager, next, jumper"
        style="margin-top: 16px; justify-content: flex-end"
        @current-change="handleTableChange"
        @size-change="handleSizeChange"
      />
    </el-card>

    <!-- 详情弹窗 -->
    <el-dialog
      v-model="detailVisible"
      title="会员详情"
      width="650px"
    >
      <div v-loading="detailLoading" style="min-height: 200px">
        <el-descriptions v-if="currentDetail" :column="2" border>
          <el-descriptions-item label="ID">{{ currentDetail.id }}</el-descriptions-item>
          <el-descriptions-item label="会员编号">{{ currentDetail.memberNo || '-' }}</el-descriptions-item>
          <el-descriptions-item label="昵称">{{ currentDetail.nickname || '-' }}</el-descriptions-item>
          <el-descriptions-item label="手机号">{{ formatPhone(currentDetail.phone) }}</el-descriptions-item>
          <el-descriptions-item label="性别">{{ currentDetail.genderDesc || '-' }}</el-descriptions-item>
          <el-descriptions-item label="生日">{{ currentDetail.birthday || '-' }}</el-descriptions-item>
          <el-descriptions-item label="地址" :span="2">{{ currentDetail.address || '-' }}</el-descriptions-item>
          <el-descriptions-item label="关注状态">
            <el-tag :type="currentDetail.subscribed ? 'success' : 'info'" size="small">
              {{ currentDetail.subscribed ? '已关注' : '未关注' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="最后登录">{{ formatDateTime(currentDetail.lastLoginAt) }}</el-descriptions-item>
          <el-descriptions-item label="注册时间">{{ formatDateTime(currentDetail.createdAt) }}</el-descriptions-item>
          <el-descriptions-item label="有效会员卡">{{ currentDetail.activeCardCount ?? 0 }}</el-descriptions-item>
          <el-descriptions-item label="头像" :span="2">
            <el-avatar v-if="currentDetail.avatar" :src="currentDetail.avatar" :size="60" />
            <span v-else>未设置</span>
          </el-descriptions-item>
        </el-descriptions>

        <!-- 绑定的会员卡记录 -->
        <div style="margin-top: 20px">
          <h4 style="margin-bottom: 10px">
            绑定的会员卡
            <span v-if="currentDetail?.activeCardCount !== undefined" style="font-weight: normal; font-size: 13px; color: #909399; margin-left: 8px">
              (有效 {{ currentDetail.activeCardCount }} 张 / 共 {{ (currentDetail.activeCardCount ?? 0) + (currentDetail.inactiveCardCount ?? 0) }} 张)
            </span>
          </h4>
          <el-table v-if="memberCardRecords.length > 0" :data="memberCardRecords" size="small" border>
            <el-table-column prop="memberCardName" label="卡名称" min-width="120" />
            <el-table-column label="卡类型" width="90">
              <template #default="{ row: rec }">
                {{ cardTypeMap[rec.memberCardType as string] || rec.memberCardType || '-' }}
              </template>
            </el-table-column>
            <el-table-column label="剩余" width="120">
              <template #default="{ row: rec }">
                <template v-if="rec.memberCardType === 'TIME_CARD'">
                  {{ formatDateTime(rec.expireTime) }}
                </template>
                <template v-else-if="rec.memberCardType === 'COUNT_CARD'">
                  {{ rec.remainingTimes ?? 0 }} 次
                </template>
                <template v-else-if="rec.memberCardType === 'STORED_VALUE_CARD'">
                  ¥{{ rec.remainingAmount ?? 0 }}
                </template>
                <template v-else>-</template>
              </template>
            </el-table-column>
            <el-table-column label="购买时间" width="170">
              <template #default="{ row: rec }">
                {{ formatDateTime(rec.purchaseTime) }}
              </template>
            </el-table-column>
            <el-table-column prop="status" label="状态" width="80">
              <template #default="{ row: rec }">
                <el-tag :type="rec.status === 'ACTIVE' ? 'success' : 'info'" size="small">
                  {{ rec.status || '-' }}
                </el-tag>
              </template>
            </el-table-column>
          </el-table>
          <el-empty v-else description="暂无绑定的会员卡" :image-size="60" />
        </div>
      </div>
    </el-dialog>

    <!-- 编辑弹窗 -->
    <el-dialog
      v-model="editVisible"
      title="编辑会员信息"
      width="500px"
    >
      <div v-loading="editLoading" style="min-height: 200px">
        <el-form
          v-if="!editLoading"
          ref="editFormRef"
          :model="editForm"
          label-width="100px"
        >
          <el-form-item label="昵称">
            <el-input v-model="editForm.nickname" placeholder="请输入昵称" />
          </el-form-item>
          <el-form-item label="性别">
            <el-select v-model="editForm.gender" placeholder="请选择性别" style="width: 100%">
              <el-option value="MALE" label="男" />
              <el-option value="FEMALE" label="女" />
              <el-option value="UNKNOWN" label="未知" />
            </el-select>
          </el-form-item>
          <el-form-item label="生日">
            <el-date-picker
              v-model="editForm.birthday"
              type="date"
              placeholder="选择生日"
              value-format="YYYY-MM-DD"
              style="width: 100%"
            />
          </el-form-item>
          <el-form-item label="地址">
            <el-input v-model="editForm.address" placeholder="请输入地址" />
          </el-form-item>
          <el-form-item label="头像">
            <div class="avatar-edit-row">
              <div class="avatar-upload">
                <el-upload
                  class="avatar-uploader"
                  :http-request="uploadAvatar"
                  :before-upload="beforeAvatarUpload"
                  :show-file-list="false"
                  accept="image/*"
                >
                  <el-avatar v-if="editForm.avatar" :src="editForm.avatar" :size="80" />
                  <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
                </el-upload>
                <span class="avatar-hint">点击上传</span>
              </div>
              <el-button
                v-if="editForm.avatar"
                type="danger"
                plain
                size="small"
                @click="handleClearAvatar"
              >
                删除头像
              </el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button @click="editVisible = false">取消</el-button>
        <el-button type="primary" @click="handleEditSubmit" :loading="editSubmitting" :disabled="editLoading">确定</el-button>
      </template>
    </el-dialog>

    <!-- 修改手机号弹窗 -->
    <el-dialog
      v-model="phoneVisible"
      title="修改手机号"
      width="400px"
    >
      <el-form
        ref="phoneFormRef"
        :model="phoneForm"
        :rules="phoneRules"
        label-width="100px"
      >
        <el-form-item label="会员ID">
          <span>{{ currentMemberId }}</span>
        </el-form-item>
        <el-form-item label="新手机号" prop="phone">
          <el-input v-model="phoneForm.phone" placeholder="请输入新手机号" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="phoneVisible = false">取消</el-button>
        <el-button type="primary" @click="handlePhoneSubmit">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Search, UserFilled, Plus, Clock } from '@element-plus/icons-vue'
import { memberApi, type Member, type MemberDetail, type MemberCardRecord, type UpdateMemberDto } from '@/api/member.api'
import request from '@/utils/request'
import { formatDateTime } from '@/utils/dateFormat'

const loading = ref(false)
const dataSource = ref<Member[]>([])
const searchKeyword = ref('')
const sortField = ref<string>('')
const sortOrder = ref<string>('')

const genderMap: Record<number, string> = {
  0: '未知',
  1: '男',
  2: '女',
}

const cardTypeMap: Record<string, string> = {
  TIME_CARD: '时长卡',
  COUNT_CARD: '次卡',
  STORED_VALUE_CARD: '储值卡',
}

/** 格式化手机号显示，null/空时显示"未绑定" */
const formatPhone = (phone: string | undefined | null): string => {
  if (!phone) return '未绑定'
  return phone
}

const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
})

// 详情相关
const detailVisible = ref(false)
const detailLoading = ref(false)
const currentDetail = ref<MemberDetail | null>(null)
const memberCardRecords = ref<MemberCardRecord[]>([])

// 编辑相关
const editVisible = ref(false)
const editLoading = ref(false)
const editSubmitting = ref(false)
const editFormRef = ref()
const editingMemberId = ref<number>()
const editForm = reactive<UpdateMemberDto>({
  nickname: '',
  gender: undefined,
  birthday: '',
  address: '',
  avatar: '',
})

// 修改手机号相关
const phoneVisible = ref(false)
const phoneFormRef = ref()
const currentMemberId = ref<number>()
const phoneForm = reactive({
  phone: '',
})
const phoneRules = {
  phone: [
    { required: true, message: '请输入手机号', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' },
  ],
}

const fetchData = async () => {
  loading.value = true
  try {
    const params: any = {
      pageNum: pagination.current,
      pageSize: pagination.pageSize,
      sortField: sortField.value || 'createdAt',
      sortOrder: sortOrder.value || 'desc',
    }
    if (searchKeyword.value) {
      params.searchValue = searchKeyword.value
    }
    let res: any
    if (searchKeyword.value) {
      res = await memberApi.search(params)
    } else {
      res = await memberApi.getAll(params)
    }
    console.log('会员列表API返回:', res)

    // 兼容多种返回格式：数组、{content/records/list/data: [...]}
    let list: any[] = []
    if (Array.isArray(res)) {
      list = res
    } else if (res?.content) {
      list = res.content
    } else if (res?.records) {
      list = res.records
    } else if (res?.list) {
      list = res.list
    } else if (res?.data && Array.isArray(res.data)) {
      list = res.data
    }
    dataSource.value = list

    // 分页总数
    if (res?.totalElements !== undefined) {
      pagination.total = Number(res.totalElements)
    } else if (res?.total !== undefined) {
      pagination.total = Number(res.total)
    } else if (Array.isArray(res)) {
      pagination.total = res.length
    } else {
      pagination.total = list.length
    }
  } catch (e: any) {
    const msg = e?.response?.data?.message || e?.message || '加载数据失败'
    ElMessage.error(msg)
    console.error('加载会员列表失败:', e)
  } finally {
    loading.value = false
  }
}

const handleTableChange = () => fetchData()
const handleSizeChange = () => {
  pagination.current = 1
  fetchData()
}
const handleSearch = () => {
  pagination.current = 1
  fetchData()
}

const handleSortChange = ({ prop, order }: { prop: string; order: string | null }) => {
  sortField.value = prop || ''
  sortOrder.value = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : ''
  pagination.current = 1
  fetchData()
}

const handleResetSort = () => {
  sortField.value = 'createdAt'
  sortOrder.value = 'desc'
  pagination.current = 1
  fetchData()
}

const handleDetail = async (row: Member) => {
  console.log('点击详情, row:', row, 'row.id:', row.id, 'type:', typeof row.id)
  if (!row.id) return
  detailVisible.value = true
  detailLoading.value = true
  currentDetail.value = null
  memberCardRecords.value = []
  try {
    const detail = await memberApi.getDetail(Number(row.id))
    console.log('会员详情API返回:', detail)
    currentDetail.value = detail
    // 获取绑定的会员卡记录
    try {
      const records: any = await memberApi.getMemberCardRecords(Number(row.id))
      memberCardRecords.value = Array.isArray(records) ? records : (records?.content || records?.data || [])
    } catch {
      memberCardRecords.value = []
    }
  } catch (e: any) {
    const msg = e?.response?.data?.message || e?.message || '获取会员详情失败'
    ElMessage.error(msg)
    console.error('获取会员详情失败:', e)
    detailVisible.value = false
  } finally {
    detailLoading.value = false
  }
}

const handleEdit = async (row: Member) => {
  console.log('点击编辑, row:', row)
  if (!row.id) return
  editingMemberId.value = Number(row.id)
  editVisible.value = true
  editLoading.value = true
  // 先重置表单
  editForm.nickname = ''
  editForm.gender = undefined
  editForm.birthday = ''
  editForm.address = ''
  editForm.avatar = ''
  try {
    const detail = await memberApi.getDetail(Number(row.id))
    console.log('编辑-会员详情API返回:', detail)
    editForm.nickname = detail.nickname || ''
    // genderDesc 为中文"男"/"女"，需转为后端枚举值
    if (detail.genderDesc === '男') {
      editForm.gender = 'MALE'
    } else if (detail.genderDesc === '女') {
      editForm.gender = 'FEMALE'
    } else {
      editForm.gender = 'UNKNOWN'
    }
    // birthday 可能是 ISO 格式（"2026-01-01T00:00:00.000+00:00"），取前10位
    if (detail.birthday) {
      const bd = String(detail.birthday)
      editForm.birthday = bd.length >= 10 ? bd.substring(0, 10) : bd
    } else {
      editForm.birthday = ''
    }
    editForm.address = detail.address || ''
    editForm.avatar = detail.avatar || ''
    console.log('编辑表单数据:', JSON.parse(JSON.stringify(editForm)))
  } catch (e: any) {
    const msg = e?.response?.data?.message || e?.message || '获取会员信息失败'
    ElMessage.error(msg)
    console.error('获取会员信息失败:', e)
    editVisible.value = false
  } finally {
    editLoading.value = false
  }
}

const handleEditSubmit = async () => {
  if (!editingMemberId.value) return
  editSubmitting.value = true
  try {
    const body: UpdateMemberDto = {
      nickname: editForm.nickname || undefined,
      gender: editForm.gender || undefined,
      birthday: editForm.birthday || undefined,
      address: editForm.address || undefined,
      avatar: editForm.avatar || undefined,
    }
    await memberApi.update(editingMemberId.value, body)
    ElMessage.success('更新成功')
    editVisible.value = false
    fetchData()
  } catch (e: any) {
    const msg = e?.response?.data?.message || e?.message || '更新失败'
    ElMessage.error(msg)
  } finally {
    editSubmitting.value = false
  }
}

// ========== 头像上传 ==========

const beforeAvatarUpload = (file: File) => {
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('只能上传图片文件')
    return false
  }
  const isLt5M = file.size / 1024 / 1024 < 5
  if (!isLt5M) {
    ElMessage.error('图片大小不能超过 5MB')
    return false
  }
  return true
}

const uploadAvatar = async (options: any) => {
  const formData = new FormData()
  formData.append('file', options.file)
  try {
    const res: any = await request.post('/files/upload', formData, {
      headers: { 'Content-Type': 'multipart/form-data' },
    })
    if (res && res.id) {
      // 通过预览接口获取图片URL
      const blob: any = await request.get(`/files/${res.id}/preview`, { responseType: 'blob' })
      editForm.avatar = URL.createObjectURL(blob)
    }
    ElMessage.success('头像上传成功')
  } catch {
    ElMessage.error('头像上传失败')
  }
}

const handleClearAvatar = () => {
  editForm.avatar = ''
  ElMessage.success('头像已清除，保存后生效')
}

// ========== 修改手机号 ==========

const handleEditPhone = (row: Member) => {
  currentMemberId.value = Number(row.id)
  phoneForm.phone = ''
  phoneVisible.value = true
}

const handlePhoneSubmit = async () => {
  if (!phoneFormRef.value || !currentMemberId.value) return
  try {
    await phoneFormRef.value.validate()
    await memberApi.updatePhone(currentMemberId.value, { phone: phoneForm.phone })
    ElMessage.success('手机号更新成功')
    phoneVisible.value = false
    fetchData()
  } catch (error: any) {
    if (error !== 'cancel' && error?.message !== 'cancel') {
      const msg = error?.response?.data?.message || error?.message || '手机号更新失败'
      ElMessage.error(msg)
    }
  }
}

onMounted(() => {
  fetchData()
})
</script>

<style scoped lang="css">
.member-management {
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;

    .search-section {
      display: flex;
      gap: 8px;
      align-items: center;
    }

    .sort-section {
      display: flex;
      gap: 8px;
      align-items: center;
    }
  }
}

.avatar-edit-row {
  display: flex;
  align-items: flex-end;
  gap: 16px;
}

.avatar-upload {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}

.avatar-uploader :deep(.el-upload) {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  width: 80px;
  height: 80px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.3s;
}

.avatar-uploader :deep(.el-upload:hover) {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
}

.avatar-hint {
  font-size: 12px;
  color: #909399;
}
</style>
