package com.css.simulation.resource.server.app.service;

import api.common.pojo.constants.DictConstants;
import api.common.pojo.constants.LogConstants;
import api.common.pojo.dto.SmsDTO;
import api.common.pojo.param.system.UserParam;
import api.common.pojo.po.system.UserPO;
import api.common.pojo.vo.system.ParameterVO;
import api.common.pojo.vo.system.UserVO;
import api.common.util.EncryptUtil;
import api.common.util.JsonUtil;
import api.common.util.ObjectUtil;
import api.common.util.StringUtil;
import com.css.simulation.resource.server.infra.oauth.OauthParameter;
import com.css.simulation.resource.server.infra.util.AuthUtil;
import com.css.simulation.resource.server.infra.util.PageUtil;
import com.css.simulation.resource.server.infra.util.PoUtil;
import com.css.simulation.resource.server.infra.sms.SmsConfiguration;
import com.css.simulation.resource.server.infra.db.mysql.mapper.SystemUserMapper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;


@Service
public class UserService {

    @Resource
    SystemUserMapper systemUserMapper;
    @Resource
    OauthParameter oauthParameter;
    @Resource
    LogService logService;
    @Resource
    DictService dictService;
    @Resource
    ParameterService parameterService;
    @Resource
    SmsConfiguration smsConfiguration;
    @Resource
    KafkaTemplate<String, String> kafkaTemplate;

    public UserVO getCurrentUserInfo() {
        String userId = AuthUtil.getCurrentUserId();
        UserVO userVO = systemUserMapper.getUserInfo(userId);
        //字典翻译
        Map<String, Map<String, String>> dictMaps = dictService.getDictMapsByTypes(DictConstants.USE_TYPE + "," + DictConstants.ROLE_CODE);
        userVO.setUseTypeName(dictMaps.get(DictConstants.USE_TYPE).get(userVO.getUseType()));
        userVO.setRoleCodeName(dictMaps.get(DictConstants.ROLE_CODE).get(userVO.getRoleCode()));
        return userVO;
    }

    public PageInfo<UserVO> getUserPageList(UserParam pageParam) {
        PageUtil.setPageInfo(pageParam);
        List<UserVO> list;
        String currentUserRoleCode = AuthUtil.getCurrentUserRoleCode();
        if (DictConstants.ROLE_CODE_SYSADMIN.equals(currentUserRoleCode)) {//超级管理员
            list = systemUserMapper.getUserPageLista(pageParam);
        } else if (DictConstants.ROLE_CODE_ADMIN.equals(currentUserRoleCode)) {//子管理员
            list = systemUserMapper.getUserPageListb(pageParam);
        } else if (DictConstants.ROLE_CODE_UESR.equals(currentUserRoleCode)) {//普通用户
            //只查询自己创建的子账户
            pageParam.setCreateUserId(AuthUtil.getCurrentUserId());
            list = systemUserMapper.getUserPageListc(pageParam);
        } else {
            return null;
        }
        //字典翻译
        Map<String, Map<String, String>> dictMaps = dictService.getDictMapsByTypes(DictConstants.ROLE_CODE);
        list.forEach(po -> {
            po.setRoleCode(dictMaps.get(DictConstants.ROLE_CODE).get(po.getRoleCode()));
        });
        return new PageInfo<>(list);
    }

