<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import http, { apiErrorMessage } from '../api/http'
import { useAuthStore } from '../stores/auth'

const route = useRoute()
const router = useRouter()
const auth = useAuthStore()
const loading = ref(true)
const actionLoading = ref(false)
const sso = reactive({
  enabled: false,
  providerDisplayName: '学校统一身份认证',
  isBound: false,
  callbackUrl: '',
})

const ssoErrors: Record<string, string> = {
  binding_intent_expired: '绑定请求已失效，请重新发起绑定。',
  identity_already_bound: '该统一身份账号已经绑定其他教务系统账号。',
  account_already_bound: '当前教务系统账号已经绑定其他统一身份账号。',
  account_disabled: '当前教务系统账号已停用或锁定。',
  account_link_failed: '统一身份账户绑定失败，请重新尝试。',
  configuration_error: '统一身份认证回调地址配置不正确，请联系管理员。',
}

async function loadAccount() {
  loading.value = true
  try {
    const { data } = await http.get('/auth/sso/account')
    sso.enabled = Boolean(data.enabled)
    sso.providerDisplayName = String(data.providerDisplayName || sso.providerDisplayName)
    sso.isBound = Boolean(data.isBound)
    sso.callbackUrl = String(data.callbackUrl || '')
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
  } finally {
    loading.value = false
  }
}

async function startBinding() {
  actionLoading.value = true
  try {
    const { data } = await http.post('/auth/sso/prepare-binding')
    window.location.assign(String(data.loginUrl))
  } catch (error) {
    ElMessage.error(apiErrorMessage(error))
    actionLoading.value = false
  }
}

async function unbind() {
  try {
    const result = await ElMessageBox.prompt(
      '解绑后将不能再使用当前统一身份账号登录。请输入教务系统密码确认。',
      '解除统一身份绑定',
      {
        inputType: 'password',
        inputPlaceholder: '请输入教务系统密码',
        inputValidator: (value) => Boolean(value) || '密码不能为空',
        confirmButtonText: '确认解绑',
        cancelButtonText: '取消',
        type: 'warning',
      },
    )
    actionLoading.value = true
    await http.post('/auth/sso/unbind', { password: result.value })
    ElMessage.success('统一身份账户已解绑。')
    await loadAccount()
  } catch (error) {
    if (error === 'cancel' || error === 'close') return
    ElMessage.error(apiErrorMessage(error))
  } finally {
    actionLoading.value = false
  }
}

onMounted(async () => {
  const ssoError = String(route.query.ssoError ?? '')
  if (ssoError) {
    ElMessage.error(ssoErrors[ssoError] ?? '统一身份账户绑定失败，请重新尝试。')
    await router.replace('/account')
  }
  await loadAccount()
})
</script>

