package com.tuoheng.miniprogram.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tuoheng.common.core.config.common.CommonConfig;
import com.tuoheng.common.core.exception.ServiceException;
import com.tuoheng.common.core.utils.CommonUtils;
import com.tuoheng.common.core.utils.JsonResult;
import com.tuoheng.common.core.utils.SecurityUserUtils;
import com.tuoheng.common.core.utils.StringUtils;
import com.tuoheng.miniprogram.config.CommonsConfig;
import com.tuoheng.miniprogram.constant.OidcUrlConstant;
import com.tuoheng.miniprogram.dao.DeptMapper;
import com.tuoheng.miniprogram.dao.UserMapper;
import com.tuoheng.miniprogram.entity.Dept;
import com.tuoheng.miniprogram.entity.dto.ResetPwdDto;
import com.tuoheng.miniprogram.entity.User;
import com.tuoheng.miniprogram.entity.dto.SubscribeTimesDto;
import com.tuoheng.miniprogram.entity.query.OidcUpdatePassRequest;
import com.tuoheng.miniprogram.enums.MarkEnum;
import com.tuoheng.miniprogram.enums.SubscribeTimesEnum;
import com.tuoheng.miniprogram.enums.UserCodeEnum;
import com.tuoheng.miniprogram.service.IUserService;
import com.tuoheng.miniprogram.utils.CurrentUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Author ChengWang
 * @Date 2022/11/21
 */
@Service
@Slf4j
public class IUserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public JsonResult getUserInfo() {
        //登录用户信息
        User userInfo = CurrentUserUtil.getUserInfo();
        String username = userInfo.getUsername();
        if(StringUtils.isEmpty(username)){
            return JsonResult.error(UserCodeEnum.USER_NAME_IS_NULL.getCode(),UserCodeEnum.USER_NAME_IS_NULL.getMsg());
        }
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, username)
                .eq(User::getMark, MarkEnum.VALID.getCode()));
        if(ObjectUtil.isNull(user)){
            return JsonResult.error(UserCodeEnum.USER_IS_NULL.getCode(),UserCodeEnum.USER_IS_NULL.getMsg());
        }
        if(2== user.getStatus()){
            return JsonResult.error(UserCodeEnum.USER_STATUS_INTERDICT.getCode(),UserCodeEnum.USER_STATUS_INTERDICT.getMsg());
        }
        if(StringUtils.isNotEmpty(user.getAvatar())){
            user.setAvatar(CommonConfig.imageURL+user.getAvatar());
        }
        //获取部门名称
        if(StringUtils.isNotEmpty(user.getDeptId())){
            Dept dept = deptMapper.selectById(user.getDeptId());
            if(StringUtils.isNotNull(dept)){
                user.setDeptName(dept.getName());
            }
        }

        return JsonResult.success(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult resetPwd(ResetPwdDto dto) {
        //获取登录用户信息
        String username = SecurityUserUtils.username();
        //查询登录用户
        User user = userMapper.selectOne(Wrappers.<User>lambdaQuery()
                .eq(StringUtils.isNotEmpty(username), User::getUsername, username)
                .eq(User::getMark, 1)
                .eq(User::getStatus, 1));
        if(ObjectUtil.isNull(user)){
            return JsonResult.error(UserCodeEnum.USER_IS_NULL.getCode(),UserCodeEnum.USER_IS_NULL.getMsg());
        }
        //密码校验
        if (!user.getPassword().equals(CommonUtils.password(dto.getOldPassword()))) {
            return JsonResult.error(UserCodeEnum.OLD_PASSWORD_IS_ERROR.getCode(),UserCodeEnum.OLD_PASSWORD_IS_ERROR.getMsg());
        }
        //设置新密码
        user.setPassword(CommonUtils.password(dto.getNewPassword()));
        int count = userMapper.updateById(user);
        if (count == 0) {
            return JsonResult.error(UserCodeEnum.PASSWORD_REVISE_FAIL.getCode(), UserCodeEnum.PASSWORD_REVISE_FAIL.getMsg());
        }
        //设置第三方请求实体
        OidcUpdatePassRequest oidcUpdatePassRequest = new OidcUpdatePassRequest();
        oidcUpdatePassRequest.setUsername(username);
        oidcUpdatePassRequest.setPassword(dto.getNewPassword());
        //设置请求头
        //设置请求头
        org.springframework.http.HttpHeaders resultRequestHeader = new HttpHeaders();
        resultRequestHeader.add("Authorization", "Bearer " + SecurityUserUtils.token());
        HttpEntity httpEntity = new HttpEntity(oidcUpdatePassRequest, resultRequestHeader);
        //设置地址，飞手小程序 经过网关
        String url = CommonsConfig.oidcUrl + OidcUrlConstant.USER_UPDATEPASS;
        ResponseEntity<JsonResult> response;
        try {
            response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, JsonResult.class);
        } catch (Exception e) {
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "oidc修改用户密码失败");
        }
        if (null == response || !response.hasBody()) {
            log.error("oidc修改用户密码响应失败");
            throw new ServiceException(HttpStatus.BAD_REQUEST.value(), "oidc修改用户密码失败");
        }
        if (response.getBody().getCode() != JsonResult.SUCCESS) {
            log.error("oidc修改用户密码失败" + response.getBody());
            return JsonResult.error(response.getBody().getMsg());
        }
        return JsonResult.success(UserCodeEnum.PASSWORD_REVISE_SUCCESS.getCode(), UserCodeEnum.PASSWORD_REVISE_SUCCESS.getMsg());
    }

    @Override
    public JsonResult getList(String deptId) {
        User user = CurrentUserUtil.getUserInfo();
        if(StringUtils.isEmpty(user.getDeptId())){
            return JsonResult.error("用户部门不存在");
        }
        List<User> userList = userMapper.selectList(Wrappers.<User>lambdaQuery()
                .eq(User::getMark, MarkEnum.VALID.getCode())
                .eq(User::getDeptId, deptId)
                .eq(User::getStatus, 1));
        return JsonResult.success(userList);
    }

    @Override
    public JsonResult updateSubscribe() {
        User user = CurrentUserUtil.getUserInfo();
        user.setSubscribeTimes(SubscribeTimesEnum.SUBSCRIBE_TIMES_NO_ONE.getCode());
        //更新用户信息
        int count = userMapper.updateById(user);
        if(count <= 0){
            return JsonResult.error("用户授权订阅次数更新失败");
        }
        return JsonResult.success();
    }
}
