<template>
  <div class="personal-page">
    <div class="profile-grid">
      <!-- 左：头像 + 基本信息 -->
      <div class="profile-card">
        <div class="card-header">
          <el-icon :size="16"><User /></el-icon>
          <span>基本信息</span>
        </div>
        <div class="card-body">
          <!-- 头像上传 -->
          <div class="avatar-section">
            <div class="avatar-wrapper" @click="triggerUpload">
              <el-avatar :size="80" :src="form.avatar" class="profile-avatar">
                {{ (form.realName || form.username || 'U').charAt(0) }}
              </el-avatar>
              <div class="avatar-overlay">
                <el-icon :size="20"><Camera /></el-icon>
              </div>
            </div>
            <input ref="fileInputRef" type="file" accept="image/*" style="display:none" @change="handleAvatarUpload" />
            <div class="avatar-info">
              <div class="avatar-name">{{ form.realName || form.username }}</div>
              <div class="avatar-role">{{ form.post || '普通用户' }}</div>
              <el-button size="small" text type="primary" @click="triggerUpload">
                <el-icon><Upload /></el-icon>更换头像
              </el-button>
            </div>
          </div>

          <el-form :model="form" label-width="80px" label-position="left" class="info-form">
            <el-form-item label="用户名">
              <el-input :model-value="form.username" disabled />
            </el-form-item>
            <el-form-item label="姓名">
              <el-input v-model="form.realName" placeholder="请输入真实姓名" />
            </el-form-item>
            <el-form-item label="邮箱">
              <el-input v-model="form.email" placeholder="请输入邮箱" />
            </el-form-item>
            <el-form-item label="手机号">
              <el-input v-model="form.phone" placeholder="请输入手机号" />
            </el-form-item>
            <el-form-item label="岗位">
              <el-input v-model="form.post" placeholder="请输入岗位" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" :loading="saving" @click="saveProfile">
                <el-icon><Check /></el-icon>保存信息
              </el-button>
            </el-form-item>
          </el-form>
        </div>
      </div>

      <!-- 右：修改密码 + 账户信息 -->
      <div class="right-cards">
        <!-- 修改密码 -->
        <div class="profile-card">
          <div class="card-header">
            <el-icon :size="16"><Lock /></el-icon>
            <span>修改密码</span>
          </div>
          <div class="card-body">
            <el-form ref="pwdFormRef" :model="pwdForm" :rules="pwdRules" label-width="80px" label-position="left">
              <el-form-item label="原密码" prop="oldPwd">
                <el-input v-model="pwdForm.oldPwd" type="password" placeholder="请输入原密码" show-password />
              </el-form-item>
              <el-form-item label="新密码" prop="newPwd">
                <el-input v-model="pwdForm.newPwd" type="password" placeholder="至少6位" show-password />
              </el-form-item>
              <el-form-item label="确认密码" prop="confirmPwd">
                <el-input v-model="pwdForm.confirmPwd" type="password" placeholder="再次输入" show-password />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" :loading="changingPwd" @click="changePassword">
                  <el-icon><Key /></el-icon>修改密码
                </el-button>
              </el-form-item>
            </el-form>
          </div>
        </div>

        <!-- 账户信息 -->
        <div class="profile-card">
          <div class="card-header">
            <el-icon :size="16"><InfoFilled /></el-icon>
            <span>账户信息</span>
          </div>
          <div class="card-body">
            <div class="meta-list">
              <div class="meta-row">
                <span class="meta-label">用户ID</span>
                <code class="meta-value mono">{{ form.userId?.substring(0, 12) || '-' }}...</code>
              </div>
              <div class="meta-row">
                <span class="meta-label">用户名</span>
                <span class="meta-value">{{ form.username || '-' }}</span>
              </div>
              <div class="meta-row">
                <span class="meta-label">注册时间</span>
                <span class="meta-value">{{ fmtDate(form.createdAt) }}</span>
              </div>
              <div class="meta-row">
                <span class="meta-label">最后登录</span>
                <span class="meta-value">{{ fmtDate(form.lastLoginTime) }}</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { User, Lock, Key, Check, InfoFilled, Camera, Upload } from '@element-plus/icons-vue'
import type { FormInstance, FormRules } from 'element-plus'
import request from '@/utils/request'
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()
const fileInputRef = ref<HTMLInputElement>()

const form = reactive({
  userId: '' as string | null,
  username: '',
  realName: '',
  email: '',
  phone: '',
  avatar: '',
  post: '',
  createdAt: '',
  lastLoginTime: '',
})

const saving = ref(false)

function fmtDate(s: string | null | undefined): string {
  if (!s) return '-'
  try {
    const d = new Date(s)
    if (isNaN(d.getTime())) return s
    return d.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })
  } catch { return s }
}

onMounted(async () => {
  try {
    const res = await request.get('/zgapi/v1/auth/user/info')
    const d = res.data
    Object.assign(form, {
      userId: d.userId ?? '',
      username: d.username ?? '',
      realName: d.realName ?? '',
      email: d.email ?? '',
      phone: d.phone ?? '',
      avatar: d.avatar ?? '',
      post: d.post ?? '',
      createdAt: d.createdAt ?? '',
      lastLoginTime: d.lastLoginTime ?? '',
    })
    setTimeout(() => pwdFormRef.value?.clearValidate(), 0)
  } catch { /* ignore */ }
})

