package com.hfkj.service.agent.impl;

import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.utils.MD5Util;
import com.hfkj.common.utils.RedisUtil;
import com.hfkj.dao.BsAgentMapper;
import com.hfkj.entity.*;
import com.hfkj.service.agent.BsAgentApiAccountService;
import com.hfkj.service.agent.BsAgentApiParamService;
import com.hfkj.service.agent.BsAgentService;
import com.hfkj.service.sec.SecUserService;
import com.hfkj.sysenum.SecUserObjectTypeEnum;
import com.hfkj.sysenum.agent.AgentStaffStatusEnum;
import com.hfkj.sysenum.agent.AgentStatusEnum;
import com.hfkj.sysenum.agent.AgentTypeEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @className: BsAgentServiceImpl
 * @author: HuRui
 * @date: 2024/2/28
 **/
@Service("agentService")
public class BsAgentServiceImpl implements BsAgentService {

    @Resource
    private BsAgentMapper agentMapper;

    @Resource
    private SecUserService secUserService;

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private BsAgentApiParamService agentApiParamService;
    @Resource
    private BsAgentApiAccountService agentApiAccountService;
    // 缓存前缀
    private final static String CACHE_AGENT = "AGENT:";

    @Override
    public BsAgent editData(BsAgent data) {
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            data.setUpdateTime(new Date());
            data.setStatus(1);
            agentMapper.insert(data);

            data.setAgentNo("A"+data.getId());
            agentMapper.updateByPrimaryKey(data);
        } else {
            data.setUpdateTime(new Date());
            agentMapper.updateByPrimaryKey(data);
        }
        return data;
    }


    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor= {RuntimeException.class})
    public BsAgent createAgent(String loginName, BsAgent agent) throws Exception {
        editData(agent);

        SecUser secUser = new SecUser();
        if (AgentTypeEnum.type1.getCode().equals(agent.getType())) {
            secUser.setRoleId(5L);
        } else if (AgentTypeEnum.type2.getCode().equals(agent.getType())) {
            secUser.setRoleId(8L);
            // 创建代理余额账户
            agentApiAccountService.create(agent.getId());
            // 生成代理api接入参数
            agentApiParamService.create(agent.getId());

        }else if (AgentTypeEnum.type3.getCode().equals(agent.getType())) {
            secUser.setRoleId(9L);
            // 生成代理api接入参数
            agentApiParamService.create(agent.getId());
        } else {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的代理类型");
        }
        secUser.setUserName(agent.getName());
        secUser.setLoginName(loginName);
        secUser.setPassword(MD5Util.encode("123654".getBytes()));
        secUser.setObjectType(SecUserObjectTypeEnum.type4.getCode());
        secUser.setObjectId(agent.getId());
        secUser.setStatus(1);
        secUser.setCreateTime(new Date());
        secUser.setUpdateTime(new Date());
        secUserService.editUser(secUser);
        return agent;
    }

    @Override
    public BsAgent updateAgent(BsAgent agent) {
        editData(agent);

        redisUtil.set(CACHE_AGENT + agent.getAgentNo(), agent);
        return agent;
    }

    @Override
    public void disable(String agentNo) {
        // 代理商
        BsAgent agent = getAgentByAgentNo(agentNo);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到代理商");
        }
        agent.setStatus(AgentStatusEnum.status2.getCode());
        updateAgent(agent);

        // 代理商账户
        if (agent.getType().equals(AgentTypeEnum.type2.getCode())) {
            BsAgentApiAccount account = agentApiAccountService.getAccount(agent.getId());
            if (account != null) {
                account.setStatus(AgentStatusEnum.status2.getCode());
                agentApiAccountService.update(account);
            }
        }

    }

    @Override
    public void enable(String agentNo) {
        // 代理商
        BsAgent agent = getAgentByAgentNo(agentNo);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到代理商");
        }
        agent.setStatus(AgentStatusEnum.status1.getCode());
        updateAgent(agent);

        // 代理商账户
        if (agent.getType().equals(AgentTypeEnum.type2.getCode())) {
            BsAgentApiAccount account = agentApiAccountService.getAccount(agent.getId());
            if (account != null) {
                account.setStatus(AgentStatusEnum.status1.getCode());
                agentApiAccountService.update(account);
            }
        }
    }

    @Override
    public BsAgent getAgentById(Long id) {
        return agentMapper.selectByPrimaryKey(id);
    }

    @Override
    public BsAgent getAgentByAgentNo(String agentNo) {
        Object obj = redisUtil.get(CACHE_AGENT + agentNo);
        if (obj != null) {
            return (BsAgent) obj;
        }
        BsAgentExample example = new BsAgentExample();
        example.createCriteria().andAgentNoEqualTo(agentNo).andStatusNotEqualTo(0);
        List<BsAgent> list = agentMapper.selectByExample(example);
        if (!list.isEmpty()) {
            BsAgent agent = list.get(0);
            redisUtil.set(CACHE_AGENT + agentNo, agent);
            return agent;
        }
        return null;
    }

    @Override
    public List<BsAgent> getAgentList(Map<String, Object> param) {
        BsAgentExample example = new BsAgentExample();
        BsAgentExample.Criteria criteria = example.createCriteria().andStatusNotEqualTo(0);

        if (StringUtils.isNotBlank(MapUtils.getString(param, "type"))) {
            List<Integer> type = Arrays.stream(MapUtils.getString(param, "type").split(","))
                    .flatMapToInt(num -> IntStream.of(Integer.parseInt(num))).boxed()
                    .collect(Collectors.toList());
            criteria.andTypeIn(type);
        }

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

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

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

}
