<template>
  <div class="space-y-4">
    <a-page-header title="账号安全" sub-title="密码、登录设备与安全设置">
      <template #extra>
        <a-space>
          <a-button danger @click="logout">退出登录</a-button>
        </a-space>
      </template>
    </a-page-header>

    <!-- 安全概览 -->
    <a-row :gutter="[16, 16]">
      <a-col :xs="24" :sm="8" v-for="s in securityOverview" :key="s.label">
        <div class="security-overview-card" :class="s.colorClass">
          <div class="overview-icon">{{ s.icon }}</div>
          <div class="overview-info">
            <div class="overview-value">{{ s.value }}</div>
            <div class="overview-label">{{ s.label }}</div>
          </div>
        </div>
      </a-col>
    </a-row>

    <a-row :gutter="[16, 16]">
      <a-col :xs="24" :lg="12">
        <a-card :bordered="false" class="card" title="修改密码">
          <a-form ref="formRef" layout="vertical" :model="form" :rules="rules">
            <a-form-item label="原密码" name="oldPassword">
              <a-input-password v-model:value="form.oldPassword" placeholder="请输入原密码" />
            </a-form-item>
            <a-form-item label="新密码" name="password">
              <a-input-password v-model:value="form.password" placeholder="请输入新密码（至少 6 位）" />
            </a-form-item>
            <a-form-item label="确认新密码" name="password2">
              <a-input-password v-model:value="form.password2" placeholder="再次输入新密码" />
            </a-form-item>
          </a-form>

          <div class="mt-2 flex justify-end gap-2">
            <a-button @click="resetForm" :disabled="pending">重置</a-button>
            <a-button type="primary" :loading="pending" @click="submit">保存</a-button>
          </div>

          <a-alert
            class="mt-4"
            show-icon
            type="info"
            message="修改密码后建议重新登录，以确保所有会话状态一致。"
          />
        </a-card>
      </a-col>

      <a-col :xs="24" :lg="12">
        <a-card :bordered="false" class="card" title="安全建议">
          <div class="security-tips">
            <div v-for="(tip, index) in securityTips" :key="index" class="tip-item">
              <div class="tip-icon" :class="tip.level">{{ tip.icon }}</div>
              <div class="tip-content">
                <div class="tip-title">{{ tip.title }}</div>
                <div class="tip-desc">{{ tip.desc }}</div>
              </div>
            </div>
          </div>
        </a-card>
      </a-col>
    </a-row>

    <!-- 登录日志 -->
    <a-card :bordered="false" class="card" title="最近登录记录">
      <template #extra>
        <a-button size="small" @click="loadLoginRecords">刷新</a-button>
      </template>
      <a-table
        :data-source="loginRecords"
        :loading="loginLoading"
        :pagination="{ pageSize: 5, showTotal: (t: number) => `共 ${t} 条` }"
        size="small"
        :row-key="(r: any) => r.id"
      >
        <a-table-column title="时间" data-index="createTime" width="180">
          <template #default="{ record }">
            {{ formatTime(record.createTime) }}
          </template>
        </a-table-column>
        <a-table-column title="类型" key="loginType" width="120">
          <template #default="{ record }">
            <a-tag :color="loginTypeColor(record.loginType)" size="small">
              {{ loginTypeText(record.loginType) }}
            </a-tag>
          </template>
        </a-table-column>
        <a-table-column title="设备" key="device" width="160">
          <template #default="{ record }">
            <span class="text-sm">{{ record.device || record.os || '-' }}</span>
          </template>
        </a-table-column>
        <a-table-column title="浏览器" data-index="browser" width="120" />
        <a-table-column title="IP 地址" data-index="ip" width="140">
          <template #default="{ record }">
            <a-typography-text :copyable="{ text: record.ip || '', tooltips: ['复制', '已复制'] }">
              {{ record.ip || '-' }}
            </a-typography-text>
          </template>
        </a-table-column>
        <a-table-column title="备注" data-index="description" ellipsis />
      </a-table>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { message, type FormInstance } from 'ant-design-vue'
import { updatePassword, getUserInfo } from '@/api/layout'
import { removeToken } from '@/utils/token-util'
import { clearAuthz } from '@/utils/permission'
import { pageLoginRecords } from '@/api/system/login-record'
import type { LoginRecord } from '@/api/system/login-record/model'

definePageMeta({ layout: 'console' })

// ─── 修改密码 ─────────────────────────────────────────────────
const pending = ref(false)

const formRef = ref<FormInstance>()
const form = reactive<{ oldPassword: string; password: string; password2: string }>({
  oldPassword: '',
  password: '',
  password2: ''
})

const rules = reactive({
  oldPassword: [{ required: true, type: 'string', message: '请输入原密码' }],
  password: [
    { required: true, type: 'string', message: '请输入新密码' },
    { min: 6, type: 'string', message: '新密码至少 6 位', trigger: 'blur' }
  ],
  password2: [{ required: true, type: 'string', message: '请再次输入新密码' }]
})

function resetForm() {
  form.oldPassword = ''
  form.password = ''
  form.password2 = ''
  formRef.value?.clearValidate()
}

