package com.hfkj.service.agent.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.Api;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.common.pay.util.SignatureUtil;
import com.hfkj.common.utils.HttpUtils;
import com.hfkj.common.utils.HttpsUtils;
import com.hfkj.dao.BsAgentMerMapper;
import com.hfkj.entity.*;
import com.hfkj.model.AgentMerAllot;
import com.hfkj.openapi.model.response.ResponseQueryGasInfoModel;
import com.hfkj.openapi.service.ApiGasService;
import com.hfkj.service.agent.*;
import com.hfkj.service.gas.BsGasOrderService;
import com.hfkj.service.gas.BsGasService;
import com.hfkj.service.merchant.BsMerchantService;
import com.hfkj.sysenum.agent.AgentTypeEnum;
import com.hfkj.sysenum.merchant.MerchantSourceTypeEnum;
import com.hfkj.sysenum.merchant.MerchantStatusEnum;
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.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

/**
 * @className: BsAgentMerServiceImpl
 * @author: HuRui
 * @date: 2024/6/15
 **/
@Service("agentMerService")
public class BsAgentMerServiceImpl implements BsAgentMerService {
    @Resource
    private BsAgentMerMapper agentMerMapper;
    @Resource
    private BsAgentService agentService;
    @Resource
    private BsAgentMerService agentMerService;
    @Resource
    private BsAgentStaffService agentStaffService;
    @Resource
    private BsMerchantService merchantService;
    @Resource
    private BsAgentMerAccountService agentMerAccountService;
    @Resource
    private BsAgentApiParamService agentApiParamService;
    @Resource
    private ApiGasService apiGasService;

    @Override
    public void editData(BsAgentMer data) {
        data.setUpdateTime(new Date());
        if (data.getId() == null) {
            data.setCreateTime(new Date());
            agentMerMapper.insert(data);
        } else {
            agentMerMapper.updateByPrimaryKey(data);
        }
    }

    @Override
    public void addData(List<BsAgentMer> dataList) {
        if (!dataList.isEmpty()) {
            agentMerMapper.addPatch(dataList);
        }
    }

    @Override
    public void assignAgent(Long agentId, List<String> merNoArray) {
        // 代理商
        BsAgent agent = agentService.getAgentById(agentId);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的代理商");
        }
        // 查询代理商的油站
        Map<String,Object> param = new HashMap<>();
        param.put("agentId", agent.getId());
        List<BsAgentMer> agentMerList = getList(param);

        List<BsAgentMer> dataList = new ArrayList<>();
        BsAgentMer agentMer;
        for (String merNo : merNoArray) {
            // 查询门店
            BsMerchant merchant = merchantService.getMerchant(merNo);
            if (merchant == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的加油站");
            }
            List<BsAgentMer> collect = agentMerList.stream().filter(o -> o.getMerNo().equals(merNo)).collect(Collectors.toList());
            if (collect.isEmpty()) {
                agentMer = new BsAgentMer();
                agentMer.setAgentId(agent.getId());
                agentMer.setAgentName(agent.getName());
                agentMer.setAgentName(agent.getName());
                agentMer.setMerSourceType(merchant.getSourceType());
                agentMer.setProvinceCode(merchant.getProvinceCode());
                agentMer.setProvinceName(merchant.getProvinceName());
                agentMer.setMerId(merchant.getId());
                agentMer.setMerNo(merchant.getMerNo());
                agentMer.setMerName(merchant.getMerName());
                agentMer.setStatus(1);
                agentMer.setCreateTime(new Date());
                agentMer.setUpdateTime(new Date());
                dataList.add(agentMer);

                if (agent.getType().equals(AgentTypeEnum.type1.getCode()) && merchant.getSourceType().equals(MerchantSourceTypeEnum.type1.getNumber())) {
                    BsAgentMerAccount account = new BsAgentMerAccount();
                    account.setAgentId(agentId);
                    account.setMerId(merchant.getId());
                    account.setMerNo(merchant.getMerNo());
                    account.setAmount(new BigDecimal("0"));
                    account.setAmountConsume(new BigDecimal("0"));
                    account.setStatus(1);
                    agentMerAccountService.editData(account);

                }
            }
        }

        agentMerService.addData(dataList);

