import { to } from 'await-to-js';
import { getToken, removeToken, setToken } from '@/utils/auth';
import { getInfo as getUserInfo, login as loginApi, logout as logoutApi } from '@/api/login';
import { LoginData, LoginResult } from '@/api/types';
import defAva from '@/assets/images/profile.jpg';
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';
import { AxiosResponse } from 'axios';

export const useUserStore = defineStore('user', () => {
  const token = ref(getToken());
  const name = ref('');
  const nickname = ref('');
  const userId = ref<string | number>('');
  const tenantId = ref<string>('');
  const avatar = ref('');
  const loginIp = ref('');
  const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
  const permissions = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限

  // 第一次登录修改密码标志（首次登录或密码过期）
  const pwdFirstChange = ref(false);
  // 强制修改密码标志（管理员重置密码后）
  const forcePwdChange = ref(false);
  // 账号是否已实名认证
  const realAuth = ref(true);
  // 最后密码修改时间
  const lastPwdUpdateTime = ref<string | null>(null);
  // 当前用户信息引用，不持久化，仅用于当前会话获取完整用户信息
  const userInfo = ref<any>(null);

  /**
   * 检查是否需要修改密码
   */
  const needsPasswordChange = computed(() => {
    return pwdFirstChange.value || forcePwdChange.value;
  });

  /**
   * 登录
   * @param userInfo
   * @returns
   */
  const login = async (userInfo: LoginData): Promise<AxiosResponse<LoginResult>> => {
    const [err, res] = await to(loginApi(userInfo));
    if (res) {
      const data = res.data;

      // 根据登录状态处理不同情况
      if (data.loginStatus === 0) {
        // 登录成功，设置token
        setToken(data.access_token);
        token.value = data.access_token;
      }
      // 对于需要人脸识别(1)或双因子验证(2)的情况，不设置token，由前端组件处理

      return Promise.resolve(res);
    }
    return Promise.reject(err);
  };

  // 获取用户信息
  const getInfo = async (): Promise<void> => {
    const [err, res] = await to(getUserInfo());
    if (res) {
      const data = res.data;
      const user = data.user;
      const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;

      if (data.roles && data.roles.length > 0) {
        // 验证返回的roles是否是一个非空数组
        roles.value = data.roles;
        permissions.value = data.permissions;
      } else {
        roles.value = ['ROLE_DEFAULT'];
      }
      name.value = user.userName;
      nickname.value = user.nickName;
      avatar.value = profile;
      userId.value = user.userId;
      tenantId.value = user.tenantId;
      loginIp.value = user.loginIp;

      // 密码修改相关标志
      pwdFirstChange.value = data.pwdFlag === true;
      forcePwdChange.value = data.forcePwdFlag === true;

      // 检查账号是否已实名认证
      realAuth.value = data.realAuth !== false;
      // 保存最后密码修改时间
      lastPwdUpdateTime.value = user.lastPwdUpdateTime || null;
      // 保存当前用户完整信息的引用
      userInfo.value = data;
      return Promise.resolve();
    }
    return Promise.reject(err);
  };

  // 注销
  const logout = async (): Promise<void> => {
    await logoutApi();
    token.value = '';
    roles.value = [];
    permissions.value = [];
    pwdFirstChange.value = false;
    forcePwdChange.value = false;
    realAuth.value = true;
    lastPwdUpdateTime.value = null;
    userInfo.value = null;
    removeToken();
  };

  const setAvatar = (value: string) => {
    avatar.value = value;
  };

  // 设置密码已修改状态
  const setPwdChanged = () => {
    pwdFirstChange.value = false;
    forcePwdChange.value = false;
    if (userInfo.value) {
      userInfo.value.pwdFlag = false;
      userInfo.value.forcePwdFlag = false;
    }
    // 更新最后密码修改时间为当前时间（仅UI显示用）
    lastPwdUpdateTime.value = new Date().toISOString();
  };

  // 设置强制修改密码状态（用于管理员重置密码后）
  const setForcePwdChange = (force: boolean = true) => {
    forcePwdChange.value = force;
    if (userInfo.value) {
      userInfo.value.forcePwdFlag = force;
    }
  };

  // 检查是否为首次登录
  const isFirstLogin = () => {
    return !lastPwdUpdateTime.value && pwdFirstChange.value;
  };

  return {
    userId,
    tenantId,
    token,
    name,
    nickname,
    loginIp,
    avatar,
    roles,
    permissions,
    pwdFirstChange, // 首次登录或密码过期修改密码标志
    forcePwdChange, // 强制修改密码标志（管理员重置后）
    realAuth, // 账号是否已实名认证
    lastPwdUpdateTime, // 最后密码修改时间
    userInfo, // 用户完整信息引用（不用于持久化）
    needsPasswordChange, // 计算属性：是否需要修改密码
    login,
    getInfo,
    logout,
    setAvatar,
    setPwdChanged, // 设置密码已修改状态的方法
    setForcePwdChange, // 设置强制修改密码状态的方法
    isFirstLogin // 检查是否为首次登录的方法
  };
});
