/**
 * 用户认证相关API接口模块
 *
 * @fileoverview 提供用户登录、注册、认证、短信验证等相关的API接口
 * @author 系统开发团队
 * @version 2.0.0
 * @since 1.0.0
 *
 * @description
 * 本模块包含以下功能分组：
 * - 用户登录相关API：普通登录、微信登录、手机号登录
 * - 用户注册相关API：用户注册、密码重置
 * - 会话管理相关API：登出、token刷新
 * - 短信验证相关API：发送验证码、验证码校验
 *
 * @example
 * // 基本用法示例
 * import { userLogin, wxPhoneLogin } from '@/http/api/auth.js'
 *
 * // 用户登录
 * const result = await userLogin({ username: 'user', password: 'pass' })
 *
 * // 微信手机号登录
 * const result = await wxPhoneLogin({ code, encryptedData, iv })
 *
 * @example
 * // 使用配置常量
 * import { AUTH_CONFIG, AUTH_UTILS } from '@/http/api/auth.js'
 *
 * // 使用工具函数创建自定义请求
 * const customRequest = AUTH_UTILS.executeAuthRequest('/custom/auth')
 */

// ==================== 类型定义 ====================

/**
 * @typedef {Object} LoginData 登录数据对象
 * @property {string} username 用户名
 * @property {string} password 密码
 * @property {boolean} [rememberMe] 是否记住登录状态
 */

/**
 * @typedef {Object} WxLoginData 微信登录数据对象
 * @property {string} code 微信登录凭证
 * @property {string} [encryptedData] 加密数据
 * @property {string} [iv] 初始向量
 */

/**
 * @typedef {Object} PhoneAuthData 手机号授权数据对象
 * @property {string} code 微信登录凭证
 * @property {string} encryptedData 加密的手机号数据
 * @property {string} iv 初始向量
 */

/**
 * @typedef {Object} AuthResult 认证结果对象
 * @property {string} token 访问令牌
 * @property {string} refreshToken 刷新令牌
 * @property {Object} userInfo 用户基本信息
 * @property {number} expiresIn 令牌过期时间（秒）
 */

// ==================== 配置常量 ====================

/**
 * 认证API的默认配置模板
 */
const AUTH_CONFIG_TEMPLATES = {
	// 无需认证的登录请求
	PUBLIC_AUTH: {
		auth: false,
		loading: true,
		toast: true
	},

	// 需要认证的会话管理请求
	AUTHENTICATED_SESSION: {
		auth: true,
		loading: true,
		toast: true
	},

	// 静默的token刷新请求
	SILENT_REFRESH: {
		auth: false,
		loading: false,
		toast: false
	}
}

/**
 * 认证相关的loading文本配置
 */
const AUTH_LOADING_TEXTS = {
	LOGIN: '正在登录...',
	WX_LOGIN: '正在登录...',
	PHONE_VERIFY: '正在验证手机号...',
	REGISTER: '正在注册...',
	LOGOUT: '正在退出...',
	SEND_SMS: '正在发送验证码...',
	VERIFY_SMS: '正在验证...',
	RESET_PASSWORD: '正在重置密码...'
}

// ==================== 工具函数 ====================

/**
 * 创建认证请求的标准化配置
 * @param {string} template 配置模板名称
 * @param {Object} customConfig 自定义配置
 * @param {string} loadingText 自定义loading文本
 * @returns {Object} 标准化的请求配置
 */
const createAuthConfig = (template, customConfig = {}, loadingText = null) => {
	const baseConfig = AUTH_CONFIG_TEMPLATES[template] || {}

	const config = {
		custom: {
			...baseConfig,
			...(loadingText && { loadingText }),
			...customConfig.custom
		},
		...customConfig
	}

	// 移除custom属性中的undefined值
	Object.keys(config.custom).forEach(key => {
		if (config.custom[key] === undefined) {
			delete config.custom[key]
		}
	})

	return config
}

/**
 * 执行认证相关的POST请求
 * @param {string} url 请求URL
 * @param {Object} data 请求数据
 * @param {string} template 配置模板
 * @param {string} loadingText loading文本
 * @param {Object} config 自定义配置
 * @returns {Promise} 请求Promise
 */
