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

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
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.StringUtils;
import org.dromara.common.core.utils.ValidatorUtils;
import org.dromara.common.core.validate.AddGroup;
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.merchant.domain.BusMerchantProduct;
import org.dromara.payment.merchant.domain.bo.BusMerchantProductBo;
import org.dromara.payment.merchant.mapper.BusMerchantProductMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.dromara.payment.channel.domain.bo.BusChannelProductBo;
import org.dromara.payment.channel.domain.vo.BusChannelProductVo;
import org.dromara.payment.channel.domain.BusChannelProduct;
import org.dromara.payment.channel.mapper.BusChannelProductMapper;
import org.dromara.payment.channel.service.IBusChannelProductService;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 代理商产品Service业务层处理
 *
 * @author LionLi
 * @date 2024-04-10
 */
@RequiredArgsConstructor
@Service
public class BusChannelProductServiceImpl extends BaseService implements IBusChannelProductService {

    private static final Logger log = LoggerFactory.getLogger(BusChannelProductServiceImpl.class);
    private final BusChannelProductMapper baseMapper;

    private final BusMerchantProductMapper busMerchantProductMapper;

    /**
     * 查询代理商产品
     */
    @Override
    public BusChannelProductVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 给代理商分配产品，查询列表
     */
    @Override
    public TableDataInfo<BusChannelProductVo> queryPageList(BusChannelProductBo bo, PageQuery pageQuery) {
        if(bo.getChId() == null){
            this.invalidationParamsException("代理商ID不能为空");
        }
        if(bo.getBusType() == null){
            this.invalidationParamsException("业务类型不能为空");
        }
        bo.setChannelId(LoginHelper.getBusId());
        int burRole = LoginHelper.getLoginUser().getBusRole();
        Page<BusChannelProductVo> result = null;

        if(burRole == BusRole.AGENT.getId()){
            result = baseMapper.selectAgentProList(bo,pageQuery.build());
        }else if(burRole == BusRole.OPERATOR.getId()){
            result = baseMapper.selectOperAgentProList(bo,pageQuery.build());
        }else if(LoginHelper.isSuperAdmin()){
            result = baseMapper.selectOperAgentProList(bo,pageQuery.build());
        }
        if (result != null) {
            result.getRecords().forEach(item -> {
                item.setUnId(IdUtil.getSnowflakeNextId());
            });
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询代理商产品列表
     */
    @Override
    public List<BusChannelProductVo> queryList(BusChannelProductBo bo) {
        LambdaQueryWrapper<BusChannelProduct> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

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

    /**
     * 新增代理商产品
     */
    @Override
    @Transactional
    public Boolean insertByBo(JSONObject bo) {
        Long chId = bo.getLong("chId");
        String chNo = bo.getString("chNo");
        Integer busType = bo.getInteger("busType");
        String proListStr = bo.getString("boList");

        if(chId == null){
            this.invalidationParamsException("代理商ID不能为空");
        }

        if(chNo == null){
            this.invalidationParamsException("代理商编码不能为空");
        }

        if(busType == null){
            this.invalidationParamsException("业务类型不能为空");
        }

        if(StringUtils.isEmpty(proListStr)){
            this.invalidationParamsException("产品列表不能为空");
        }

        Map paraMap = new HashMap();
        paraMap.put("channel_no", LoginHelper.getNo());
        paraMap.put("bus_type",busType);
        List<BusChannelProductVo> agentList = new ArrayList();
        int busRole = LoginHelper.getLoginUser().getBusRole();
        if(busRole == BusRole.AGENT.getId()){
            agentList = this.baseMapper.selectAgentProInfos(paraMap);
            if(agentList.size() == 0){
                this.invalidationParamsException("当前代理商未配置产品");
            }
        }else if(busRole == BusRole.OPERATOR.getId()){
            agentList = this.baseMapper.selectOperProInfos(paraMap);
            if(agentList.size() == 0){
                this.invalidationParamsException("当前运营商未配置产品");
            }
        }

        List<BusChannelProductBo> voList = JSONUtil.toList(bo.getJSONArray("boList").toJSONString(), BusChannelProductBo.class);

        List<BusChannelProduct> insertList = new ArrayList();
        List<BusChannelProduct> updateList = new ArrayList();
        for(BusChannelProductBo vo1 :voList){

            BusChannelProductVo agentVo = agentList.stream().filter(t -> t.getProNo().equals(vo1.getProNo())).findFirst().orElse(null);
            if(agentVo == null){
                this.invalidationParamsException("产品["+vo1.getProNo()+"]未配置");
            }


            vo1.setSydId(agentVo.getSydId());
            vo1.setSydNo(agentVo.getSydNo());
            vo1.setProId(agentVo.getProId());
            vo1.setOpId(agentVo.getOpId());
            vo1.setOpNo(agentVo.getOpNo());
            vo1.setBusType(agentVo.getBusType());
            vo1.setChannelId(chId);
            vo1.setChannelNo(chNo);
            vo1.setCostServiceCharge(agentVo.getServiceCharge());
            vo1.setMaxMonth(agentVo.getMaxMonth());
            vo1.setCreateBy(LoginHelper.getUserId());
            vo1.setCreateTime(new  Date());
            if(vo1.getServiceCharge() != null){
                if(vo1.getServiceCharge().compareTo(vo1.getCostServiceCharge()) < 0){
                    vo1.setServiceCharge(vo1.getCostServiceCharge());
                }
                Map pMap = new HashMap();
                pMap.put("channelNo",chNo);
                pMap.put("busType",busType);
                pMap.put("proNo",vo1.getProNo());
                BigDecimal merMinCharge = this.busMerchantProductMapper.selMinChargeByAgentAndBusType(pMap);

                pMap.put("channelNo",chNo+"-");
                pMap.put("channelId",chId);
                BigDecimal chMinCharge = this.baseMapper.selMinChargeFromChannelProByAgentInfo(pMap);
                BigDecimal min = merMinCharge;

                if(min != null && chMinCharge != null && chMinCharge.compareTo(min) < 0){
                    min = chMinCharge;
                }else if(min == null && chMinCharge != null){
                    min = chMinCharge;
                }
                if(min != null && vo1.getServiceCharge().compareTo(min) > 0){
                    this.invalidationParamsException("产品["+vo1.getProNo()+"]分配费率不能超过"+min.toString()+"请重新分配");
                }
            }
            ValidatorUtils.validate(vo1, AddGroup.class);
            BusChannelProduct bp = MapstructUtils.convert(vo1, BusChannelProduct.class);
            if(busRole == BusRole.OPERATOR.getId()){
                bp.setUpIsOp(1);
            }else{
                bp.setUpIsOp(0);
            }
            bp.setCreateTime(new Date());
            bp.setCreateBy(LoginHelper.getUserId());
            if(vo1.getId() != null ){
                insertList.add(bp);
                if(bp.getProStatus() == 1){
                    updateList.add(bp);
                }
            }else{
                insertList.add(bp);
            }
        }
        this.baseMapper.insertOrUpdateBatch(insertList);

        for(BusChannelProduct pro : updateList){
            BusMerchantProductBo  proBo = new BusMerchantProductBo();
            proBo.setProNo(pro.getProNo());
            proBo.setCostServiceCharge(pro.getServiceCharge());
            proBo.setBusType(pro.getBusType());
            proBo.setChannelNo(chNo);
            proBo.setUpdateBy(LoginHelper.getUserId());
            proBo.setUpdateTime(new Date());
            this.busMerchantProductMapper.updateMerProInfos(proBo);


            BusChannelProductBo  bpBo = new BusChannelProductBo();
            bpBo.setCostServiceCharge(pro.getServiceCharge());
            bpBo.setProNo(pro.getProNo());
            bpBo.setBusType(pro.getBusType());
            bpBo.setChannelId(chId);
            bpBo.setChannelNo(chNo);

            this.baseMapper.updateBusChannelCost(bpBo);

        }
        return true;
    }

    /**
     * 修改代理商产品
     */
    @Override
    public Boolean updateByBo(BusChannelProductBo bo) {
        BusChannelProduct update = MapstructUtils.convert(bo, BusChannelProduct.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

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

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