package com.xyw.console.auth;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xyw.console.asset.entity.SystemUserEntity;
import com.xyw.console.asset.mapper.SystemUserMapper;
import com.xyw.console.auth.dto.CurrentUserResponse;
import com.xyw.console.auth.dto.LoginRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

@Service
public class AuthService {
  private final SystemUserMapper users; private final PasswordEncoder encoder; private final AuthTokenService tokens; private final PagePermissionService permissions;
  /** 代码作用（白话）：接收认证依赖；关联文件：AuthController.java、SystemUserMapper.java。关联逻辑（调用链/数据流）：Controller -> Service -> 用户表/令牌/权限。 */
  public AuthService(SystemUserMapper users, PasswordEncoder encoder, AuthTokenService tokens, PagePermissionService permissions) { this.users = users; this.encoder = encoder; this.tokens = tokens; this.permissions = permissions; }
  /** 代码作用（白话）：验证账号密码并签发登录 Cookie；关联文件：LoginRequest.java、AuthTokenService.java。关联逻辑（调用链/数据流）：登录表单 -> 用户表/BCrypt -> Cookie -> 当前用户响应。 */
  public CurrentUserResponse login(LoginRequest request, HttpServletResponse response) { SystemUserEntity user = users.selectOne(new LambdaQueryWrapper<SystemUserEntity>().eq(SystemUserEntity::getUsername, request.username()).eq(SystemUserEntity::getDeleteTime, 0L)); if (user == null || !"ACTIVE".equals(user.getStatus()) || user.getPasswordHash() == null || !encoder.matches(request.password(), user.getPasswordHash())) throw new BadCredentialsException("账号或密码错误"); tokens.issue(new AuthPrincipal(user.getId(), user.getUsername(), user.getRoleCode(), user.getAuthVersion() == null ? 1 : user.getAuthVersion()), response); return responseOf(user); }
  /** 代码作用（白话）：把当前令牌身份重新读取为最新菜单资料；关联文件：AuthTokenFilter.java、App.js。关联逻辑（调用链/数据流）：Cookie -> SecurityContext -> 用户表 -> 菜单权限响应。 */
  public CurrentUserResponse me() { Object value = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); if (!(value instanceof AuthPrincipal principal)) throw new BadCredentialsException("登录已失效"); SystemUserEntity user = users.selectById(principal.userId()); if (user == null || !"ACTIVE".equals(user.getStatus())) throw new BadCredentialsException("登录已失效"); return responseOf(user); }
  /** 代码作用（白话）：让浏览器删除登录 Cookie；关联文件：AuthController.java。关联逻辑（调用链/数据流）：登出按钮 -> Service -> 过期 Cookie。 */
  public void logout(HttpServletResponse response) { tokens.clear(response); }
  /** 代码作用（白话）：将用户实体转换为绝不包含密码哈希的当前登录响应；关联文件：CurrentUserResponse.java、auth-store.js。关联逻辑（调用链/数据流）：用户表 -> 计算有效权限 -> 前端会话状态。 */
  private CurrentUserResponse responseOf(SystemUserEntity user) { return new CurrentUserResponse(user.getId(), user.getUsername(), user.getRoleCode(), permissions.effectivePermissions(user)); }
}