const executeAuthRequest = (url, data = {}, template = 'PUBLIC_AUTH', loadingText = null, config = {}) => {
	const requestConfig = createAuthConfig(template, config, loadingText)

	return uni.$u.http.post(url, data, requestConfig)
}

// ==================== API方法 ====================

// ==================== 用户登录相关API ====================

/**
 * 用户账号密码登录
 * @description 使用用户名和密码进行登录认证
 * @param {LoginData} loginData 登录数据对象
 * @param {string} loginData.username 用户名或邮箱
 * @param {string} loginData.password 用户密码
 * @param {boolean} [loginData.rememberMe=false] 是否记住登录状态
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<AuthResult>} 返回认证结果，包含token和用户信息
 * @example
 * // 基本登录
 * const result = await userLogin({
 *   username: 'user@example.com',
 *   password: 'password123'
 * })
 *
 * // 记住登录状态
 * const result = await userLogin({
 *   username: 'user@example.com',
 *   password: 'password123',
 *   rememberMe: true
 * })
 */
export const userLogin = (loginData, config = {}) => {
	return executeAuthRequest('/auth/login', loginData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.LOGIN, config)
}

/**
 * 微信授权登录
 * @description 使用微信授权码进行登录认证
 * @param {WxLoginData} wxData 微信登录数据对象
 * @param {string} wxData.code 微信登录凭证code
 * @param {string} [wxData.encryptedData] 加密的用户数据
 * @param {string} [wxData.iv] 初始向量
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<AuthResult>} 返回认证结果，包含token和用户信息
 * @example
 * // 基本微信登录
 * const result = await wxLogin({ code: 'wx_code_123' })
 *
 * // 包含用户信息的微信登录
 * const result = await wxLogin({
 *   code: 'wx_code_123',
 *   encryptedData: 'encrypted_user_data',
 *   iv: 'initial_vector'
 * })
 */
export const wxLogin = (wxData, config = {}) => {
	return executeAuthRequest('/auth/wx-login', wxData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.WX_LOGIN, config)
}

/**
 * 微信手机号授权登录
 * @description 使用微信手机号授权进行登录认证，适用于小程序环境
 * @param {PhoneAuthData} phoneData 手机号授权数据对象
 * @param {string} phoneData.code 微信登录凭证code
 * @param {string} phoneData.encryptedData 加密的手机号数据
 * @param {string} phoneData.iv 初始向量
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<AuthResult>} 返回认证结果，包含token和用户信息
 * @example
 * // 微信手机号登录
 * const result = await wxPhoneLogin({
 *   code: 'wx_code_123',
 *   encryptedData: 'encrypted_phone_data',
 *   iv: 'initial_vector'
 * })
 *
 * @since 2.0.0 新增的登录流程重构功能
 */
export const wxPhoneLogin = (phoneData, config = {}) => {
	return executeAuthRequest('/auth/wx-phone-login', phoneData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.PHONE_VERIFY, config)
}

// ==================== 用户注册相关API ====================

/**
 * 用户账号注册
 * @description 创建新的用户账号
 * @param {Object} registerData 注册数据对象
 * @param {string} registerData.username 用户名
 * @param {string} registerData.password 密码
 * @param {string} registerData.email 邮箱地址
 * @param {string} [registerData.phoneNumber] 手机号码
 * @param {string} [registerData.inviteCode] 邀请码
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<AuthResult>} 返回注册结果，包含token和用户信息
 * @example
 * // 基本注册
 * const result = await userRegister({
 *   username: 'newuser',
 *   password: 'password123',
 *   email: 'user@example.com'
 * })
 *
 * // 包含手机号的注册
 * const result = await userRegister({
 *   username: 'newuser',
 *   password: 'password123',
 *   email: 'user@example.com',
 *   phoneNumber: '13800138000'
 * })
 */
export const userRegister = (registerData, config = {}) => {
	return executeAuthRequest('/auth/register', registerData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.REGISTER, config)
}

// ==================== 会话管理相关API ====================

/**
 * 用户登出
 * @description 退出当前用户登录状态，清除服务端会话
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<Object>} 返回登出结果
 * @example
 * // 基本登出
 * await userLogout()
 *
 * // 静默登出（不显示loading）
 * await userLogout({
 *   custom: { loading: false }
 * })
 */
