package cn.superdesk.uniorder.service.unified.settlement.impl;

import cn.hutool.core.date.DateUtil;
import cn.superdesk.uniorder.common.enums.accounting.operator.SettlementProgrammeTypeEnum;
import cn.superdesk.uniorder.common.enums.accounting.operator.SettlementRangeWayEnum;
import cn.superdesk.uniorder.common.enums.accounting.operator.SettlementScopeEnum;
import cn.superdesk.uniorder.common.enums.accounting.operator.SupnameDisplayRuleEnum;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.sequence.GenRandomHelper;
import cn.superdesk.uniorder.dao.entity.operationCenter.UnifiedCenterCustomer;
import cn.superdesk.uniorder.dao.entity.unified.settlement.*;
import cn.superdesk.uniorder.dao.mapper.operationCenter.UnifiedCenterCustomerMapper;
import cn.superdesk.uniorder.dao.mapper.unified.settlement.*;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.OperationCenterCustomerParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.settlement.UnifiedSettlementAmountRuleParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.settlement.UnifiedSettlementParam;
import cn.superdesk.uniorder.dto.param.operationCenter.customer.settlement.UnifiedSettlementRangeRuleParam;
import cn.superdesk.uniorder.dto.vo.accounting.unified.operator.SettlementExportFieldVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.base.OperationCenterVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.OperationCenterCustomerVo;
import cn.superdesk.uniorder.dto.vo.operationCenter.customer.settlement.UnifiedSettlementVo;
import cn.superdesk.uniorder.service.unified.settlement.UnifiedSettlementProgrammeService;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class UnifiedSettlementProgrammeServiceImpl implements UnifiedSettlementProgrammeService {
    private final UnifiedSettlementProgrammeMapper unifiedSettlementProgrammeMapper;
    private final UnifiedSettlementProgrammeMapperEx unifiedSettlementProgrammeMapperEx;

    private final UnifiedSettlementProgrammeAmountRuleMapper unifiedSettlementProgrammeAmountRuleMapper;

    private final UnifiedSettlementProgrammeRangeRuleMapper unifiedSettlementProgrammeRangeRuleMapper;

    private final UnifiedCenterCustomerMapper unifiedCenterCustomerMapper;


    @Override
    public int insertSelective(UnifiedSettlementProgramme unifiedSettlementProgramme) {
        return 0;
    }

    @Override
    public int updateByPrimaryKeySelective(UnifiedSettlementProgramme unifiedSettlementProgramme) {
        return 0;
    }

    @Override
    public void deleteObj(Long id) {

    }

    @Override
    public UnifiedSettlementProgramme findById(Long id) {
        return unifiedSettlementProgrammeMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<UnifiedSettlementProgramme> findAll(Map<String, Object> queryMap) {
        return null;
    }

    @Override
    public PageInfo<UnifiedSettlementProgramme> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        return null;
    }

    @Override
    public List<UnifiedSettlementVo> list(OperationCenterCustomerParam param) {
        return unifiedSettlementProgrammeMapperEx.list(param);
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public R<String> saveUnifiedSettlement(UnifiedSettlementParam param, Long sysUserId) {
        //校验

        UnifiedSettlementProgramme entity = new UnifiedSettlementProgramme();
        BeanUtils.copyProperties(param, entity);
        entity.setCreateUserId(sysUserId);
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(sysUserId);

        entity.setProgrammeNo("PR"+ DateUtil.format(new Date(), "yyyyMM")+  GenRandomHelper.genRandomNum(6) );
        SettlementExportFieldVo vo = new SettlementExportFieldVo();
        BeanUtils.copyProperties(param, vo);
        entity.setExportField(JSON.toJSONString(vo));
        unifiedSettlementProgrammeMapper.insertSelective(entity);

        if (param.getSettlementScope().intValue() == SettlementScopeEnum.部分订单不参与结算.getKey().intValue()
            && CollectionUtils.isNotEmpty(param.getUnifiedSettlementRangeRuleParam1List())) {

            //结算范围 部分订单不参与结算
            for (UnifiedSettlementRangeRuleParam unifiedSettlementRangeRuleParam : param.getUnifiedSettlementRangeRuleParam1List()) {
                UnifiedSettlementProgrammeRangeRule rangeRule = new UnifiedSettlementProgrammeRangeRule();
                rangeRule.setType(1);
                rangeRule.setProgrammeId(entity.getId());
                rangeRule.setDisplay(unifiedSettlementRangeRuleParam.getDisplay());
                rangeRule.setCreateUserId(sysUserId);
                rangeRule.setCreateTime(new Date());
                rangeRule.setWay(unifiedSettlementRangeRuleParam.getWay());
                rangeRule.setNotJoiningRange(unifiedSettlementRangeRuleParam.getNotJoiningRange());
                rangeRule.setNotJoiningRangeJson(JSON.toJSONString(unifiedSettlementRangeRuleParam.getSysSelectVoList()));

                unifiedSettlementProgrammeRangeRuleMapper.insertSelective(rangeRule);
            }
        }

        if (CollectionUtils.isNotEmpty(param.getUnifiedSettlementAmountRuleParamList())) {

            //订单结算金额
            for (UnifiedSettlementAmountRuleParam amountRuleParam : param.getUnifiedSettlementAmountRuleParamList()) {
                UnifiedSettlementProgrammeAmountRule rule = new UnifiedSettlementProgrammeAmountRule();

                BeanUtils.copyProperties(amountRuleParam,rule);
                rule.setCreateUserId(sysUserId);
                rule.setCreateTime(new Date());
                rule.setProgrammeId(entity.getId());
                unifiedSettlementProgrammeAmountRuleMapper.insertSelective(rule);
            }


        }


        if (param.getSupnameDisplayRule().intValue() == SupnameDisplayRuleEnum.部分按原供应商名称导出.getKey().intValue()
                && CollectionUtils.isNotEmpty(param.getUnifiedSettlementRangeRuleParam1List())) {


            for (UnifiedSettlementRangeRuleParam unifiedSettlementRangeRuleParam : param.getUnifiedSettlementRangeRuleParam1List()) {
                UnifiedSettlementProgrammeRangeRule rangeRule = new UnifiedSettlementProgrammeRangeRule();
                rangeRule.setType(2);
                rangeRule.setProgrammeId(entity.getId());
                rangeRule.setDisplay(unifiedSettlementRangeRuleParam.getDisplay());
                rangeRule.setCreateUserId(sysUserId);
                rangeRule.setCreateTime(new Date());
                rangeRule.setWay(unifiedSettlementRangeRuleParam.getWay());
                rangeRule.setNotJoiningRange(unifiedSettlementRangeRuleParam.getNotJoiningRange());
                rangeRule.setNotJoiningRangeJson(JSON.toJSONString(unifiedSettlementRangeRuleParam.getSysSelectVoList()));

                unifiedSettlementProgrammeRangeRuleMapper.insertSelective(rangeRule);
            }
        }

        UnifiedCenterCustomer customer = new UnifiedCenterCustomer();
        customer.setId(param.getCustomerId());
        customer.setIsSettlementMethod((byte)1);
        unifiedCenterCustomerMapper.updateByPrimaryKeySelective(customer);

        //更改客户主体 结算方案已配置
        return new R<>("新增成功");
    }

    @Override
    public R<String> updateUnifiedSettlement(UnifiedSettlementParam param, Long sysUserId) {
        //校验
        if (null == param.getId()) {
            return new R<>("500", "id不能为空", false);
        }

        UnifiedSettlementProgramme entity = unifiedSettlementProgrammeMapper.selectByPrimaryKey(param.getId());
        BeanUtils.copyProperties(param, entity);

        entity.setUpdateTime(new Date());
        entity.setUpdateUserId(sysUserId);

        SettlementExportFieldVo vo = new SettlementExportFieldVo();
        BeanUtils.copyProperties(param, vo);
        entity.setExportField(JSON.toJSONString(vo));
        unifiedSettlementProgrammeMapper.updateByPrimaryKeySelective(entity);

        if (param.getSettlementScope().intValue() == SettlementScopeEnum.部分订单不参与结算.getKey().intValue()
                && CollectionUtils.isNotEmpty(param.getUnifiedSettlementRangeRuleParam1List())) {

            //先删除
            UnifiedSettlementProgrammeRangeRuleExample example =new UnifiedSettlementProgrammeRangeRuleExample();
            example.createCriteria().andProgrammeIdEqualTo(param.getId());
            unifiedSettlementProgrammeRangeRuleMapper.deleteByExample(example);


            //结算范围 部分订单不参与结算
            for (UnifiedSettlementRangeRuleParam unifiedSettlementRangeRuleParam : param.getUnifiedSettlementRangeRuleParam1List()) {
                UnifiedSettlementProgrammeRangeRule rangeRule = new UnifiedSettlementProgrammeRangeRule();
                rangeRule.setType(1);
                rangeRule.setProgrammeId(entity.getId());
                rangeRule.setDisplay(unifiedSettlementRangeRuleParam.getDisplay());
                rangeRule.setCreateUserId(sysUserId);
                rangeRule.setCreateTime(new Date());
                rangeRule.setWay(unifiedSettlementRangeRuleParam.getWay());
                rangeRule.setNotJoiningRange(unifiedSettlementRangeRuleParam.getNotJoiningRange());
                rangeRule.setNotJoiningRangeJson(JSON.toJSONString(unifiedSettlementRangeRuleParam.getSysSelectVoList()));

                unifiedSettlementProgrammeRangeRuleMapper.insertSelective(rangeRule);
            }
        }

        if (CollectionUtils.isNotEmpty(param.getUnifiedSettlementAmountRuleParamList())) {

            //先删除
            UnifiedSettlementProgrammeAmountRuleExample example = new UnifiedSettlementProgrammeAmountRuleExample();
            example.createCriteria().andProgrammeIdEqualTo(param.getId());
            unifiedSettlementProgrammeAmountRuleMapper.deleteByExample(example);


            //订单结算金额
            for (UnifiedSettlementAmountRuleParam amountRuleParam : param.getUnifiedSettlementAmountRuleParamList()) {
                UnifiedSettlementProgrammeAmountRule rule = new UnifiedSettlementProgrammeAmountRule();

                BeanUtils.copyProperties(amountRuleParam,rule);
                rule.setCreateUserId(sysUserId);
                rule.setCreateTime(new Date());
                rule.setProgrammeId(entity.getId());
                unifiedSettlementProgrammeAmountRuleMapper.insertSelective(rule);
            }


        }


        if (param.getSupnameDisplayRule().intValue() == SupnameDisplayRuleEnum.部分按原供应商名称导出.getKey().intValue()
                && CollectionUtils.isNotEmpty(param.getUnifiedSettlementRangeRuleParam1List())) {
            UnifiedSettlementProgrammeRangeRuleExample example =new UnifiedSettlementProgrammeRangeRuleExample();
            example.createCriteria().andProgrammeIdEqualTo(param.getId());
            unifiedSettlementProgrammeRangeRuleMapper.deleteByExample(example);

            for (UnifiedSettlementRangeRuleParam unifiedSettlementRangeRuleParam : param.getUnifiedSettlementRangeRuleParam1List()) {
                UnifiedSettlementProgrammeRangeRule rangeRule = new UnifiedSettlementProgrammeRangeRule();
                rangeRule.setType(2);
                rangeRule.setProgrammeId(entity.getId());
                rangeRule.setDisplay(unifiedSettlementRangeRuleParam.getDisplay());
                rangeRule.setCreateUserId(sysUserId);
                rangeRule.setCreateTime(new Date());
                rangeRule.setWay(unifiedSettlementRangeRuleParam.getWay());
                rangeRule.setNotJoiningRange(unifiedSettlementRangeRuleParam.getNotJoiningRange());
                rangeRule.setNotJoiningRangeJson(JSON.toJSONString(unifiedSettlementRangeRuleParam.getSysSelectVoList()));

                unifiedSettlementProgrammeRangeRuleMapper.insertSelective(rangeRule);
            }
        }

        //更改客户主体 结算方案已配置
        return new R<>("修改成功");
    }

    @Override
    public R<UnifiedSettlementParam> get(Long id) {
        UnifiedSettlementProgramme programme = unifiedSettlementProgrammeMapper.selectByPrimaryKey(id);
        UnifiedSettlementParam vo = new UnifiedSettlementParam();
        BeanUtils.copyProperties(programme, vo);


        programme.getExportField();
        SettlementExportFieldVo settlementExportFieldVo = JSON.parseObject(programme.getExportField(), SettlementExportFieldVo.class);
        BeanUtils.copyProperties(settlementExportFieldVo, vo);


        //主体
        UnifiedCenterCustomer customer = unifiedCenterCustomerMapper.selectByPrimaryKey(programme.getCustomerId());
        vo.setCustomerName(customer.getCustomerName());
        vo.setTypeDesc(SettlementProgrammeTypeEnum.getDescByKey((int)customer.getType()));

        List<UnifiedSettlementRangeRuleParam> unifiedSettlementRangeRuleParam1List = new ArrayList<>();

        List<UnifiedSettlementAmountRuleParam> unifiedSettlementAmountRuleParamList = new ArrayList<>();

        List<UnifiedSettlementRangeRuleParam> unifiedSettlementRangeRuleParam2List = new ArrayList<>();



        UnifiedSettlementProgrammeRangeRuleExample example1 =new UnifiedSettlementProgrammeRangeRuleExample();
        example1.createCriteria().andProgrammeIdEqualTo(id).andTypeEqualTo((byte) 1);
        List<UnifiedSettlementProgrammeRangeRule> rangeRules1 = unifiedSettlementProgrammeRangeRuleMapper.selectByExample(example1);

        for (UnifiedSettlementProgrammeRangeRule voRangeRule : rangeRules1) {
            UnifiedSettlementRangeRuleParam RangeRuleParam = new UnifiedSettlementRangeRuleParam();
            BeanUtils.copyProperties(voRangeRule,RangeRuleParam);
            if (StringUtils.isNotBlank(voRangeRule.getNotJoiningRangeJson())) {

                RangeRuleParam.setSysSelectVoList(JSON.parseArray(voRangeRule.getNotJoiningRangeJson(), OperationCenterVo.class));
            }
            unifiedSettlementRangeRuleParam1List.add(RangeRuleParam);
        }


        UnifiedSettlementProgrammeRangeRuleExample example2 =new UnifiedSettlementProgrammeRangeRuleExample();
        example2.createCriteria().andProgrammeIdEqualTo(id).andTypeEqualTo((byte) 2);
        List<UnifiedSettlementProgrammeRangeRule> rangeRules2 = unifiedSettlementProgrammeRangeRuleMapper.selectByExample(example2);

        for (UnifiedSettlementProgrammeRangeRule voRangeRule : rangeRules2) {
            UnifiedSettlementRangeRuleParam RangeRuleParam = new UnifiedSettlementRangeRuleParam();
            BeanUtils.copyProperties(voRangeRule,RangeRuleParam);
            if (StringUtils.isNotBlank(voRangeRule.getNotJoiningRangeJson())) {
                List<OperationCenterVo> operationCenterVos = JSON.parseArray(voRangeRule.getNotJoiningRangeJson(), OperationCenterVo.class);
                RangeRuleParam.setSysSelectVoList(operationCenterVos);
            }
            unifiedSettlementRangeRuleParam2List.add(RangeRuleParam);
        }


        UnifiedSettlementProgrammeAmountRuleExample example = new UnifiedSettlementProgrammeAmountRuleExample();
        example.createCriteria().andProgrammeIdEqualTo(id);
        List<UnifiedSettlementProgrammeAmountRule> amountRules = unifiedSettlementProgrammeAmountRuleMapper.selectByExample(example);
        for (UnifiedSettlementProgrammeAmountRule amountRule : amountRules) {
            UnifiedSettlementAmountRuleParam param = new UnifiedSettlementAmountRuleParam();
            BeanUtils.copyProperties(amountRule, param);
            unifiedSettlementAmountRuleParamList.add(param);
        }
        vo.setUnifiedSettlementRangeRuleParam1List(unifiedSettlementRangeRuleParam1List);
        vo.setUnifiedSettlementAmountRuleParamList(unifiedSettlementAmountRuleParamList);
        vo.setUnifiedSettlementRangeRuleParam2List(unifiedSettlementRangeRuleParam2List);

        return new R<>(vo);
    }

}
