package cn.pluss.platform.common.impl;

import cn.pluss.platform.common.RiskBlacklistService;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.dto.RiskBlacklistDTO;
import cn.pluss.platform.entitiy.ShiroUser;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.RiskBlacklistMapper;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantStore.MerchantStoreService;
import cn.pluss.platform.operationRecord.OperationRecordService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.userInfo.UserInfoService;
import cn.pluss.platform.vo.RiskBlacklistVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 风控黑名单表 服务实现类
 * </p>
 *
 * @author Djh
 * @since 2021-09-07
 */
@Slf4j
@Service
public class RiskBlacklistServiceImpl extends ServiceImpl<RiskBlacklistMapper, RiskBlacklist> implements RiskBlacklistService {

    @Autowired
    private AccountService accountService;

    @Autowired
    private UserAppService uaService;

    @Autowired
    private UserInfoService uiService;

    @Lazy
    @Autowired
    private RiskBlacklistService self;

    @Autowired
    private MerchantBaseInfoService mbiService;

    @Autowired
    private OperationRecordService opRecordService;

    @Autowired
    private MerchantStoreService msService;

    @Override
    public void addData(RiskBlacklistDTO riskBlacklistDTO) {
        riskBlacklistDTO.setCauseUserId(riskBlacklistDTO.getUserId());
        if (riskBlacklistDTO.getUserId() == null) {
            throw new MsgException("缺少用户id");
        }

        if (riskBlacklistDTO.getPayWay() == null) {
            throw new MsgException("缺少付款方式");
        }

        if (riskBlacklistDTO.getChannel() == null) {
            throw new MsgException("缺少进件渠道");
        }

        if ("1".equals(riskBlacklistDTO.getConnectFlag() + "")) {
            List<MerchantBaseInfo> mbiList = mbiService.getAllByUserId(riskBlacklistDTO.getUserId() + "");

            for (MerchantBaseInfo mbi : mbiList) {
                riskBlacklistDTO.setUserId(Integer.parseInt(mbi.getUserId()));
                riskBlacklistDTO.setMerchantCode(mbi.getMerchantCode());

                try {
                    self.closeMerch(riskBlacklistDTO);
                } catch (Exception e) {
                    log.warn("关闭商户【{}】交易权限失败, 错误信息：{}", riskBlacklistDTO.getUserId(), e.getMessage());
                }
            }
        } else {
            MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(riskBlacklistDTO.getUserId() + "");
            riskBlacklistDTO.setUserId(Integer.parseInt(mbi.getUserId()));
            riskBlacklistDTO.setMerchantCode(mbi.getMerchantCode());
            try {
                self.closeMerch(riskBlacklistDTO);
            } catch (Exception e) {
                log.warn("关闭商户【{}】交易权限失败", riskBlacklistDTO.getUserId());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void closeMerch(RiskBlacklistDTO riskBlacklistDTO) {

//        MerchantChannelStatus mcs = channelStatusMapper.getByMerchantCode(riskBlacklistDTO.getMerchantCode(), riskBlacklistDTO.getChannel());
//
//        if (mcs == null || !MerchantChannelStatus.AUDIT_STATUS_SUCCESS.equals(mcs.getStatus())) {
//            throw new MsgException("所选商户所选通道下未进件");
//        }

        AccountDTO accountDTO = accountService.getRealAccount(riskBlacklistDTO.getUserId() + "");
        if (accountDTO == null || accountDTO.getIdcard() == null) {
            throw new MsgException("未查询到结算身份信息");
        }
        riskBlacklistDTO.setCertName(accountDTO.getIdcard().getCertName());
        riskBlacklistDTO.setIdcardNo(accountDTO.getIdcard().getCertNo());

        LambdaQueryWrapper<RiskBlacklist> qWrapperRiskBlacklist = Wrappers.lambdaQuery();
        qWrapperRiskBlacklist.eq(RiskBlacklist::getCertName, riskBlacklistDTO.getCertName())
                .eq(RiskBlacklist::getIdcardNo, riskBlacklistDTO.getIdcardNo())
                .last("limit 1");
        RiskBlacklist existData = getOne(qWrapperRiskBlacklist);
        if (existData != null) {
            return;
        }

        // 只包含userId和merchantCode
        List<MerchantBaseInfo> mbiList = accountService.getMbiListCertNo(riskBlacklistDTO.getIdcardNo());

        // 要插入的数据
        List<RiskBlacklist> addList = new ArrayList<>();
        // 要关闭交易权限的商编列表
        List<String> merchCodeList = new ArrayList<>();
        // 关闭交易权限的备注信息
        List<OperationRecord> opRecordList = new ArrayList<>();

        for (MerchantBaseInfo mbi : mbiList) {
            RiskBlacklist entity = new RiskBlacklist();
            entity.setChannel(riskBlacklistDTO.getChannel());
            entity.setRemark(riskBlacklistDTO.getRemark());
            entity.setUserId(Integer.parseInt(mbi.getUserId()));
            entity.setIdcardNo(riskBlacklistDTO.getIdcardNo());
            entity.setCertName(riskBlacklistDTO.getCertName());
            entity.setPayWay(riskBlacklistDTO.getPayWay());
            entity.setCauseUserId(riskBlacklistDTO.getCauseUserId());

            OperationRecord opRecord = new OperationRecord();
            opRecord.setUserId(mbi.getUserId());
            opRecord.setRemark(riskBlacklistDTO.getRemark());
            opRecord.setDictValue("GBSHJYGN");
            opRecordList.add(opRecord);

            addList.add(entity);
            merchCodeList.add(mbi.getMerchantCode());
        }

        LambdaUpdateWrapper<MerchantStore> uWrapper = Wrappers.lambdaUpdate();
        uWrapper.set(MerchantStore::getStatus, "2")
                .in(MerchantStore::getMerchantCode, merchCodeList);
        // 保存黑名单信息
        saveBatch(addList);
        // 变更店铺状态
        riskBlacklistDTO.setCount(riskBlacklistDTO.getCount() + (addList.size()));
        msService.update(uWrapper);
        // 保存商户拉黑的备注
        opRecordService.saveBatch(opRecordList);

        // 修改后台可操控的推广权限字段, 关闭推广权限
        UserInfo ui = uiService.getById(riskBlacklistDTO.getUserId());
        ui.setStatus(UserInfo.STATUS_NO_SPREAD);
        uiService.updateById(ui);

        LambdaUpdateWrapper<UserInfo> uWrapper3 = Wrappers.lambdaUpdate();
        uWrapper3.set(UserInfo::getStatus, UserInfo.STATUS_NO_SPREAD)
                .eq(UserInfo::getId, riskBlacklistDTO.getUserId());
        uiService.update(uWrapper3);
    }

    @Override
    public Page<RiskBlacklistVO> page(Page<RiskBlacklistVO> page, Map<String, Object> condition) {
        return getBaseMapper().selectPageVO(page, condition);
    }

    @Override
    public void batchAddData(RiskBlacklistDTO riskBlacklistDTO) {
        if (riskBlacklistDTO.getUserIdArr().isEmpty()) {
            throw new MsgException("缺少id信息");
        }

        for (String userId : riskBlacklistDTO.getUserIdArr()) {
            riskBlacklistDTO.setUserId(Integer.parseInt(userId));
            addData(riskBlacklistDTO);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void relieve(Long opUserId, Long userId) {
        RiskBlacklist exist = new RiskBlacklist();
        exist.setUserId(userId.intValue());

        exist = getOne(new QueryWrapper<>(exist));

        if (exist == null) {
            return;
        }

        // 先移除黑名单的数据
        removeById(exist.getId());
        // 如果是商户，则把商户禁用解除
        msService.enableMerchantStore(opUserId, userId, "解除拉黑");
        // 修改后台可操控的推广权限字段, 打开推广权限
        UserInfo ui = uiService.getById(userId);
        ui.setStatus(UserInfo.STATUS_VALID);
        uiService.updateById(ui);
    }
}