export const userLogout = (config = {}) => {
	return executeAuthRequest('/auth/logout', {}, 'AUTHENTICATED_SESSION', AUTH_LOADING_TEXTS.LOGOUT, config)
}

/**
 * 刷新访问令牌
 * @description 使用刷新令牌获取新的访问令牌，通常在token过期时自动调用
 * @param {Object} [config={}] 自定义请求配置
 * @param {string} [config.refreshToken] 自定义刷新令牌，不传则从本地存储获取
 * @returns {Promise<Object>} 返回新的token信息
 * @example
 * // 自动刷新token
 * const newTokens = await refreshToken()
 *
 * // 使用自定义刷新令牌
 * const newTokens = await refreshToken({
 *   refreshToken: 'custom_refresh_token'
 * })
 */
export const refreshToken = (config = {}) => {
	const refreshTokenValue = config.refreshToken || uni.getStorageSync('refreshToken')
	const requestConfig = createAuthConfig('SILENT_REFRESH', config)

	return uni.$u.http.post('/auth/refresh', { refreshToken: refreshTokenValue }, requestConfig)
}

// ==================== 短信验证相关API ====================

/**
 * 发送短信验证码
 * @description 向指定手机号发送短信验证码，用于注册、登录或密码重置
 * @param {Object} phoneData 手机号数据对象
 * @param {string} phoneData.phoneNumber 手机号码
 * @param {string} phoneData.type 验证码类型：'register' | 'login' | 'reset' | 'bind'
 * @param {string} [phoneData.captcha] 图形验证码（防刷机制）
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<Object>} 返回发送结果，包含验证码ID和过期时间
 * @example
 * // 注册时发送验证码
 * const result = await sendSmsCode({
 *   phoneNumber: '13800138000',
 *   type: 'register'
 * })
 *
 * // 密码重置时发送验证码
 * const result = await sendSmsCode({
 *   phoneNumber: '13800138000',
 *   type: 'reset',
 *   captcha: 'abc123'
 * })
 */
export const sendSmsCode = (phoneData, config = {}) => {
	return executeAuthRequest('/sms/send', phoneData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.SEND_SMS, config)
}

/**
 * 验证短信验证码
 * @description 验证用户输入的短信验证码是否正确
 * @param {Object} verifyData 验证数据对象
 * @param {string} verifyData.phoneNumber 手机号码
 * @param {string} verifyData.code 验证码
 * @param {string} verifyData.codeId 验证码ID（发送时返回）
 * @param {string} verifyData.type 验证码类型
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<Object>} 返回验证结果
 * @example
 * // 验证注册验证码
 * const result = await verifySmsCode({
 *   phoneNumber: '13800138000',
 *   code: '123456',
 *   codeId: 'sms_id_123',
 *   type: 'register'
 * })
 */
export const verifySmsCode = (verifyData, config = {}) => {
	return executeAuthRequest('/sms/verify', verifyData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.VERIFY_SMS, config)
}

/**
 * 重置用户密码
 * @description 通过短信验证码重置用户密码
 * @param {Object} resetData 重置密码数据对象
 * @param {string} resetData.phoneNumber 手机号码
 * @param {string} resetData.code 短信验证码
 * @param {string} resetData.codeId 验证码ID
 * @param {string} resetData.newPassword 新密码
 * @param {Object} [config={}] 自定义请求配置
 * @returns {Promise<Object>} 返回重置结果
 * @example
 * // 重置密码
 * const result = await resetPassword({
 *   phoneNumber: '13800138000',
 *   code: '123456',
 *   codeId: 'sms_id_123',
 *   newPassword: 'newPassword123'
 * })
 */
export const resetPassword = (resetData, config = {}) => {
	return executeAuthRequest('/auth/reset-password', resetData, 'PUBLIC_AUTH', AUTH_LOADING_TEXTS.RESET_PASSWORD, config)
}

// ==================== 导出配置常量（供外部使用） ====================

/**
 * 导出认证配置常量，供其他模块使用
 */
export const AUTH_CONFIG = {
	AUTH_CONFIG_TEMPLATES,
	AUTH_LOADING_TEXTS
}

/**
 * 导出认证工具函数，供其他模块使用
 */
export const AUTH_UTILS = {
	createAuthConfig,
	executeAuthRequest
}
