package cn.pluss.platform.agent.impl;

import cn.pluss.platform.agent.AgentService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.AgentMapper;
import cn.pluss.platform.mapper.MerchantRateMapper;
import cn.pluss.platform.user.UserLevelService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userInfo.UserInfoService;
import cn.pluss.platform.util.MD5Util;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.vo.AgentInfo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author DJH
 */
@Service
@Slf4j
public class AgentServiceImpl implements AgentService {

    private static final String NOT_ALL_NUM = "^[0-9]*$";

    /**
     * \u3000是全角空格
     */
    private static final String NO_SPECIAL_CHAR = "[ \u3000`~!@#$%^&*()+=|{}':;,\\[\\].<>/?！￥…（）—【】‘；：”“’。，、？]";

    private final Pattern compile = Pattern.compile(NOT_ALL_NUM);

    private final Pattern compile2 = Pattern.compile(NO_SPECIAL_CHAR);

    @Setter(onMethod_ = {@Autowired})
    private AgentMapper agentMapper;
    @Setter(onMethod_ = {@Autowired})
    private UserAppService userAppService;
    @Setter(onMethod_ = {@Autowired})
    private UserInfoService userInfoService;
    @Setter(onMethod_ = {@Autowired})
    private MerchantRateMapper rateMapper;

    @Autowired
    private UserLevelService ulService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(AgentInfo agentInfo) {
        UserApp userApp = userAppService.queryUserAppByToken();
        if (!userApp.getUserId().equals(agentInfo.getParentId())) {
            throw new MsgException("拒绝访问");
        }

        Matcher matcher = compile.matcher(agentInfo.getLoginName());
        if (matcher.matches()) {
            throw new MsgException("账号不能使用纯数字");
        }

        Matcher matcher2 = compile2.matcher(agentInfo.getLoginName());
        if (matcher2.find()) {
            throw new MsgException("账号不能使用包含特殊符号");
        }

        MsgException.throwException("代理账户和普通账户即将合并，暂无法开通代理商，请使用推广海报拓展团队");

        saveAgentInfo(agentInfo);
    }

    @Override
    public Page<AgentInfo> page(Page<AgentInfo> page, AgentInfo agentInfo, OrderItem orderItem) {
        if (agentInfo.getParentId() == null) {
            throw new MsgException("缺少parentId");
        }

        UserApp userApp = userAppService.queryUserAppByToken();
        if (!userApp.getUserId().equals(agentInfo.getParentId())) {
            throw new MsgException("拒绝访问");
        }

        page.getOrders().clear();
        if (orderItem != null && StringUtils.isNotBlank(orderItem.getColumn())) {
            page.addOrder(orderItem);
        }

        if (page.getOrders().isEmpty()) {
            page.addOrder(OrderItem.desc("createTime"));
        }

        return agentMapper.selectPage(page, agentInfo);
    }

    @Override
    public Integer getMinSettingRate() {
        UserApp userApp = userAppService.queryUserAppByToken();

        // if (!"agent".equals(userApp.getUserType())) {
        //     throw new MsgException("拒绝访问");
        // }

        MerchantRate userRate = new MerchantRate().setUserId(userApp.getUserId() + "");
        userRate = rateMapper.selectOne(new QueryWrapper<>(userRate));

        int min = 0;
        // 非固定费率的服务商，下级服务商费率必须大于25
        if (!"1".equals(userApp.getIsFixedRate())) {
            min = 25;
        }

        return Math.max(userRate.getCurrentRate(), min);
    }

    @Override
    public MerchantRateNew getMinSettingRateNew() {
        UserApp userApp = userAppService.queryUserAppByToken();

        UserLevel entity = ulService.getLevelInfoByRoleLevel(userApp.getRoleCode(), userApp.getLevelCode());

        MerchantRateNew rateNew = new MerchantRateNew();
        rateNew.setWxRate(entity.getRate().intValue() + 1);
        rateNew.setAliRate(entity.getRate().intValue() + 1);
        rateNew.setBankRate(entity.getRate().intValue() + 1);
        rateNew.setBankRateLarge(entity.getRate().intValue() + 1);

        MerchantRateNew.setRateValue(rateNew);

        return rateNew;
    }

    private void saveAgentInfo(AgentInfo agentInfo) {
        AgentInfo exist = new AgentInfo().setLoginName(agentInfo.getLoginName());
        exist = agentMapper.selectOne(exist);
        MsgException.check(exist != null, "该账号已存在");

        exist = new AgentInfo().setPhone(agentInfo.getPhone());
        exist = agentMapper.selectOne(exist);
        MsgException.check(exist != null, "该手机号已存在关联代理商");

        Date date = new Date();
        UserInfo userInfo = new UserInfo()
                .setPassword(MD5Util.MD5Encode(agentInfo.getPassword(), "UTF-8"))
                .setLoginName(agentInfo.getLoginName())
                .setPhone(agentInfo.getPhone())
                .setUpdateTime(date)
                .setCreateTime(date);
        userInfoService.saveUserInfo(userInfo);
        MsgException.check(userInfo.getId() == null, "插入数据失败");

        UserApp userApp = userAppService.queryUserAppByToken();
        if (!(userApp.getStatus() == 3) || !(userApp.getBankStatus() == 3)) {
            throw new MsgException("当前服务商账号暂未实名，无法添加下级代理");
        }

        MerchantRate userRate = new MerchantRate().setUserId(userApp.getUserId() + "");
        userRate = rateMapper.selectOne(new QueryWrapper<>(userRate));

        log.info("自身费率: {}", userRate.getRate());
        log.info("设置下级费率: {}", agentInfo.getRate().intValue());

        // 非固定费率的服务商，下级服务商费率必须大于25
        if (!"1".equals(userApp.getIsFixedRate()) && agentInfo.getRate().intValue() <= MerchantRate.MAX_RATE) {
            throw new MsgException("下级代理商费率必须大于" + MerchantRate.MAX_RATE);
        }

        if (userRate.getRate() >= agentInfo.getRate().intValue()) {
            throw new MsgException("下级代理商费率必须大于自身费率");
        }

        agentInfo.setUserId(userInfo.getId());

        String pIdArr = userApp.getUserId() + "";
        if (StringUtils.isNotBlank(userApp.getPIdArr())) {
            pIdArr += "," + userApp.getPIdArr();
        }

        UserApp subUserApp = new UserApp();
        subUserApp.setUserType("agent")
                .setUserId(userInfo.getId())
                .setLoginName(agentInfo.getPhone())
                .setInviteNum(getRandomNum())
                .setParentId(userApp.getUserId())
                .setLevel(3)
                // 默认身份认证状态
                .setStatus(0)
                .setIsFixedRate("1")
                .setCreateDt(date)
                .setPIdArr(pIdArr);

        UserApp.setSort(userApp, subUserApp);
        UserApp.setRoleInfo(userApp, subUserApp,null);

        userAppService.save(subUserApp);

        MerchantRate merchantRate = new MerchantRate()
                .setUserId(userInfo.getId() + "")
                .setRate(agentInfo.getRate().intValue())
                .setPreviousRate(agentInfo.getRate().intValue())
                .setUpdateTime(new Date());
        rateMapper.insert(merchantRate);
    }

    private String getRandomNum() {
        String inviteNum;
        UserApp condition = new UserApp();

        do {
            inviteNum = StringUtil.genRandomNum(5);
            condition.setInviteNum(inviteNum);
            UserApp userApp = userAppService.queryUserApp(condition);
            if (userApp == null) {
                return inviteNum;
            }
        } while (true);
    }
}
