/**
 * 租户伪装登录状态管理模块
 *
 * 负责管理“平台管理员伪装登录租户”的状态切换与退出恢复
 *
 * @module store/modules/impersonation
 */
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { router } from '@/router'
import { resetRouterState } from '@/router/guards/beforeEach'
import { useUserStore } from '@/store/modules/user'
import { StorageConfig } from '@/utils/storage/storage-config'

interface ImpersonationSnapshot {
  originalAccessToken: string
  originalRefreshToken: string
  originalTenantId: string
  impersonatedTenantId: string
  startedAt: number
}

/**
 * 租户伪装登录 Store
 */
export const useImpersonationStore = defineStore(
  'impersonationStore',
  () => {
    // 伪装快照（为空表示未处于伪装态）
    const snapshot = ref<ImpersonationSnapshot | null>(null)

    // 计算属性：是否处于伪装态
    const isImpersonating = computed(() => snapshot.value !== null)

    /**
     * 开始伪装登录
     */
    const start = async (token: Api.Auth.TokenResponse) => {
      const userStore = useUserStore()

      // 1. 校验当前不处于伪装态
      if (isImpersonating.value) {
        throw new Error('当前已处于伪装态，请先退出后再继续')
      }

      // 2. 记录原始会话快照
      const originalTenantId = localStorage.getItem(StorageConfig.TENANT_ID_KEY) || ''
      snapshot.value = {
        originalAccessToken: userStore.accessToken,
        originalRefreshToken: userStore.refreshToken,
        originalTenantId,
        impersonatedTenantId: token.user?.tenantId || '',
        startedAt: Date.now()
      }

      // 3. 切换到目标租户会话（Token + TenantId）
      userStore.setToken(token.accessToken, token.refreshToken)
      if (token.user) {
        userStore.setUserInfo(token.user)
      }
      userStore.setLoginStatus(true)

      if (token.user?.tenantId) {
        localStorage.setItem(StorageConfig.TENANT_ID_KEY, token.user.tenantId)
      }

      // 4. 重置动态路由并重新导航（触发重新拉取用户信息与菜单）
      resetRouterState(0)
      await new Promise((resolve) => setTimeout(resolve, 20))
      await router.replace({ path: '/' })
    }

    /**
     * 退出伪装登录
     */
    const exit = async () => {
      const userStore = useUserStore()

      // 1. 校验当前处于伪装态
      if (!snapshot.value) {
        return
      }

      // 2. 恢复原始 Token 与 TenantId
      userStore.setToken(snapshot.value.originalAccessToken, snapshot.value.originalRefreshToken)
      if (snapshot.value.originalTenantId) {
        localStorage.setItem(StorageConfig.TENANT_ID_KEY, snapshot.value.originalTenantId)
      }
      userStore.setLoginStatus(true)

      // 3. 清空快照并重置动态路由
      snapshot.value = null
      resetRouterState(0)
      await new Promise((resolve) => setTimeout(resolve, 20))
      await router.replace({ path: '/' })
    }

    /**
     * 清空伪装快照（不做会话恢复）
     */
    const clear = () => {
      snapshot.value = null
    }

    return {
      snapshot,
      isImpersonating,
      start,
      exit,
      clear
    }
  },
  {
    persist: {
      key: 'impersonation',
      storage: localStorage
    }
  }
)
