package com.hertz.modules.system.controller;

import com.hertz.common.api.ApiResponse;
import com.hertz.common.exception.BusinessException;
import com.hertz.security.JwtService;
import com.hertz.security.SecurityUtils;
import com.hertz.modules.system.dto.AuthDtos;
import com.hertz.modules.system.mapper.SysRoleMapper;
import com.hertz.modules.system.service.CaptchaService;
import com.hertz.modules.system.service.UserService;
import jakarta.validation.Valid;
import java.util.List;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/auth")
public class AuthController {
  private final UserService userService;
  private final PasswordEncoder passwordEncoder;
  private final JwtService jwtService;
  private final SysRoleMapper roleMapper;
  private final CaptchaService captchaService;

  public AuthController(
      UserService userService,
      PasswordEncoder passwordEncoder,
      JwtService jwtService,
      SysRoleMapper roleMapper,
      CaptchaService captchaService
  ) {
    this.userService = userService;
    this.passwordEncoder = passwordEncoder;
    this.jwtService = jwtService;
    this.roleMapper = roleMapper;
    this.captchaService = captchaService;
  }

  @PostMapping("/register")
  public ApiResponse<AuthDtos.MeResponse> register(@Valid @RequestBody AuthDtos.RegisterRequest req) {
    captchaService.validateCaptcha(req.uuid(), req.code());
    var user = userService.register(req.username(), req.password(), req.nickname());
    return ApiResponse.ok(new AuthDtos.MeResponse(
        user.getId(),
        user.getUsername(),
        user.getNickname(),
        user.getAvatarPath(),
        user.getPhone(),
        user.getEmail(),
        user.getGender(),
        List.of()
    ));
  }

  @PostMapping("/login")
  public ApiResponse<AuthDtos.LoginResponse> login(@Valid @RequestBody AuthDtos.LoginRequest req) {
    captchaService.validateCaptcha(req.uuid(), req.code());
    var user = userService.findByUsername(req.username());
    if (user == null || user.getStatus() == null || user.getStatus() != 1) {
      throw new BusinessException(40003, "用户名或密码错误");
    }
    if (!passwordEncoder.matches(req.password(), user.getPassword())) {
      throw new BusinessException(40003, "用户名或密码错误");
    }
    var token = jwtService.createToken(user.getId(), user.getUsername());
    var roles = roleMapper.selectRoleKeysByUserId(user.getId());
    return ApiResponse.ok(new AuthDtos.LoginResponse(token, user.getId(), user.getUsername(), roles));
  }

  @GetMapping("/me")
  public ApiResponse<AuthDtos.MeResponse> me(Authentication authentication) {
    var userId = SecurityUtils.getCurrentUserId(authentication);
    if (userId == null) {
      throw new BusinessException(40100, "未登录或登录已过期");
    }
    var user = userService.findByUsername(authentication.getName());
    var roles = roleMapper.selectRoleKeysByUserId(userId);
    return ApiResponse.ok(new AuthDtos.MeResponse(
        userId,
        authentication.getName(),
        user == null ? null : user.getNickname(),
        user == null ? null : user.getAvatarPath(),
        user == null ? null : user.getPhone(),
        user == null ? null : user.getEmail(),
        user == null ? null : user.getGender(),
        roles
    ));
  }

  @PostMapping("/profile")
  public ApiResponse<Void> updateProfile(@RequestBody @Valid AuthDtos.UpdateProfileRequest req) {
    var userId = SecurityUtils.getCurrentUserId();
    if (userId == null) {
      throw new BusinessException(40100, "未登录或登录已过期");
    }
    userService.updateProfile(userId, req);
    return ApiResponse.ok();
  }

  @PostMapping("/password")
  public ApiResponse<Void> updatePassword(@RequestBody @Valid AuthDtos.UpdatePasswordRequest req) {
    var userId = SecurityUtils.getCurrentUserId();
    if (userId == null) {
      throw new BusinessException(40100, "未登录或登录已过期");
    }
    userService.updatePassword(userId, req);
    return ApiResponse.ok();
  }
}