    @SneakyThrows
    public UserPO saveUser(UserPO userPO) {
        //权限校验
        String currentUserRoleCode = AuthUtil.getCurrentUserRoleCode();
        if (DictConstants.ROLE_CODE_SYSADMIN.equals(currentUserRoleCode)) {// 超级管理员
            if (DictConstants.ROLE_CODE_ADMIN.equals(userPO.getRoleCode())) {
                userPO.setRoleCode(DictConstants.ROLE_CODE_ADMIN);
            } else {
                userPO.setRoleCode(DictConstants.ROLE_CODE_UESR);
            }
        } else if (DictConstants.ROLE_CODE_ADMIN.equals(currentUserRoleCode)) {// 子管理员
            userPO.setRoleCode(DictConstants.ROLE_CODE_UESR);
        } else if (DictConstants.ROLE_CODE_UESR.equals(currentUserRoleCode)) { //普通用户
            //新增参数校验
            if (ObjectUtil.isNull(userPO.getId())) {
                ParameterVO parameter = parameterService.getParameterByUserId();
                if (ObjectUtil.isNull(parameter)) {
                    return null;
                }
                int num = parameter.getNumCreateUser(); // 最大用户数
                int subUserNum = 0;
                String userId = AuthUtil.getCurrentUserId();
                List<UserPO> subUsers = systemUserMapper.getSubUser(userId);
                if (ObjectUtil.isNotNull(subUsers)) {
                    subUserNum = subUsers.size();
                }
                if (subUserNum >= num) {
                    userPO.setId("subUserNum");
                    return userPO;
                }
            }
            userPO.setRoleCode(DictConstants.ROLE_CODE_SUBUESR);
            // 普通用户创建子账户时，占用类型继承
            userPO.setUseType(AuthUtil.getCurrentUseType());
        } else {
            return null;
        }
        //重名校验
        List<UserPO> list = systemUserMapper.checkUsername(userPO);
        if (ObjectUtil.isNotNull(list)) {
            userPO.setId("checkUsername");
            return userPO;
        }
        PoUtil.initAddPo(userPO);
        String id = userPO.getId();
        if (ObjectUtil.isNull(id)) {//新增
            userPO.setId(StringUtil.getRandomUUID());
            // 初始密码
            userPO.setPassword(EncryptUtil.getLowerMD5(oauthParameter.getSimulationDefaultPassword()));
            userPO.setVisible("1");
            systemUserMapper.insert(userPO);
            logService.logUser(LogConstants.SYS_LOG_USER_INSERT, userPO);


            kafkaTemplate.send(smsConfiguration.getKafkaTopic(),
                    JsonUtil.beanToJson(SmsDTO.builder()
                            .secretId(smsConfiguration.getSecretId())
                            .secretKey(smsConfiguration.getSecretKey())
                            .sdkAppId(smsConfiguration.getSdkAppId())
                            .signName(smsConfiguration.getSignName())
                            .templateId(smsConfiguration.getTemplateIdForCreate())
                            .phone(userPO.getPhone())
                            .build())
            );

        } else {
            systemUserMapper.update(userPO);
            logService.logUser(LogConstants.SYS_LOG_USER_UPDATE, userPO);
        }
        // 密码清空
        userPO.setPassword(null);
        return userPO;
    }

    @SneakyThrows
    public void saveDefaultPassword(UserPO userPO) {
        userPO.setPassword(EncryptUtil.getLowerMD5(oauthParameter.getSimulationDefaultPassword()));
        PoUtil.initUpdatePo(userPO);
        systemUserMapper.saveDefaultPassword(userPO);
        logService.logUser(LogConstants.SYS_LOG_USER_RESET, userPO);

        // 发送短信
        kafkaTemplate.send(smsConfiguration.getKafkaTopic(),
                JsonUtil.beanToJson(SmsDTO.builder()
                        .secretId(smsConfiguration.getSecretId())
                        .secretKey(smsConfiguration.getSecretKey())
                        .sdkAppId(smsConfiguration.getSdkAppId())
                        .signName(smsConfiguration.getSignName())
                        .templateId(smsConfiguration.getTemplateIdForReset())
                        .phone(userPO.getPhone())
                        .build())
        );
    }

    public void saveVisible(UserPO userPO) {
        PoUtil.initUpdatePo(userPO);
        systemUserMapper.saveVisible(userPO);
        if ("1".equals(userPO.getVisible())) {
            logService.logUser(LogConstants.SYS_LOG_USER_START, userPO);
        } else { // 停用
            UserVO userInfo = systemUserMapper.getUserInfo(userPO.getId());
            String roleCode = userInfo.getRoleCode();
            if (DictConstants.ROLE_CODE_UESR.equals(roleCode)) {  // 停用普通用户时-停用子账户
                List<UserPO> subUsers = systemUserMapper.getSubUser(userPO.getId());
                if (ObjectUtil.isNotNull(subUsers)) {
                    subUsers.forEach(po -> {
                        PoUtil.initUpdatePo(po);
                        po.setVisible("0");
                        systemUserMapper.saveVisible(po);
                    });
                }
            }
            //只记录普通账户日志
            logService.logUser(LogConstants.SYS_LOG_USER_STOP, userPO);
        }

    }

    public void savePhone(UserPO userPO) {
        PoUtil.initUpdatePo(userPO);
        systemUserMapper.savePhone(userPO);
    }

    public UserPO savePassword(UserVO userVO) throws NoSuchAlgorithmException {
        //确认原密码是否正确
        userVO.setPassword(EncryptUtil.getLowerMD5(userVO.getPassword()));
        List<UserVO> list = systemUserMapper.checkPassword(userVO);
        if (ObjectUtil.isNull(list)) {
            return null;
        }
        //修改密码
        UserPO userPO = new UserPO();
        userPO.setId(userVO.getId());
        userPO.setPassword(EncryptUtil.getLowerMD5(userVO.getNewPassword()));
        PoUtil.initUpdatePo(userPO);
        systemUserMapper.savePassword(userPO);
        return userPO;
    }
}
