package com.ruoyi.dxp.service.impl;

import java.util.List;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.dxp.constant.DxpConstants;
import com.ruoyi.dxp.domain.UserCompany;
import com.ruoyi.dxp.dto.AuditDto;
import com.ruoyi.dxp.dto.NoticeSendDto;
import com.ruoyi.dxp.dto.UserCompanyDto;
import com.ruoyi.dxp.dto.customer.CompanyRegisterParam;
import com.ruoyi.dxp.mapper.UserCompanyMapper;
import com.ruoyi.dxp.service.INoticeService;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.dxp.mapper.UserApplyMapper;
import com.ruoyi.dxp.domain.UserApply;
import com.ruoyi.dxp.service.IUserApplyService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 企业用户申请Service业务层处理
 *
 * @author jy
 * @date 2022-12-05
 */
@Service
public class UserApplyServiceImpl implements IUserApplyService {
    @Autowired
    private UserApplyMapper userApplyMapper;

    @Autowired
    private UserCompanyMapper userCompanyMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private INoticeService noticeService;

    /**
     * 查询企业用户申请
     *
     * @param id 企业用户申请主键
     * @return 企业用户申请
     */
    @Override
    public UserApply selectUserApplyById(Long id) {
        return userApplyMapper.selectUserApplyById(id);
    }

    /**
     * 查询企业用户申请列表
     *
     * @param userApply 企业用户申请
     * @return 企业用户申请
     */
    @Override
    public List<UserApply> selectUserApplyList(UserApply userApply) {
        return userApplyMapper.selectUserApplyList(userApply);
    }