<template>
  <section class="account-page">
    <header class="account-heading">
      <div>
        <span class="eyebrow">ACCOUNT &amp; SECURITY</span>
        <h1>个人账户</h1>
        <p>管理您的登录身份与单点登录绑定。</p>
      </div>
      <div class="account-avatar">{{ auth.user?.displayName?.slice(0, 1) ?? '用' }}</div>
    </header>

    <div class="account-grid">
      <article class="account-card identity-card">
        <div class="card-title">
          <div>
            <span>基本信息</span>
            <h2>{{ auth.user?.displayName }}</h2>
          </div>
          <el-tag type="success" effect="light">账号已启用</el-tag>
        </div>
        <dl>
          <div>
            <dt>登录账号</dt>
            <dd>{{ auth.user?.userName }}</dd>
          </div>
          <div>
            <dt>系统角色</dt>
            <dd class="role-list">
              <el-tag v-for="role in auth.user?.roles" :key="role" effect="plain">{{ role }}</el-tag>
            </dd>
          </div>
          <div>
            <dt>数据范围</dt>
            <dd>{{ auth.user?.effectiveDataScope }}</dd>
          </div>
        </dl>
      </article>

      <article v-loading="loading" class="account-card sso-card">
        <div class="card-title">
          <div>
            <span>单点登录</span>
            <h2>{{ sso.providerDisplayName }}</h2>
          </div>
          <el-tag v-if="sso.isBound" type="success">已绑定</el-tag>
          <el-tag v-else-if="sso.enabled" type="info">未绑定</el-tag>
          <el-tag v-else type="warning">未启用</el-tag>
        </div>

        <p v-if="sso.isBound" class="sso-description">
          当前教务系统账号已经关联统一身份认证。您可以直接通过 Keycloak 登录。
        </p>
        <p v-else-if="sso.enabled" class="sso-description">
          绑定后，即使统一身份用户名与教务系统账号不同，也可以直接登录当前账号。
        </p>
        <p v-else class="sso-description">管理员尚未启用统一身份认证。</p>

        <el-button
          v-if="sso.enabled && !sso.isBound"
          type="primary"
          :loading="actionLoading"
          @click="startBinding"
        >
          绑定统一身份账户
        </el-button>
        <el-button
          v-else-if="sso.isBound"
          type="danger"
          plain
          :loading="actionLoading"
          @click="unbind"
        >
          解除绑定
        </el-button>

        <details v-if="sso.enabled && sso.callbackUrl" class="callback-details">
          <summary>管理员配置参考</summary>
          <p>Keycloak Valid redirect URI 必须与下列地址完全一致：</p>
          <code>{{ sso.callbackUrl }}</code>
        </details>
      </article>
    </div>
  </section>
</template>

<style scoped>
.account-page { display: grid; gap: 22px; }
.account-heading { display: flex; align-items: center; justify-content: space-between; padding: 26px 30px; border-radius: 18px; background: linear-gradient(125deg, #173a50, #176b87 65%, #2e9b91); color: white; box-shadow: 0 18px 45px rgba(23, 58, 80, .18); }
.account-heading h1 { margin: 7px 0 5px; font-family: "STZhongsong", "Songti SC", serif; font-size: 30px; }
.account-heading p { margin: 0; color: rgba(255,255,255,.72); }
.account-heading .eyebrow { color: #8ee4d8; }
.account-avatar { display: grid; place-items: center; width: 68px; height: 68px; border: 1px solid rgba(255,255,255,.34); border-radius: 22px; background: rgba(255,255,255,.12); font-size: 28px; font-weight: 700; }
.account-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.account-card { min-width: 0; min-height: 310px; padding: 28px; border: 1px solid #e2e8ee; border-radius: 16px; background: white; box-shadow: 0 12px 34px rgba(35, 57, 78, .07); }
.card-title { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding-bottom: 20px; border-bottom: 1px solid #edf0f3; }
.card-title span { color: #73808d; font-size: 12px; }
.card-title h2 { margin: 6px 0 0; color: #263445; font-size: 21px; }
dl { margin: 6px 0 0; }
dl > div { display: grid; grid-template-columns: 100px 1fr; gap: 18px; padding: 16px 0; border-bottom: 1px solid #f0f2f4; }
dt { color: #7b8794; font-size: 13px; }
dd { margin: 0; color: #263445; font-weight: 650; }
.role-list { display: flex; flex-wrap: wrap; gap: 7px; }
.sso-description { min-height: 54px; margin: 22px 0; color: #65717e; line-height: 1.7; }
.callback-details { margin-top: 24px; color: #65717e; font-size: 12px; }
.callback-details summary { cursor: pointer; color: #315b73; font-weight: 650; }
.callback-details p { margin: 10px 0 7px; }
.callback-details code { display: block; overflow-wrap: anywhere; padding: 10px 12px; border-radius: 8px; background: #f4f7f9; color: #176b87; }
@media (max-width: 1100px) {
  .account-grid { grid-template-columns: 1fr; }
  .account-heading { padding: 22px; }
  .account-avatar { width: 56px; height: 56px; border-radius: 18px; }
  .account-card { min-height: 0; padding: 22px; }
}
</style>
