package com.test.musichouduan.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import com.test.musichouduan.dto.*;
import com.test.musichouduan.service.FileService;
import com.test.musichouduan.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

/**
 * 用户控制器
 */
@Tag(name = "用户接口", description = "用户的注册、登录、信息管理等操作")
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private FileService fileService;

    /**
     * 用户注册
     *
     * @param request 注册请求
     * @return 响应结果
     */
    @SaIgnore
    @Operation(summary = "用户注册", description = "新用户注册接口")
    @PostMapping("/register")
    public Result<UserDTO> register(@Parameter(description = "注册信息") @Validated @RequestBody RegisterRequest request) {
        UserDTO userDTO = userService.register(request);
        return Result.success("注册成功", userDTO);
    }

    /**
     * 用户登录
     *
     * @param request 登录请求
     * @return 响应结果
     */
    @SaIgnore
    @Operation(summary = "用户登录", description = "用户登录接口，登录成功后返回用户信息和令牌")
    @PostMapping("/login")
    public Result<LoginResultDTO> login(@Parameter(description = "登录信息") @Validated @RequestBody LoginRequest request) {
        LoginResultDTO resultDTO = userService.login(request);
        return Result.success("登录成功", resultDTO);
    }

    /**
     * 用户登出
     *
     * @return 响应结果
     */
    @Operation(summary = "用户登出", description = "用户登出接口，需要登录状态")
    @SaCheckLogin
    @PostMapping("/logout")
    public Result<String> logout() {
        StpUtil.logout();
        return Result.success("登出成功", null);
    }

    /**
     * 获取当前登录用户
     *
     * @return 响应结果
     */
    @Operation(summary = "获取当前登录用户", description = "获取当前登录用户的信息，需要登录状态")
    @SaCheckLogin
    @GetMapping("/current")
    public Result<UserDTO> getCurrentUser() {
        UserDTO userDTO = userService.getCurrentUser();
        return Result.success(userDTO);
    }

    /**
     * 更新用户信息
     *
     * @param request 用户信息更新请求
     * @return 响应结果
     */
    @Operation(summary = "更新用户信息", description = "更新当前登录用户的信息，需要登录状态")
    @SaCheckLogin
    @PutMapping("/update")
    public Result<UserDTO> updateUser(@Parameter(description = "用户信息更新请求") @Validated @RequestBody UserUpdateRequest request) {
        UserDTO userDTO = userService.updateUser(request);
        return Result.success("更新成功", userDTO);
    }

    /**
     * 修改密码
     *
     * @param request 修改密码请求
     * @return 响应结果
     */
    @Operation(summary = "修改密码", description = "修改当前登录用户的密码，需要登录状态")
    @SaCheckLogin
    @PutMapping("/password")
    public Result<Boolean> updatePassword(@Parameter(description = "密码修改请求") @Validated @RequestBody PasswordUpdateRequest request) {
        boolean result = userService.updatePassword(request);
        return Result.success("修改成功", result);
    }

    /**
     * 获取用户统计数据
     *
     * @return 响应结果
     */
    @Operation(summary = "获取用户统计数据", description = "获取当前登录用户的统计数据，包括收藏数量等，需要登录状态")
    @SaCheckLogin
    @GetMapping("/stats")
    public Result<UserDTO> getUserStats() {
        UserDTO userDTO = userService.getUserStats(StpUtil.getLoginIdAsLong());
        return Result.success(userDTO);
    }

    /**
     * 分页获取用户列表
     *
     * @param page 页码
     * @param size 每页大小
     * @param keyword 关键字
     * @return 响应结果
     */
    @Operation(summary = "分页获取用户列表", description = "分页获取用户列表，支持关键字搜索，需要管理员权限")
    @SaCheckRole("admin")
    @GetMapping("/list")
    public Result<PageResult<UserDTO>> getUserList(
            @Parameter(description = "页码", example = "1") @RequestParam(defaultValue = "1") Integer page,
            @Parameter(description = "每页大小", example = "10") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "搜索关键字", example = "用户名") @RequestParam(required = false) String keyword) {
        PageResult<UserDTO> pageResult = userService.getUserList(page, size, keyword);
        return Result.success(pageResult);
    }

    /**
     * 根据ID获取用户
     *
     * @param id 用户ID
     * @return 响应结果
     */
    @Operation(summary = "根据ID获取用户", description = "根据用户ID获取用户信息，需要管理员权限")
    @SaCheckRole("admin")
    @GetMapping("/{id}")
    public Result<UserDTO> getUserById(@Parameter(description = "用户ID", example = "1") @PathVariable Long id) {
        UserDTO userDTO = userService.getUserById(id);
        return Result.success(userDTO);
    }

    /**
     * 删除用户
     *
     * @param id 用户ID
     * @return 响应结果
     */
    @Operation(summary = "删除用户", description = "根据用户ID删除用户，需要管理员权限")
    @SaCheckRole("admin")
    @DeleteMapping("/{id}")
    public Result<Boolean> deleteUser(@Parameter(description = "用户ID", example = "1") @PathVariable Long id) {
        boolean result = userService.deleteUser(id);
        return Result.success("删除成功", result);
    }

    /**
     * 更新用户状态
     *
     * @param id 用户ID
     * @param status 状态
     * @return 响应结果
     */
    @Operation(summary = "更新用户状态", description = "更新用户状态，0-禁用，1-启用，需要管理员权限")
    @SaCheckRole("admin")
    @PutMapping("/{id}/status")
    public Result<Boolean> updateUserStatus(
            @Parameter(description = "用户ID", example = "1") @PathVariable Long id,
            @Parameter(description = "状态，0-禁用，1-启用", example = "1") @RequestParam Integer status) {
        boolean result = userService.updateUserStatus(id, status);
        return Result.success("更新成功", result);
    }

    /**
     * 管理员更新用户信息
     *
     * @param id 用户ID
     * @param request 用户信息更新请求
     * @return 响应结果
     */
    @Operation(summary = "管理员更新用户信息", description = "管理员更新用户信息，需要管理员权限")
    @SaCheckRole("admin")
    @PutMapping("/{id}")
    public Result<UserDTO> adminUpdateUser(
            @Parameter(description = "用户ID", example = "1") @PathVariable Long id,
            @Parameter(description = "用户信息更新请求") @Validated @RequestBody UserUpdateRequest request) {
        UserDTO userDTO = userService.adminUpdateUser(id, request);
        return Result.success("更新成功", userDTO);
    }

    /**
     * 上传用户头像
     *
     * @param file 头像文件
     * @return 响应结果
     */
    @Operation(summary = "上传用户头像", description = "上传当前登录用户的头像，需要登录状态")
    @SaCheckLogin
    @PostMapping("/upload/avatar")
    public Result<String> uploadAvatar(@Parameter(description = "头像文件") @RequestParam("file") MultipartFile file) {
        // 上传头像
        String avatarPhysicalPath = fileService.uploadImage(file);
        String avatarUrl = avatarPhysicalPath.replace(System.getProperty("user.dir") + File.separator + "music-houduan", "").replace(File.separator, "/");

        // 用户ID已经通过 SaCheckLogin 注解验证

        // 更新用户头像
        UserUpdateRequest request = new UserUpdateRequest();
        request.setAvatar(avatarUrl);
        userService.updateUser(request);

        return Result.success("上传成功", avatarUrl);
    }
}
