package com.hfkj.service.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.DateUtil;
import com.hfkj.common.utils.MD5Util;
import com.hfkj.common.utils.RandomUtils;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsMerMapper;
import com.hfkj.entity.BsMer;
import com.hfkj.entity.BsMerExample;
import com.hfkj.entity.SecRole;
import com.hfkj.entity.SecUser;
import com.hfkj.model.BsMerModel;
import com.hfkj.service.BsMerService;
import com.hfkj.service.SecRoleService;
import com.hfkj.service.SecUserService;
import com.hfkj.sysenum.MerStatusEnum;
import com.hfkj.sysenum.SecUserObjectTypeEnum;
import com.hfkj.sysenum.SecUserStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @className: BsMerServiceImpl
 * @author: HuRui
 * @date: 2024/4/24
 **/
@Service("merService")
public class BsMerServiceImpl implements BsMerService {
    @Autowired
    private RedisUtil redisUtil;
    private final static String CACHE_MER_KEY = "MER:";
    @Resource
    private BsMerMapper merMapper;
    @Resource
    private SecUserService secUserService;
    @Resource
    private SecRoleService secRoleService;

    /**
     * 生成商户号
     * @return
     */
    private static String generateMerNo() {
        // 166 + 时间 + 随机3位数
        return "166"+DateUtil.format(new Date(), "yyHHmm") + RandomUtils.number(3, false);
    }

    @Override
    public void editData(BsMer mer) {
        mer.setUpdateTime(new Date());
        if (mer.getId() == null) {
            mer.setCreateTime(new Date());
            merMapper.insert(mer);
            // 生成商户号
            mer.setMerNo(generateMerNo());
            if (getDetail(mer.getMerNo()) != null) {
                editData(mer);
            }
            merMapper.updateByPrimaryKey(mer);
        } else {
            merMapper.updateByPrimaryKey(mer);
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void create(BsMerModel mer) throws Exception {
        mer.setStatus(MerStatusEnum.status1.getCode());
        editData(mer);

        if (secUserService.getDetailByLoginName(mer.getLoginName()) != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "登录账户已存在，请更换");
        }

        SecUser secUser = new SecUser();
        secUser.setUserName(mer.getMerName());
        secUser.setLoginName(mer.getLoginName());
        secUser.setPassword(MD5Util.encode("123456".getBytes()));
        secUser.setTelephone(mer.getDirectorTel());
        secUser.setRoleId(mer.getRoleId());
        secUser.setObjectType(SecUserObjectTypeEnum.type2.getCode());
        secUser.setObjectId(mer.getId());
        secUser.setStatus(SecUserStatusEnum.status1.getCode());
        secUserService.editUser(secUser);

        // 查询角色
        SecRole secRole = secRoleService.getDetail(secUser.getRoleId());
        if (secRole != null) {
            mer.setRoleId(secRole.getId());
            mer.setRoleName(secRole.getRoleName());
        }
        // 加入缓存
        redisUtil.set(CACHE_MER_KEY+mer.getMerNo(), mer);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public void update(BsMerModel mer) throws Exception {
        editData(mer);

        // 查询账户
        SecUser secUser = secUserService.getDetail(SecUserObjectTypeEnum.type2, mer.getId());
        if (secUser == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户登录账户数据异常");
        }
        secUser.setUserName(mer.getMerName());
        secUser.setTelephone(mer.getDirectorTel());
        secUser.setRoleId(mer.getRoleId());
        secUserService.editUser(secUser);

        // 加入缓存
        redisUtil.set(CACHE_MER_KEY+mer.getMerNo(), mer);
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public String resetPwd(String merNo) throws Exception {
        // 查询商户
        BsMerModel mer = getDetail(merNo);
        if (mer == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的商户");
        }
        // 查询账户
        SecUser secUser = secUserService.getDetail(SecUserObjectTypeEnum.type2, mer.getId());
        if (secUser == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "商户登录账户数据异常");
        }
        String newPwd = "123456";
        secUser.setPassword(MD5Util.encode(newPwd.getBytes()));
        secUserService.editUser(secUser);
        return newPwd;
    }

    @Override
    public BsMerModel getDetail(String merNo) {
        Object cacheObj = redisUtil.get(CACHE_MER_KEY+merNo);
        if (cacheObj != null) {
            return (BsMerModel) cacheObj;
        }
        BsMerExample example = new BsMerExample();
        example.createCriteria().andMerNoEqualTo(merNo).andStatusNotEqualTo(MerStatusEnum.status0.getCode());
        List<BsMer> list = merMapper.selectByExample(example);
        if (!list.isEmpty()) {
            BsMerModel mer = new BsMerModel();
            BeanUtils.copyProperties(list.get(0), mer);;
            // 查询账户
            SecUser secUser = secUserService.getDetail(SecUserObjectTypeEnum.type2, mer.getId());
            if (secUser != null) {
                mer.setLoginName(secUser.getLoginName());
                // 角色
                SecRole secRole = secRoleService.getDetail(secUser.getRoleId());
                if (secRole != null) {
                    mer.setRoleId(secRole.getId());
                    mer.setRoleName(secRole.getRoleName());
                }
            }
            redisUtil.set(CACHE_MER_KEY+merNo, mer);
            return mer;
        }
        return null;
    }

    @Override
    public BsMer getDetailById(Long id) {
        return merMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<BsMer> getList(Map<String, Object> param) {
        BsMerExample example = new BsMerExample();
        BsMerExample.Criteria criteria = example.createCriteria()
                                        .andStatusNotEqualTo(MerStatusEnum.status0.getCode());

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merNo"))) {
            criteria.andMerNoLike("%"+MapUtils.getString(param, "merNo")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "merName"))) {
            criteria.andMerNameLike("%"+MapUtils.getString(param, "merName")+"%");
        }

        if (StringUtils.isNotBlank(MapUtils.getString(param, "opUserName"))) {
            criteria.andOpUserNameLike("%"+MapUtils.getString(param, "opUserName")+"%");
        }

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        example.setOrderByClause("create_time desc");
        return merMapper.selectByExample(example);
    }


}