function triggerUpload() {
  fileInputRef.value?.click()
}

async function handleAvatarUpload(e: Event) {
  const file = (e.target as HTMLInputElement).files?.[0]
  if (!file) return
  const fd = new FormData()
  fd.append('file', file)
  fd.append('fileType', 'avatar')
  fd.append('userId', form.userId || '')
  try {
    const res = await request.post('/zgapi/v1/admin/file/upload', fd)
    // 文件存入数据库后，用文件ID构建访问路径
    const fileId = res.data?.id
    if (!fileId) { ElMessage.error('上传返回异常'); return }
    const gatewayUrl = import.meta.env.VITE_GATEWAY_URL || ''
    const avatarUrl = `${gatewayUrl}/zgapi/v1/admin/file/${fileId}/view`
    form.avatar = avatarUrl
    // 更新用户头像字段
    await request.put('/zgapi/v1/admin/user', {
      id: form.userId,
      avatar: avatarUrl,
    })
    // 同步刷新 store 中的用户信息（也会更新 Redis TokenInfo）
    await authStore.fetchUserInfo()
    ElMessage.success('头像已更新')
  } catch { ElMessage.error('上传失败') }
}

async function saveProfile() {
  saving.value = true
  try {
    await request.put('/zgapi/v1/admin/user', {
      id: form.userId,
      username: form.username,
      realName: form.realName,
      email: form.email,
      phone: form.phone,
      post: form.post,
    })
    await authStore.fetchUserInfo()
    ElMessage.success('个人信息已更新')
  } catch { /* ignore */ } finally {
    saving.value = false
  }
}

// 密码
const pwdFormRef = ref<FormInstance>()
const changingPwd = ref(false)
const pwdForm = reactive({ oldPwd: '', newPwd: '', confirmPwd: '' })

const pwdRules: FormRules = {
  oldPwd: [{ required: true, message: '请输入原密码', trigger: 'blur' }],
  newPwd: [
    { required: true, message: '请输入新密码', trigger: 'blur' },
    { min: 6, message: '密码至少6位', trigger: 'blur' },
  ],
  confirmPwd: [
    { required: true, message: '请再次输入', trigger: 'blur' },
    { validator: (_r: any, v: string, cb: any) => v !== pwdForm.newPwd ? cb(new Error('两次密码不一致')) : cb(), trigger: 'blur' },
  ],
}

async function changePassword() {
  const valid = await pwdFormRef.value?.validate().catch(() => false)
  if (!valid) return
  changingPwd.value = true
  try {
    await request.put('/zgapi/v1/auth/password/update', null, {
      params: { oldPwd: pwdForm.oldPwd, newPwd: pwdForm.newPwd },
    })
    ElMessage.success('密码修改成功，即将重新登录')
    pwdForm.oldPwd = ''; pwdForm.newPwd = ''; pwdForm.confirmPwd = ''
    setTimeout(() => {
      authStore.logout()
      window.location.href = '/login'
    }, 1500)
  } catch { /* ignore */ } finally {
    changingPwd.value = false
  }
}
</script>

<style scoped>
.personal-page { max-width: 960px; }
.profile-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.right-cards { display: flex; flex-direction: column; gap: 20px; }

.profile-card {
  background: var(--bg-surface); border-radius: var(--radius-lg);
  border: 1px solid var(--border-color); box-shadow: var(--shadow-xs); overflow: hidden;
}
.card-header {
  display: flex; align-items: center; gap: 8px;
  padding: 16px 20px; border-bottom: 1px solid var(--border-light);
  font-weight: 600; font-size: 14px; color: var(--text-primary);
}
.card-body { padding: 24px 20px; }

/* 头像 */
.avatar-section { display: flex; align-items: center; gap: 16px; margin-bottom: 24px; padding-bottom: 20px; border-bottom: 1px solid var(--border-light); }
.avatar-wrapper { position: relative; cursor: pointer; flex-shrink: 0; }
.profile-avatar { box-shadow: 0 4px 12px rgba(99,102,241,0.2); }
.avatar-overlay {
  position: absolute; inset: 0; border-radius: 50%;
  background: rgba(0,0,0,0.35); display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--transition-fast); color: #fff;
}
.avatar-wrapper:hover .avatar-overlay { opacity: 1; }
.avatar-name { font-size: 18px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; }
.avatar-role { font-size: 13px; color: var(--text-muted); margin-bottom: 8px; }

/* 表单 */
.info-form :deep(.el-form-item) { margin-bottom: 18px; }
.info-form :deep(.el-form-item:last-child) { margin-bottom: 0; padding-top: 4px; }

/* 元信息 */
.meta-list { display: flex; flex-direction: column; }
.meta-row { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid var(--border-light); }
.meta-row:last-child { border-bottom: none; }
.meta-label { font-size: 13px; color: var(--text-muted); font-weight: 500; }
.meta-value { font-size: 13px; color: var(--text-secondary); font-weight: 600; }
.meta-value.mono { font-family: 'SF Mono', 'Consolas', monospace; font-size: 12px; }

@media (max-width: 768px) {
  .profile-grid { grid-template-columns: 1fr; gap: 12px; }
  .personal-page { padding: 0; }
  .avatar-section { flex-direction: column; text-align: center; }
  .avatar-info { align-items: center; }
  .card-body { padding: 16px; }
}
</style>