        // 通知代理商
        if (agent.getType().equals(AgentTypeEnum.type2.getCode())) {
            // 代理参数
            BsAgentApiParam apiParam = agentApiParamService.getParam(agentId);
            if (apiParam != null && StringUtils.isNotBlank(apiParam.getMerInfoNotify())) {
                for (BsAgentMer data : dataList) {
                    // 通知代理
                    agentMerService.agentNotify(apiParam.getAgentId(), data.getMerNo());
                }
            }
        }
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void unbindAgent(Long agentId, List<String> merNoArray) {
        // 代理商
        BsAgent agent = agentService.getAgentById(agentId);
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的代理商");
        }
        // 删除代理商商户
        BsAgentMer agentMer = new BsAgentMer();
        agentMer.setStatus(0);
        BsAgentMerExample example = new BsAgentMerExample();
        example.createCriteria().andAgentIdEqualTo(agentId).andMerNoIn(merNoArray).andStatusNotEqualTo(0);
        agentMerMapper.updateByExampleSelective(agentMer, example);

        // 删除代理商下的工作人员商户
        List<Long> staffIdList = agentStaffService.getStaffList(agentId)
                .stream()
                .flatMapToLong(num -> LongStream.of(num.getId())).boxed()
                .collect(Collectors.toList());
        example.clear();

        BsAgentMerExample.Criteria criteria = example.createCriteria().andMerNoIn(merNoArray).andStatusNotEqualTo(0);
        if (!staffIdList.isEmpty()) {
            criteria.andAgentStaffIdIn(staffIdList);
        }
        agentMerMapper.updateByExampleSelective(agentMer, example);

        for (String merNo : merNoArray) {
            // 查询门店
            BsMerchant merchant = merchantService.getMerchant(merNo);
            if (merchant != null && AgentTypeEnum.type1.getCode().equals(agent.getType()) && MerchantSourceTypeEnum.type1.getNumber().equals(merchant.getSourceType())) {
                // 删除代理商下的商户账户
                BsAgentMerAccount account = agentMerAccountService.getAccount(agentId, merchant.getMerNo());
                if (account != null) {
                    account.setStatus(0);
                    agentMerAccountService.editData(account);
                }
            }
        }