    /**
     * 新增企业用户申请
     *
     * @param userApply 企业用户申请
     * @return 结果
     */
    @Override
    public int insertUserApply(UserApply userApply) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        userApply.setCreateBy(loginUser.getUsername());
        userApply.setCreateTime(DateUtils.getNowDate());
        return userApplyMapper.insertUserApply(userApply);
    }

    /**
     * 修改企业用户申请
     *
     * @param userApply 企业用户申请
     * @return 结果
     */
    @Override
    public int updateUserApply(UserApply userApply) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        userApply.setUpdateBy(loginUser.getUsername());
        userApply.setUpdateTime(DateUtils.getNowDate());
        return userApplyMapper.updateUserApply(userApply);
    }

    /**
     * 批量删除企业用户申请
     *
     * @param ids 需要删除的企业用户申请主键
     * @return 结果
     */
    @Override
    public int deleteUserApplyByIds(Long[] ids) {
        return userApplyMapper.deleteUserApplyByIds(ids);
    }

    /**
     * 删除企业用户申请信息
     *
     * @param id 企业用户申请主键
     * @return 结果
     */
    @Override
    public int deleteUserApplyById(Long id) {
        return userApplyMapper.deleteUserApplyById(id);
    }

    /**
     * 注册
     *
     * @param apply 注册对象
     * @return 注册结果
     */
    @Override
    public AjaxResult register(CompanyRegisterParam apply) {
        // 验证码开关
        boolean captchaEnabled = configService.selectCaptchaEnabled();
        if (captchaEnabled)
        {
            validateCaptcha(apply.getUserName(), apply.getCode(), apply.getUuid());
        }

        if (StringUtils.isEmpty(apply.getCompanyName())) {
            return AjaxResult.error("请输入企业名称");
        }
        if (StringUtils.isEmpty(apply.getLinkMan())) {
            return AjaxResult.error("请输入企业联系人");
        }
        if (StringUtils.isEmpty(apply.getPhonenumber())) {
            return AjaxResult.error("请输入联系电话");
        }
        if (StringUtils.isEmpty(apply.getUnifiedCode())) {
            return AjaxResult.error("请输入统一社会信用码");
        }
        if (StringUtils.isEmpty(apply.getAddress())) {
            return AjaxResult.error("请输入地址");
        }
        if (StringUtils.isEmpty(apply.getApplyReason())) {
            return AjaxResult.error("请输入申请原因");
        }
        if (StringUtils.isEmpty(apply.getLicenseUrl())) {
            return AjaxResult.error("请上传营业执照");
        }

        if (StringUtils.isEmpty(apply.getUserName())) {
            return AjaxResult.error("请填写用户名");
        }

        // 申请是否重复
        UserApply uReq = new UserApply();
        uReq.setUserName(apply.getUserName());
        List<UserApply> userApplies = this.userApplyMapper.selectUserApplyList(uReq);
        if (userApplies != null && userApplies.size() > 0) {
            return AjaxResult.error("当前用户名已注册");
        }

        // 用户是否重复
        UserCompanyDto req = new UserCompanyDto();
        req.setUserName(apply.getUserName());
        List<UserCompanyDto> userCompanyDtos = userCompanyMapper.selectUserCompanyList(req);
        if (userCompanyDtos != null && userCompanyDtos.size() > 0) {
            return AjaxResult.error("当前用户名已注册");
        }

        if (StringUtils.isEmpty(apply.getPassword())) {
            return AjaxResult.error("请填写密码");
        }
//        LoginUser loginUser = SecurityUtils.getLoginUser();
        apply.setCreateBy(null);
        apply.setCreateTime(DateUtils.getNowDate());
        apply.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
        apply.setAuditBy(null);
        apply.setAuditTime(null);
        apply.setAuditRemark(null);
        apply.setRefuseReason(null);

        userApplyMapper.insertUserApply(apply);

        // 发送通知
        NoticeSendDto sendDto = new NoticeSendDto();
        sendDto.setNoticeType("companyRegister");
        noticeService.sendNotice(sendDto);

        return AjaxResult.success(apply.getId());
    }

    /**
     * 审核
     * @param auditDto 审核对象
     * @return 审核结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult audit(AuditDto auditDto) {
        UserApply userApply = userApplyMapper.selectUserApplyById(auditDto.getId());
        if (userApply == null || !userApply.getStatus().equals(DxpConstants.STATUS_WAIT_APPROVED)) {
            return AjaxResult.error("待审核用户不存在或非待审核状态");
        }

        if (auditDto.getStatus() == null) {
            return AjaxResult.error("审核状态错误");
        }

        if (!auditDto.getStatus().equals(DxpConstants.STATUS_VALID) && !auditDto.getStatus().equals(DxpConstants.STATUS_REJECT)) {
            return AjaxResult.error("审核状态错误");
        }

        if (StringUtils.isEmpty(auditDto.getAuditRemark())) {
            return AjaxResult.error("审核意见不能为空");
        }

        // 查询企业用户角色
        SysRole sysRole = new SysRole();
        sysRole.setRoleKey("company");
        List<SysRole> sysRoles = sysRoleService.selectRoleList(sysRole);
        if (sysRoles == null || sysRoles.size() == 0) {
            return AjaxResult.error("还未配置外部企业用户角色");
        }
        Long[] roleIds = new Long[1];
        roleIds[0] = sysRoles.get(0).getRoleId();
        LoginUser loginUser = SecurityUtils.getLoginUser();

        // 审核拒绝
        if (auditDto.getStatus().equals(DxpConstants.STATUS_REJECT)) {
            // 记录审核情况
            userApply.setStatus(auditDto.getStatus());
            userApply.setAuditBy(loginUser.getUsername());
            userApply.setAuditTime(DateUtils.getNowDate());
            userApply.setAuditRemark(auditDto.getAuditRemark());
            userApplyMapper.updateUserApply(userApply);
            return AjaxResult.success();
        } else {
            // 用户是否重复
            UserCompanyDto req = new UserCompanyDto();
            req.setUserName(userApply.getUserName());
            List<UserCompanyDto> userCompanyDtos = userCompanyMapper.selectUserCompanyList(req);
            if (userCompanyDtos != null && userCompanyDtos.size() > 0) {
                return AjaxResult.error("当前用户名已注册");
            }

            // 保存用户表及角色
            SysUser sysUser = new SysUser();
            sysUser.setRoleIds(roleIds);
            BeanUtils.copyProperties(userApply, sysUser);
            sysUser.setCreateBy(loginUser.getUsername());
            sysUser.setStatus(DxpConstants.STATUS_WAIT_APPROVED);
            sysUser.setCreateTime(DateUtils.getNowDate());
            sysUser.setRemark("企业注册");
            sysUser.setUserType(DxpConstants.USER_TYPE_COMPANY);
            sysUser.setNickName(userApply.getLinkMan());
            sysUser.setPassword(SecurityUtils.encryptPassword(sysUser.getPassword()));
            sysUserService.insertUser(sysUser);

            // 保存userCompany
            UserCompany userCompany = new UserCompany();
            BeanUtils.copyProperties(userApply, userCompany);
            userCompany.setUserId(sysUser.getUserId());
            userCompany.setCreateBy(loginUser.getUsername());
            userCompany.setCreateTime(DateUtils.getNowDate());
            userCompanyMapper.insertUserCompany(userCompany);

            // 记录审核情况
            userApply.setStatus(auditDto.getStatus());
            userApply.setAuditBy(loginUser.getUsername());
            userApply.setAuditTime(DateUtils.getNowDate());
            userApply.setAuditRemark(auditDto.getAuditRemark());
            userApplyMapper.updateUserApply(userApply);

            return AjaxResult.success(sysUser.getUserId());

        }
  }

    /**
     * 校验验证码
     *
     * @param username 用户名
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    private void validateCaptcha(String username, String code, String uuid)
    {
        String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        String captcha = redisCache.getCacheObject(verifyKey);
        redisCache.deleteObject(verifyKey);
        if (captcha == null)
        {
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha))
        {
            throw new CaptchaException();
        }
    }
}
