package org.dromara.payment.operator.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.enums.BusRole;
import org.dromara.common.core.service.BaseService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.payment.api.operator.domain.RemoteBusOperatorProductVo;
import org.dromara.payment.channel.domain.BusChannelProduct;
import org.dromara.payment.operator.domain.ReProductInvoice;
import org.dromara.payment.operator.domain.bo.AllocOperatorProductBo;
import org.dromara.payment.operator.mapper.ReProductInvoiceMapper;
import org.dromara.payment.sys.service.ISysSydService;
import org.dromara.system.api.model.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.dromara.payment.operator.domain.bo.BusOperatorProductBo;
import org.dromara.payment.operator.domain.vo.BusOperatorProductVo;
import org.dromara.payment.operator.domain.BusOperatorProduct;
import org.dromara.payment.operator.mapper.BusOperatorProductMapper;
import org.dromara.payment.operator.service.IBusOperatorProductService;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 运营商产品Service业务层处理
 *
 * @author LionLi
 * @date 2024-03-28
 */
@RequiredArgsConstructor
@Service
public class BusOperatorProductServiceImpl extends BaseService implements IBusOperatorProductService {

    private final BusOperatorProductMapper baseMapper;

    private final ReProductInvoiceMapper reProductInvoiceMapper;

    private final StreamBridge streamBridge;
    /**
     * 查询运营商产品
     */
    @Override
    public BusOperatorProductVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询运营商产品列表
     */
    @Override
    public TableDataInfo<BusOperatorProductVo> queryPageList(BusOperatorProductBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BusOperatorProduct> lqw = buildQueryWrapper(bo);
        Page<BusOperatorProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询运营商产品列表
     */
    @Override
    public List<BusOperatorProductVo> queryList(BusOperatorProductBo bo) {
        LambdaQueryWrapper<BusOperatorProduct> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<BusOperatorProduct> buildQueryWrapper(BusOperatorProductBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BusOperatorProduct> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getSydId() != null, BusOperatorProduct::getSydId, bo.getSydId());
        lqw.eq(StringUtils.isNotBlank(bo.getSydNo()), BusOperatorProduct::getSydNo, bo.getSydNo());
        lqw.eq(bo.getBusType() != null, BusOperatorProduct::getBusType, bo.getBusType());
        lqw.eq(StringUtils.isNotBlank(bo.getProNo()), BusOperatorProduct::getProNo, bo.getProNo());
        lqw.eq(bo.getProId() != null, BusOperatorProduct::getProId, bo.getProId());
        lqw.eq(StringUtils.isNotBlank(bo.getOpNo()), BusOperatorProduct::getOpNo, bo.getOpNo());
        lqw.eq(bo.getOpId() != null, BusOperatorProduct::getOpId, bo.getOpId());
        lqw.eq(bo.getCostServiceCharge() != null, BusOperatorProduct::getCostServiceCharge, bo.getCostServiceCharge());
        lqw.eq(bo.getServiceCharge() != null, BusOperatorProduct::getServiceCharge, bo.getServiceCharge());
        lqw.eq(bo.getChargeMode() != null, BusOperatorProduct::getChargeMode, bo.getChargeMode());
        lqw.eq(bo.getSettlementStyle() != null, BusOperatorProduct::getSettlementStyle, bo.getSettlementStyle());
        lqw.eq(bo.getMaxMonth() != null, BusOperatorProduct::getMaxMonth, bo.getMaxMonth());
        lqw.eq(bo.getInvoiceType() != null, BusOperatorProduct::getInvoiceType, bo.getInvoiceType());
        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceItems()), BusOperatorProduct::getInvoiceItems, bo.getInvoiceItems());
        lqw.eq(bo.getProStatus() != null, BusOperatorProduct::getProStatus, bo.getProStatus());
        return lqw;
    }

    /**
     * 新增运营商产品
     */
    @Override
    public Boolean insertByBo(BusOperatorProductBo bo) {
        BusOperatorProduct add = MapstructUtils.convert(bo, BusOperatorProduct.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改运营商产品
     */
    @Override
    public Boolean updateByBo(BusOperatorProductBo bo) {
        BusOperatorProduct update = MapstructUtils.convert(bo, BusOperatorProduct.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BusOperatorProduct entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除运营商产品
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean allocOperatorProduct(AllocOperatorProductBo bo) {
        bo.setCreateTime(new Date());
        LambdaQueryWrapper<BusOperatorProduct> lqw = Wrappers.lambdaQuery();

        Long opId = bo.getProducts().get(0).getOpId();
        String opNo = bo.getProducts().get(0).getOpNo();
        if(opId == null){
            this.invalidationParamsException("运营商ID[opId]不能为空");
        }
        if(StringUtils.isEmpty(opNo)){
            this.invalidationParamsException("运营商编码[opNo]不能为空");
        }

        Long busType = bo.getProducts().get(0).getBusType();
        List<Long> proIds = StreamUtils.toList(bo.getProducts(), RemoteBusOperatorProductVo::getProId);
        lqw.eq(BusOperatorProduct::getOpId,opId);
        lqw.in(BusOperatorProduct::getProId,proIds);


        Map selOperPros = new HashMap();
        Map paraMap = new HashMap();
        paraMap.put("busType",busType);
        paraMap.put("opId",opId);

        List<BusChannelProduct> busProList  = this.baseMapper.selectChannelProductMin(paraMap);

        //查询已经分配的产品费率
        if(busProList != null && !busProList.isEmpty()){
            for(BusChannelProduct bopd: busProList){
                selOperPros.put(bopd.getProNo(),bopd);
            }
        }

        //验证产品费率
        List<RemoteBusOperatorProductVo>  remoteBusProList =  bo.getProducts();

        List updateList = new ArrayList();

        for(RemoteBusOperatorProductVo  opv : remoteBusProList){
            opv.setCreateTime(new Date());
            opv.setCreateBy(LoginHelper.getUserId());
//            opv.setCostServiceCharge(opv.getServiceCharge());
            if(opv.getServiceCharge() != null ){

//                opv.setServiceCharge(opv.getServiceCharge());
                if(opv.getServiceCharge().compareTo(opv.getCostServiceCharge()) < 0){
                    this.invalidationParamsException("产品编号["+opv.getProNo() + "]的配置服务费率不能小于成本费率");
                }
                BusChannelProduct  bopd = (BusChannelProduct)selOperPros.get(opv.getProNo());
                if(bopd != null && bopd.getServiceCharge() != null){
                    if(bopd.getServiceCharge() != null){
                        if(opv.getServiceCharge().compareTo(bopd.getServiceCharge()) > 0){
                            this.invalidationParamsException("产品编号["+opv.getProNo() + "]的配置服务费率不能大于成本费率["+bopd.getServiceCharge()+"]");
                        }else{
                            if(opv.getProStatus() == 1){
                                Map upMap = new HashMap();
                                upMap.put("cost_service_charge",opv.getServiceCharge());
                                upMap.put("op_id",opId);
                                upMap.put("pro_id",opv.getProId());
                                updateList.add(upMap);
                            }
                        }
                    }
                }
            }
        }
        baseMapper.delete(lqw);
//        baseMapper.allocOperatorProduct(bo);
        baseMapper.insertOperatorProduct(bo);
        if(!updateList.isEmpty()){
            this.baseMapper.updateChannelProCostCharge(updateList);
        }
        reProductInvoiceMapper.delete(new LambdaQueryWrapper<ReProductInvoice>().eq(ReProductInvoice::getBusId,opId).eq(ReProductInvoice::getBusType,BusRole.OPERATOR.getId()));
        List<Long> sydIds = bo.getProducts().stream().map(RemoteBusOperatorProductVo::getSydId).distinct().collect(Collectors.toList());
        reProductInvoiceMapper.allocProduct(proIds,sydIds, BusRole.SERVICE.getId(),opId,BusRole.OPERATOR.getId(),bo.getCreateBy(),new Date());
        JSONObject queueParam = new JSONObject();
        queueParam.put("accType", BusRole.OPERATOR.getId());
        queueParam.put("addAccType", BusRole.PLATFORM.getId());
        queueParam.put("accUnitId", opId);
        queueParam.put("sydIds",sydIds.stream().map(String::valueOf).collect(Collectors.joining(",")));
        streamBridge.send("account-out-0", MessageBuilder.withPayload(queueParam).build());
        return true;
    }

    @Override
    public TableDataInfo<BusOperatorProductVo> queryPageListNew(BusOperatorProductBo bo, PageQuery pageQuery) {
        QueryWrapper lqw = Wrappers.query();
        lqw.eq("t.pro_status",1);
        lqw.like(StringUtils.isNotEmpty(bo.getSydName()),"t2.gsmc",bo.getSydName());
        lqw.eq("t.bus_type",bo.getBusType());
        lqw.isNotNull("t2.id");
        lqw.orderByDesc("t.create_time");
        Page<BusOperatorProductVo> result = baseMapper.setingOpratorProductList(pageQuery.build(), lqw,bo.getOpId());
        return TableDataInfo.build(result);

    }
}