        if (agent.getType().equals(AgentTypeEnum.type2.getCode())) {
            // 通知
            BsAgentApiParam apiParam = agentApiParamService.getParam(agentId);
            if (apiParam != null && StringUtils.isNotBlank(apiParam.getMerInfoNotify())) {
                // 创建一个单线程的线程池
                ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
                // 异步记录登录信息
                singleThreadExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            for (String merNo : merNoArray) {
                                try {
                                    // 查询油站
                                    ResponseQueryGasInfoModel gasInfo = apiGasService.queryGasInfo(agentId,merNo);
                                    gasInfo.setGasStatus(MerchantStatusEnum.status2.getNumber());
                                    JSONObject notifyParam = JSONObject.parseObject(JSONObject.toJSONString(gasInfo), JSONObject.class);
                                    notifyParam.put("sign", SignatureUtil.createSign(notifyParam, apiParam.getAppSecret()));
                                    // 通知代理提供的URL
                                    HttpsUtils.doApiPost(apiParam.getMerInfoNotify(), notifyParam);
                                } catch (Exception e) {
                                    System.out.println("通知代理商："+apiParam.getAgentId()+"失败"+e.getMessage());
                                }
                            }
                        } catch (Exception e) {
                            System.out.println("通知代理商："+apiParam.getAgentId()+"失败"+e.getMessage());
                        }
                    }
                });
            }
        }
    }

    @Override
    public List<AgentMerAllot> getAllotList(Map<String, Object> param) {
        return agentMerMapper.getAllotList(param);
    }

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

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

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

        if (MapUtils.getLong(param, "provinceCode") != null) {
            criteria.andProvinceCodeEqualTo(MapUtils.getLong(param, "provinceCode"));
        }

        if (MapUtils.getLong(param, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(param, "agentId"));
        }

        if (MapUtils.getLong(param, "agentStaffId") != null) {
            criteria.andAgentStaffIdEqualTo(MapUtils.getLong(param, "agentStaffId"));
        }

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

    @Override
    public List<ResponseQueryGasInfoModel> getMerNoList(Long agentId) {
        return agentMerMapper.getMerNoList(agentId);
    }

    @Override
    public BsAgentMer getDetailByAgent(Long agentId, String merNo) {
        BsAgentMerExample example = new BsAgentMerExample();
        example.createCriteria().andAgentIdEqualTo(agentId).andMerNoEqualTo(merNo).andStatusNotEqualTo(0);
        List<BsAgentMer> list = agentMerMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsAgentMer getDetail(Long id) {
        return agentMerMapper.selectByPrimaryKey(id);
    }

    @Override
    public BsAgentMer getDetailByAgentStaff(Long agentStaffId, String merNo) {
        BsAgentMerExample example = new BsAgentMerExample();
        example.createCriteria().andAgentStaffIdEqualTo(agentStaffId).andMerNoEqualTo(merNo).andStatusNotEqualTo(0);
        List<BsAgentMer> list = agentMerMapper.selectByExample(example);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public void assignStaff(Long staffId, List<String> merNoArray) {
        // 代理商工作人员
        BsAgentStaff staff = agentStaffService.getStaffDetailById(staffId);
        if (staff == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的代理商");
        }
        // 代理商
        BsAgent agent = agentService.getAgentById(staff.getAgentId());
        if (agent == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的代理商");
        }
        // 查询代理商工作人员的油站
        Map<String,Object> param = new HashMap<>();
        param.put("agentStaffId", agent.getId());
        List<BsAgentMer> agentMerList = getList(param);

        List<BsAgentMer> dataList = new ArrayList<>();
        BsAgentMer agentMer;
        for (String merNo : merNoArray) {
            // 查询门店
            BsMerchant merchant = merchantService.getMerchant(merNo);
            if (merchant == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的加油站");
            }
            List<BsAgentMer> collect = agentMerList.stream().filter(o -> o.getMerNo().equals(merNo)).collect(Collectors.toList());
            if (collect.isEmpty()) {
                agentMer = new BsAgentMer();
                agentMer.setAgentId(agent.getId());
                agentMer.setAgentName(agent.getName());
                agentMer.setAgentName(agent.getName());
                agentMer.setAgentStaffId(staff.getId());
                agentMer.setAgentStaffName(staff.getName());
                agentMer.setMerSourceType(merchant.getSourceType());
                agentMer.setProvinceCode(merchant.getProvinceCode());
                agentMer.setProvinceName(merchant.getProvinceName());
                agentMer.setMerId(merchant.getId());
                agentMer.setMerNo(merchant.getMerNo());
                agentMer.setMerName(merchant.getMerName());
                agentMer.setStatus(1);
                agentMer.setCreateTime(new Date());
                agentMer.setUpdateTime(new Date());
                dataList.add(agentMer);
            }
        }
        agentMerService.addData(dataList);
    }

    @Override
    public void unbindStaff(Long staffId, List<String> merNoArray) {
        // 删除商户
        BsAgentMer agentMer = new BsAgentMer();
        agentMer.setStatus(0);
        BsAgentMerExample example = new BsAgentMerExample();
        example.createCriteria().andAgentStaffIdEqualTo(staffId).andMerNoIn(merNoArray).andStatusNotEqualTo(0);
        agentMerMapper.updateByExampleSelective(agentMer, example);
    }

    @Override
    public void agentNotify(Long agentId, String merNo) {
        List<BsAgentApiParam> list = agentApiParamService.getParamListByGasNo(merNo);
        if (agentId != null) {
            list = list.stream().filter(o-> o.getAgentId().equals(agentId)).collect(Collectors.toList());
        }
        for (BsAgentApiParam apiParam : list) {
            if (StringUtils.isNotBlank(apiParam.getMerInfoNotify())) {
                // 查询油站
                ResponseQueryGasInfoModel gasInfo = apiGasService.queryGasInfo(apiParam.getAgentId(),merNo);
                // 创建一个单线程的线程池
                ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
                // 异步记录登录信息
                singleThreadExecutor.submit(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // 通知代理
                            JSONObject notifyParam = JSONObject.parseObject(JSONObject.toJSONString(gasInfo), JSONObject.class);
                            notifyParam.put("sign", SignatureUtil.createSign(notifyParam, apiParam.getAppSecret()));
                            HttpsUtils.doApiPost(apiParam.getMerInfoNotify(), notifyParam);
                        } catch (Exception e) {
                            System.out.println("通知代理商："+apiParam.getAgentId()+"失败"+e.getMessage());
                        }
                    }
                });
            }
        }
    }


}
