package com.fjhx.sale.flow;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.utils.Assert;
import com.fjhx.flow.core.FlowDelegate;
import com.fjhx.item.entity.product.po.ProductInfoEhsdJson;
import com.fjhx.sale.entity.contract.dto.ContractDto;
import com.fjhx.sale.entity.contract.po.Contract;
import com.fjhx.sale.entity.contract.po.ContractProduct;
import com.fjhx.sale.entity.contract.po.ContractProject;
import com.fjhx.sale.entity.contract.po.ContractShipment;
import com.fjhx.sale.service.contract.ContractProductService;
import com.fjhx.sale.service.contract.ContractProjectService;
import com.fjhx.sale.service.contract.ContractService;
import com.fjhx.sale.service.contract.ContractShipmentService;
import com.ruoyi.common.core.domain.BaseIdPo;
import com.ruoyi.common.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 合同变更流程
 */
@Component
public class ContractUpdateFlow extends FlowDelegate {

    @Autowired
    private ContractFlow contractFlow;

    @Autowired
    private ContractService contractService;

    @Autowired
    private ContractProductService contractProductService;

    @Autowired
    private ContractProjectService contractProjectService;

    @Autowired
    private ContractShipmentService contractShipmentService;

    @Override
    public String getFlowKey() {
        return "contract_update_flow";
    }

    /**
     * 发起流程
     *
     * @param flowId     流程ID
     * @param submitData 采购付款数据
     * @return
     */
    @Override
    public Long start(Long flowId, JSONObject submitData) {

        ContractDto contract = submitData.toJavaObject(ContractDto.class);

        // 原合同id不能为空
        Long oldContractId = contract.getOldContractId();
        if (oldContractId == null) {
            throw new ServiceException("原合同id不能为空");
        }
        //查询原合同
        Contract oldContract = contractService.getById(contract.getOldContractId());
        if(ObjectUtil.isEmpty(oldContract)){
            throw new ServiceException("查询不到原合同信息");
        }
        //查询旧合同的订单产品
        List<ContractProduct> oldContractProductList = contractProductService.list(q -> q.eq(ContractProduct::getContractId, oldContractId));
        if(CollectionUtils.isEmpty(oldContractProductList)){
            throw new ServiceException("原合同没有产品");
        }
        Map<Long,List<ContractProduct>> oldContractProductMap = oldContractProductList.stream().collect(Collectors.groupingBy(ContractProduct::getId));
        List<ContractProduct> newContractProductList = contract.getContractProductList();
        if(CollectionUtils.isEmpty(newContractProductList)){
            throw new ServiceException("变更合同产品不能为空");
        }
        /**
         * 赋值新的变更合同号
         */
        String code = oldContract.getCode();
        Matcher matcher = Pattern.compile(".*\\((.*?)\\)$").matcher(code);
        int index = 2;
        if (matcher.find()) {
            index = (Integer.parseInt(matcher.group(1)) + 1);
            code = code.substring(0, code.lastIndexOf("("));
        }
        contract.setCode(code + "(" + index + ")");
        /**
         * 计算新合同的剩余数量
         */
        for(ContractProduct newCp:newContractProductList){

            if(ObjectUtil.isNotEmpty(newCp.getId())){//如果新合同产品ID不为空
                //取出旧合同
                ContractProduct oldContractProduct = oldContractProductMap.getOrDefault(newCp.getId(),null).get(0);
                //取出旧合同包装方式
                JSONObject oldJson = JSONObject.parseObject(oldContractProduct.getEhsdJson());
                String oldPackMethod = oldJson.getOrDefault("packMethod",null)==null?null:oldJson.getOrDefault("packMethod",null).toString();
                //取出新合同包装方式
                JSONObject newJson = JSONObject.parseObject(newCp.getEhsdJson());
                String newPackMethod = newJson.getOrDefault("packMethod",null)==null?null:oldJson.getOrDefault("packMethod",null).toString();
                /**
                 * 商品英文名、尺寸、包装方式、数量 没有变更---取原本的剩余数量
                 */
                if(oldContractProduct.getQuantity().compareTo(newCp.getQuantity())==0
                        && StringUtils.equals(oldContractProduct.getProductName(), newCp.getProductName())
                        && StringUtils.equals(oldContractProduct.getProductModel(),newCp.getProductModel())
                        && StringUtils.equals(oldPackMethod,newPackMethod)){
                    //取出旧的剩余数量
                    newCp.setExpendQuantity(oldContractProduct.getExpendQuantity());
                }
            }
        }
        return contractFlow.start(contract);
    }

    /**
     * 结束流程
     *
     * @param flowId     流程ID
     * @param businessId 业务ID
     * @param submitData 数据
     */
    @Override
    public void end(Long flowId, Long businessId, JSONObject submitData) {
        // 通过业务ID查询合同数据
        Contract newContract = contractService.getById(businessId);
        if (ObjectUtils.isEmpty(newContract)) {
            throw new ServiceException("合同不存在");
        }
        long  oldContractId = newContract.getOldContractId();//取出旧的合同ID
        Contract oldContract = contractService.getById(oldContractId);
        if (oldContract == null) {
            throw new ServiceException("原合同不存在");
        }
        /**
         * 处理新合同---
         */
        newContract.setId(oldContractId);//id赋值为旧合同的id
        newContract.setStatus(FlowStatusEnum1.PASS.getKey());
        newContract.setApprovedDate(new Date());
        contractService.update(newContract,Wrappers.<Contract>query().lambda().eq(Contract::getId,businessId));
        //修改合同产品相关数据
        contractProductService.update(Wrappers.<ContractProduct>update().lambda().set(ContractProduct::getContractId,oldContractId).eq(ContractProduct::getContractId,businessId));
        //修改合同收费相关数据
        contractProjectService.update(Wrappers.<ContractProject>update().lambda().set(ContractProject::getContractId,oldContractId).eq(ContractProject::getContractId,businessId));
        //修改合同出货相关数据
        contractShipmentService.update(Wrappers.<ContractShipment>update().lambda().set(ContractShipment::getContractId,oldContractId).eq(ContractShipment::getContractId,businessId));
        /**
         * 处理旧的合同---
         */
        oldContract.setId(businessId);
        oldContract.setStatus(FlowStatusEnum1.UPDATE.getKey());
        oldContract.setIsChange("1");
        contractService.update(oldContract,Wrappers.<Contract>query().lambda().eq(Contract::getId,oldContractId));
        //修改合同产品相关数据
        contractProductService.update(Wrappers.<ContractProduct>update().lambda().set(ContractProduct::getContractId,businessId).eq(ContractProduct::getContractId,oldContractId));
        //修改合同收费相关数据
        contractProjectService.update(Wrappers.<ContractProject>update().lambda().set(ContractProject::getContractId,businessId).eq(ContractProject::getContractId,oldContractId));
        //修改合同出货相关数据
        contractShipmentService.update(Wrappers.<ContractShipment>update().lambda().set(ContractShipment::getContractId,businessId).eq(ContractShipment::getContractId,oldContractId));
    }
}
