package com.njcn.product.auth.controller;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.annotation.OperateInfo;
import com.njcn.common.pojo.constant.LogInfo;
import com.njcn.common.pojo.constant.OperateType;
import com.njcn.common.pojo.constant.SecurityConstants;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.common.LogEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.HttpResultUtil;
import com.njcn.common.utils.LogUtil;
import com.njcn.common.utils.sm.DesUtils;
import com.njcn.common.utils.sm.Sm2;

import com.njcn.product.auth.pojo.dto.UserDTO;
import com.njcn.product.auth.pojo.enums.UserResponseEnum;
import com.njcn.product.auth.pojo.param.UserParam;
import com.njcn.product.auth.pojo.po.User;
import com.njcn.product.auth.pojo.vo.UserVO;
import com.njcn.product.auth.service.IUserService;
import com.njcn.redis.utils.RedisUtil;
import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.RequestUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author hongawen
 * @since 2021-12-13
 */
@Validated
@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "用户信息管理")
@AllArgsConstructor
public class UserController extends BaseController {

    private final IUserService userService;

    private final RedisUtil redisUtil;

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getUserByName/{loginName}")
    @ApiOperation("根据登录名查询用户信息")
    @ApiImplicitParam(name = "loginName", value = "登录名", required = true)
    public HttpResult<UserDTO> getUserByName(@PathVariable String loginName) {
        RequestUtil.saveLoginName(loginName);
        String methodDescribe = getMethodDescribe("getUserByName");
        LogUtil.njcnDebug(log, "{},登录名为：{}", methodDescribe, loginName);
        UserDTO user = userService.getUserByName(loginName);
        if (Objects.isNull(user)) {
            throw new BusinessException(UserResponseEnum.LOGIN_WRONG_PWD);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, user, methodDescribe);
        }
    }


    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @ApiIgnore
    @GetMapping("/getUserByPhone/{phone}")
    @ApiOperation("根据手机号查询用户信息")
    @ApiImplicitParam(name = "phone", value = "手机号", required = true)
    public HttpResult<UserDTO> getUserByPhone(@PathVariable String phone) {
        RequestUtil.saveLoginName(phone);
        String methodDescribe = getMethodDescribe("getUserByPhone");
        LogUtil.njcnDebug(log, "{},手机号为：{}", methodDescribe, phone);
        UserDTO user = userService.loadUserByPhone(phone);
        if (Objects.isNull(user)) {
            throw new BusinessException(UserResponseEnum.LOGIN_PHONE_NOT_REGISTER);
        } else {
            return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, user, methodDescribe);
        }
    }

    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/judgeUserStatus/{loginName}")
    @ApiOperation("认证后根据用户名判断用户状态")
    @ApiImplicitParam(name = "loginName", value = "登录名", required = true)
    public HttpResult<Boolean> judgeUserStatus(@PathVariable String loginName) {
        RequestUtil.saveLoginName(loginName);
        String methodDescribe = getMethodDescribe("judgeUserStatus");
        LogUtil.njcnDebug(log, "{},登录名为：{}", methodDescribe, loginName);
        userService.judgeUserStatus(loginName);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, true, methodDescribe);
    }






    /**
     * 根据用户id获取用户详情
     *
     * @param id 用户id
     */
    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getUserById")
    @ApiOperation("用户详情")
    @ApiImplicitParam(name = "id", value = "用户id", required = true)
    public HttpResult<UserVO> getUserById(@RequestParam @Validated String id) {
        String methodDescribe = getMethodDescribe("getUserById");
        LogUtil.njcnDebug(log, "{}，用户id为：{}", methodDescribe, id);
        UserVO userVO = userService.getUserById(id);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, userVO, methodDescribe);
    }









    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/generateSm2Key")
    @ApiOperation("根据登录名获取公钥")
    @ApiImplicitParam(name = "loginName", value = "登录名", required = true)
    public HttpResult<String> generateSm2Key(String loginName, @ApiIgnore HttpServletRequest request) {
        System.out.println("request1==:" + request);
        if (StrUtil.isBlankIfStr(loginName)) {
            RequestUtil.saveLoginName(LogInfo.UNKNOWN_USER);
            throw new BusinessException(UserResponseEnum.LOGIN_USERNAME_INVALID);
        }
        String methodDescribe = getMethodDescribe("generateSm2Key");
        loginName = DesUtils.aesDecrypt(loginName);
        RequestUtil.saveLoginName(loginName);
        Map<String, String> keyMap;
        try {
            keyMap = Sm2.getSm2CipHer();
        } catch (NoSuchAlgorithmException e) {
            throw new BusinessException(CommonResponseEnum.SM2_CIPHER_ERROR);
        }
        String publicKey = keyMap.get("publicKey");
        String privateKey = keyMap.get("privateKey");
        String ip = request.getHeader(SecurityConstants.REQUEST_HEADER_KEY_CLIENT_REAL_IP);

        if (redisUtil.hasKey(loginName + ip)) {
            //秘钥先删除再添加
            redisUtil.delete(loginName + ip);
        }
        // 保存私钥到 redis
        redisUtil.saveByKeyWithExpire(loginName + ip, privateKey, 5 * 60L);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, publicKey, methodDescribe);
    }

    @OperateInfo(operateType = OperateType.UPDATE, info = LogEnum.SYSTEM_SERIOUS)
    @PutMapping("/updateUserLoginErrorTimes/{loginName}")
    @ApiOperation("更新用户登录认证密码错误次数")
    @ApiImplicitParam(name = "loginName", value = "登录名", required = true)
    public HttpResult<String> updateUserLoginErrorTimes(@PathVariable String loginName) {
        RequestUtil.saveLoginName(loginName);
        String methodDescribe = getMethodDescribe("updateUserLoginErrorTimes");
        LogUtil.njcnDebug(log, "{}，登录名为：{}", methodDescribe, loginName);
        String result = userService.updateUserLoginErrorTimes(loginName);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }



    /**
     * 查询所有用户包含管理员
     */
    @OperateInfo(info = LogEnum.SYSTEM_COMMON)
    @GetMapping("/getAllUserSimpleList")
    @ApiOperation("查询所有用户作为下拉框")
    public HttpResult<Object> getAllUserSimpleList() {
        String methodDescribe = getMethodDescribe("getAllUserSimpleList");
        List<User> result = userService.simpleList(true);
        return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
    }

}

