package com.dji.sample.manage.controller;

import com.dji.sample.common.error.CommonErrorEnum;
import com.dji.sample.common.model.CustomClaim;
import com.dji.sample.common.util.SecurityUtils;
import com.dji.sample.manage.model.dto.UserListDTO;
import com.dji.sample.manage.model.entity.UserEntity;
import com.dji.sample.manage.model.param.ChangePasswordParam;
import com.dji.sample.manage.model.param.searchParam.LoginLogSearchParam;
import com.dji.sample.manage.model.param.searchParam.UserSearchParam;
import com.dji.sample.manage.service.IUserService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.PaginationData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

import static com.dji.sample.component.AuthInterceptor.TOKEN_CLAIM;


@RestController
@RequestMapping("${url.manage.prefix}${url.manage.version}/users")
public class UserController {

    @Autowired
    private IUserService userService;

    /**
     * Query the information of the current user.
     * @param request
     * @return
     */
    @GetMapping("/current")
    public HttpResultResponse getCurrentUserInfo(HttpServletRequest request) {
        CustomClaim customClaim = (CustomClaim)request.getAttribute(TOKEN_CLAIM);
        return userService.getUserByUsername(customClaim.getUsername(), customClaim.getWorkspaceId());
    }

    /**
     * Paging to query all users in a workspace.
     * @param param     param
     * @param page      current page
     * @param pageSize
     * @param workspaceId
     * @return
     */
    @GetMapping("/{workspace_id}/users")
    public HttpResultResponse<PaginationData<UserListDTO>> getUsers(UserSearchParam param,
                                                                    @RequestParam(defaultValue = "1") Long page,
                                                                    @RequestParam(value = "page_size", defaultValue = "50") Long pageSize,
                                                                    @PathVariable("workspace_id") String workspaceId) {
        PaginationData<UserListDTO> paginationData = userService.getUsers(param, workspaceId, page, pageSize);
        return HttpResultResponse.success(paginationData);
    }

    /**
     * Modify user information. Only mqtt account information is included, nothing else can be modified.
     * @param user
     * @param workspaceId
     * @param userId
     * @return
     */
    @PutMapping("/{workspace_id}/users/{user_id}")
    public HttpResultResponse updateUser(@RequestBody UserListDTO user,
                                         @PathVariable("workspace_id") String workspaceId,
                                         @PathVariable("user_id") String userId) {

        userService.updateUser(workspaceId, userId, user);
        return HttpResultResponse.success();
    }

    /**
     * delete user
     * @param workspaceId
     * @param userId
     * @return
     */
    @DeleteMapping("/{workspace_id}/delUser/{user_id}")
    public HttpResultResponse delUser(@PathVariable("workspace_id") String workspaceId,
                                      @PathVariable("user_id") String userId) {
        userService.deleteUser(workspaceId, userId);
        return HttpResultResponse.success();
    }

    /**
     * delete user
     * @param workspaceId
     * @return
     */
    @PostMapping("/{workspace_id}/addUser")
    public HttpResultResponse addUser(@RequestBody UserEntity user,
                                      @PathVariable("workspace_id") String workspaceId) {
        userService.addUser(workspaceId, user);
        return HttpResultResponse.success();
    }

    /**
     * Query the information of the userId user.
     * @param workspaceId
     * @param userId
     * @return
     */
    @GetMapping("/{workspace_id}/userInfo/{user_id}")
    public HttpResultResponse getOneUserInfo(@PathVariable("workspace_id") String workspaceId,
                                             @PathVariable("user_id") String userId) {

        return userService.getUserByUserId(userId, workspaceId);
    }

    /**
     * 获取用户登录日志
     *
     * @param param    查询参数
     * @param page     第几页
     * @param pageSize 每页大小
     * @return 返回结果
     */
    @PostMapping("/login_log")
    public HttpResultResponse<Object> loginLog(
            @RequestBody(required = false) LoginLogSearchParam param,
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(value = "page_size", defaultValue = "50") int pageSize
    ) {


        String userId = SecurityUtils.getUserId();

        if (StringUtils.isBlank(userId)) {
            throw new RuntimeException(CommonErrorEnum.NO_TOKEN.getMessage());
        }

        Integer roleType = SecurityUtils.getRoleType();

        return HttpResultResponse.success(userService.getUserLoginLog(param, userId, roleType, page, pageSize));
    }

    /**
     * Current user changes their own password.
     * Requires: oldPassword, newPassword, confirmPassword.
     *
     * @param request HTTP request
     * @param param   change-password parameters
     * @return result
     */
    @PostMapping("/changePassword")
    public HttpResultResponse<Object> changePassword(HttpServletRequest request,
                                                     @RequestBody ChangePasswordParam param) {
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        return userService.changePassword(customClaim.getId(), param);
    }

    /**
     * Admin resets a user's password.
     * The new password must comply with all password rules.
     *
     * @param request HTTP request
     * @param param   reset-password parameters containing newPassword
     * @return result
     */
    @PostMapping("/resetPassword")
    public HttpResultResponse<Object> resetPassword(HttpServletRequest request,
                                                    @RequestBody ChangePasswordParam param) {
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        String userId = customClaim.getId();
        return userService.resetPassword(userId, param);
    }

    /**
     * Admin changes the password of a specific user.
     * Requires admin role. The new password must comply with all password rules.
     *
     * @param param parameters containing userId and newPassword
     * @return result
     */
    @PostMapping("/changePasswordByAdmin")
    public HttpResultResponse<Object> changePasswordByAdmin(@RequestBody ChangePasswordParam param) {
        return userService.changePasswordByAdmin(param.getUserId(), param);
    }

    /**
     * Check whether the current user's password has expired.
     *
     * @param request HTTP request
     * @return true/false
     */
    @GetMapping("/passwordExpired")
    public HttpResultResponse<Boolean> passwordExpired(HttpServletRequest request) {
        CustomClaim customClaim = (CustomClaim) request.getAttribute(TOKEN_CLAIM);
        boolean expired = userService.isPasswordExpired(customClaim.getId());
        return HttpResultResponse.success(expired);
    }

}