async function submit() {
  try {
    await formRef.value?.validate()
  } catch {
    return
  }
  if (form.password !== form.password2) {
    message.error('两次输入的新密码不一致')
    return
  }

  pending.value = true
  try {
    await updatePassword({ oldPassword: form.oldPassword, password: form.password })
    message.success('密码修改成功')
    resetForm()
  } catch (e) {
    message.error(e instanceof Error ? e.message : '密码修改失败')
  } finally {
    pending.value = false
  }
}

function logout() {
  removeToken()
  try {
    localStorage.removeItem('TenantId')
    localStorage.removeItem('UserId')
  } catch {
    // ignore
  }
  clearAuthz()
  navigateTo('/login')
}

// ─── 安全概览 ─────────────────────────────────────────────────
const securityOverview = computed(() => [
  {
    icon: '🔐',
    label: '密码强度',
    value: '基础',
    colorClass: 'overview-warn',
  },
  {
    icon: '📱',
    label: '登录设备',
    value: `${loginRecords.value.length} 次登录`,
    colorClass: 'overview-info',
  },
  {
    icon: '⚠️',
    label: '异常登录',
    value: failedLogins.value > 0 ? `${failedLogins.value} 次` : '无',
    colorClass: failedLogins.value > 0 ? 'overview-danger' : 'overview-success',
  },
])

// ─── 安全建议 ─────────────────────────────────────────────────
const securityTips = [
  {
    icon: '🔑',
    level: 'level-info',
    title: '定期修改密码',
    desc: '建议每 3 个月更换一次密码，避免与其他平台重复使用。',
  },
  {
    icon: '🛡️',
    level: 'level-info',
    title: '使用强密码',
    desc: '密码至少 6 位，建议混合使用大小写字母、数字和特殊字符。',
  },
  {
    icon: '📱',
    level: 'level-warn',
    title: '关注登录记录',
    desc: '定期检查登录日志，如发现异常设备登录请立即修改密码。',
  },
  {
    icon: '🔐',
    level: 'level-info',
    title: '保护账号安全',
    desc: '不要将账号/密码分享给他人，如怀疑账号被盗用请立即修改密码并退出登录。',
  },
]

// ─── 登录日志 ─────────────────────────────────────────────────
const loginLoading = ref(false)
const loginRecords = ref<LoginRecord[]>([])
const failedLogins = computed(() => loginRecords.value.filter(r => r.loginType === 1).length)

async function loadLoginRecords() {
  loginLoading.value = true
  try {
    const data = await pageLoginRecords({
      page: 1,
      limit: 20,
    })
    loginRecords.value = data?.list || []
  } catch (e) {
    console.error('加载登录日志失败', e)
    loginRecords.value = []
  } finally {
    loginLoading.value = false
  }
}

function loginTypeText(type?: number) {
  const map: Record<number, string> = {
    0: '登录成功',
    1: '登录失败',
    2: '退出登录',
    3: 'Token 续签',
  }
  return type !== undefined ? (map[type] || `类型${type}`) : '-'
}

function loginTypeColor(type?: number) {
  const map: Record<number, string> = {
    0: 'green',
    1: 'red',
    2: 'default',
    3: 'blue',
  }
  return type !== undefined ? (map[type] || 'default') : 'default'
}

function formatTime(value?: string) {
  if (!value) return '-'
  try {
    const d = new Date(value)
    if (Number.isNaN(d.getTime())) return value
    const pad = (n: number) => String(n).padStart(2, '0')
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
  } catch {
    return value
  }
}

// ─── 初始化 ──────────────────────────────────────────────────
onMounted(() => {
  loadLoginRecords()
})
</script>

<style scoped>
.card {
  border-radius: 12px;
}

/* 安全概览 */
.security-overview-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 20px;
  border-radius: 12px;
  border: 1px solid #f0f0f0;
  background: #fff;
}

.overview-icon {
  font-size: 32px;
  flex-shrink: 0;
}

.overview-info { flex: 1; }

.overview-value {
  font-size: 18px;
  font-weight: 700;
  color: rgba(0, 0, 0, 0.85);
}

.overview-label {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  margin-top: 2px;
}

.overview-info { background: #f9fafb; border-color: #e5e7eb; }
.overview-warn { background: #fffbeb; border-color: #fde68a; }
.overview-info { background: #eff6ff; border-color: #bfdbfe; }
.overview-success { background: #f0fdf4; border-color: #bbf7d0; }
.overview-danger { background: #fef2f2; border-color: #fecaca; }

/* 安全建议 */
.security-tips {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.tip-item {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: #fafafa;
  border: 1px solid #f0f0f0;
}

.tip-icon {
  font-size: 22px;
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
}

.tip-icon.level-info { background: #eff6ff; }
.tip-icon.level-warn { background: #fff7ed; }

.tip-content { flex: 1; }

.tip-title {
  font-size: 14px;
  font-weight: 600;
  color: rgba(0, 0, 0, 0.85);
  margin-bottom: 2px;
}

.tip-desc {
  font-size: 12px;
  color: rgba(0, 0, 0, 0.45);
  line-height: 1.5;
}
</style>
