package com.fjhx.sale.flow;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.common.enums.FlowStatusEnum1;
import com.fjhx.common.utils.Assert;
import com.fjhx.flow.core.FlowDelegate;
import com.fjhx.flow.core.FlowThreadLocalUtil;
import com.fjhx.flow.enums.FlowStatusEnum;
import com.fjhx.flow.enums.HandleTypeEnum;
import com.fjhx.purchase.entity.purchase.enums.PurchaseDataResourceEnum;
import com.fjhx.sale.entity.contract.po.ContractProduct;
import com.fjhx.sale.entity.purchase.dto.EhsdPurchaseDto;
import com.fjhx.sale.entity.purchase.po.EhsdPurchase;
import com.fjhx.sale.entity.purchase.po.EhsdPurchaseArrival;
import com.fjhx.sale.entity.purchase.po.EhsdPurchaseProduct;
import com.fjhx.sale.entity.purchase.po.EhsdPurchaseProject;
import com.fjhx.sale.entity.sample.po.Sample;
import com.fjhx.sale.entity.sample.po.SampleProduct;
import com.fjhx.sale.service.contract.ContractProductService;
import com.fjhx.sale.service.purchase.EhsdPurchaseArrivalService;
import com.fjhx.sale.service.purchase.EhsdPurchaseProductService;
import com.fjhx.sale.service.purchase.EhsdPurchaseProjectService;
import com.fjhx.sale.service.purchase.EhsdPurchaseService;
import com.fjhx.sale.service.sample.SampleProductService;
import com.ruoyi.common.annotation.LogicIgnore;
import com.ruoyi.common.core.domain.BaseIdPo;
import com.ruoyi.common.core.domain.BasePo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * EHSD采购变更流程
 */
@Component
@DS(SourceConstant.SALE)
public class EhsdPurchaseUpdateFlow extends FlowDelegate {
    @Autowired
    private EhsdPurchaseService ehsdPurchaseService;
    @Autowired
    private EhsdPurchaseFlow ehsdPurchaseFlow;
    @Autowired
    private EhsdPurchaseProductService ehsdPurchaseProductService;
    @Autowired
    private EhsdPurchaseProjectService ehsdPurchaseProjectService;
    @Autowired
    private EhsdPurchaseArrivalService ehsdPurchaseArrivalService;
    @Autowired
    private ContractProductService contractProductService;
    @Autowired
    private SampleProductService sampleProductService;

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

    /**
     * 发起流程
     */
    @Override
    public Long start(Long flowId, JSONObject submitData) {
        EhsdPurchaseDto purchase = submitData.toJavaObject(EhsdPurchaseDto.class);
        Assert.notEmpty(purchase.getId(), "采购合同id不能为空");

        //赋值原合同id
        purchase.setOldPurchaseId(purchase.getId());

        //赋值流程id
        purchase.setFlowId(flowId);

        //变更 用原来合同号加后缀
        EhsdPurchase oldPurchase = ehsdPurchaseService.getById(purchase.getOldPurchaseId());
        Assert.notEmpty(oldPurchase, "查询不到原合同信息");
        //原合同修改为变更中
        oldPurchase.setStatus(FlowStatusEnum1.UPDATE_LOADING.getKey());
        ehsdPurchaseService.updateById(oldPurchase);

        String code = oldPurchase.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("("));
        }
        purchase.setCode(code + "(" + index + ")");

        //获取明细信息
        List<EhsdPurchaseProduct> purchaseProductList = purchase.getPurchaseProductList();
        List<EhsdPurchaseProject> purchaseProjectList = purchase.getPurchaseProjectList();
        List<EhsdPurchaseArrival> purchaseArrivalList = purchase.getPurchaseArrivalList();

        //清空采购合同的id
        purchase.setId(null);
        //清空采购明细的id 以及 配件id 方便后面重新发起
        for (EhsdPurchaseProduct ehsdPurchaseProduct : purchaseProductList) {
            ehsdPurchaseProduct.setId(null);
            ehsdPurchaseProduct.getPurchaseProductMountingsList().forEach(item -> item.setId(null));
        }
        //清空其他费用的id方便后面重新发起
        purchaseProjectList.forEach(item -> item.setId(null));
        //清空到货要求的id方便后面重新发起
        purchaseArrivalList.forEach(item -> item.setId(null));

        //调用采购发起公共代码块
        purchase = ehsdPurchaseFlow.updateStart(purchase);

        return purchase.getId();
    }

    /**
     * 重新发起
     * @param flowId
     * @param businessId
     * @param flowStatus
     * @param submitData
     */
    @Override
    @LogicIgnore(tableName = {""},alias = {""})
    @Transactional(rollbackFor = Exception.class)
    public void relaunch(Long flowId, Long businessId, FlowStatusEnum flowStatus, JSONObject submitData) {
        //删除采购合同
        EhsdPurchaseDto purchase = submitData.toJavaObject(EhsdPurchaseDto.class);
        if(ObjectUtils.isEmpty(purchase)){
            throw new ServiceException("采购数据不能为空");
        }
        purchase.setFlowId(flowId);
        ehsdPurchaseFlow.connStart(purchase);
    }

    /**
     * 驳回
     * @param flowId
     * @param businessId
     * @param flowStatus
     */
    @Override
    public void reject(Long flowId, Long businessId, FlowStatusEnum flowStatus) {
        if (HandleTypeEnum.REJECT.equals(FlowThreadLocalUtil.getHandleTypeEnum())) {
            ehsdPurchaseService.update(q -> q
                    .eq(EhsdPurchase::getId, FlowThreadLocalUtil.getBusinessId())
                    .set(EhsdPurchase::getStatus, 20)//20为驳回
                    .set(EhsdPurchase::getUpdateTime, new Date())
                    .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
            );
        }
    }

    /**
     * 结束流程
     */
    @Override
    public void end(Long flowId, Long businessId, JSONObject submitData) {
        //通过业务ID查询采购数据
        EhsdPurchase purchase = ehsdPurchaseService.getById(businessId);
        Assert.notEmpty(purchase, "采购单不存在,或已被删除");

        //原合同改为 已变更
        EhsdPurchase oldEhsdPurchase = ehsdPurchaseService.getById(purchase.getOldPurchaseId());
        oldEhsdPurchase.setStatus(FlowStatusEnum1.UPDATE.getKey());
        ehsdPurchaseService.updateById(oldEhsdPurchase);

        //回滚旧合同的已采购数量
        List<EhsdPurchaseProduct> oldPurchaseProductList = ehsdPurchaseProductService.list(q -> q.eq(EhsdPurchaseProduct::getPurchaseId, purchase.getOldPurchaseId()));
        for (EhsdPurchaseProduct ehsdPurchaseProduct : oldPurchaseProductList) {
            if (ObjectUtils.isNotEmpty(ehsdPurchaseProduct.getDataResourceId()) && ehsdPurchaseProduct.getDataResource() == PurchaseDataResourceEnum.DATA_RESOURCE_1.getKey()) {//如果采购的是外销合同
                ContractProduct contractProduct = contractProductService.getById(ehsdPurchaseProduct.getDataResourceId());
                //回滚变更前待采购数量
                contractProduct.setExpendQuantity(contractProduct.getExpendQuantity().add(ehsdPurchaseProduct.getQuantity()));
                contractProductService.updateById(contractProduct);
            }
            if (ObjectUtils.isNotEmpty(ehsdPurchaseProduct.getDataResourceId()) && ehsdPurchaseProduct.getDataResource() == PurchaseDataResourceEnum.DATA_RESOURCE_2.getKey()) {//如果采购的是样品单
                SampleProduct sampleProduct = sampleProductService.getById(ehsdPurchaseProduct.getDataResourceId());
                //回滚变更前待采购数量
                sampleProduct.setExpendQuantity(sampleProduct.getExpendQuantity().add(ehsdPurchaseProduct.getQuantity()));
                sampleProductService.updateById(sampleProduct);
            }
        }


        //调用采购发起流程的结束方法
        ehsdPurchaseFlow.end(flowId, businessId, submitData);

        Long oldPurchaseId = purchase.getOldPurchaseId();

        //先将当前合同id 以及 当前合同关联数据的合同id 改为临时id
        long tempId = IdWorker.getId();
//        ehsdPurchaseService.update(q -> q.eq(BaseIdPo::getId, businessId).set(BaseIdPo::getId, tempId));
        ehsdPurchaseService.updatePurchaseId(businessId,tempId,SecurityUtils.getUserId());
        ehsdPurchaseProductService.update(q -> q.eq(EhsdPurchaseProduct::getPurchaseId, businessId).set(EhsdPurchaseProduct::getPurchaseId, tempId));
        ehsdPurchaseProjectService.update(q -> q.eq(EhsdPurchaseProject::getPurchaseId, businessId).set(EhsdPurchaseProject::getPurchaseId, tempId));
        ehsdPurchaseArrivalService.update(q -> q.eq(EhsdPurchaseArrival::getPurchaseId, businessId).set(EhsdPurchaseArrival::getPurchaseId, tempId));


        //将旧合同的id改为新合同id
        ehsdPurchaseService.updatePurchaseId(oldPurchaseId,businessId,SecurityUtils.getUserId());
        ehsdPurchaseService.update(q -> q
                .eq(BaseIdPo::getId, oldPurchaseId)
                .set(EhsdPurchase::getOldPurchaseId, oldPurchaseId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseProductService.update(q -> q
                .eq(EhsdPurchaseProduct::getPurchaseId, oldPurchaseId)
                .set(EhsdPurchaseProduct::getPurchaseId, businessId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseProjectService.update(q -> q
                .eq(EhsdPurchaseProject::getPurchaseId, oldPurchaseId)
                .set(EhsdPurchaseProject::getPurchaseId, businessId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseArrivalService.update(q -> q
                .eq(EhsdPurchaseArrival::getPurchaseId, oldPurchaseId)
                .set(EhsdPurchaseArrival::getPurchaseId, businessId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        //将新合同id改为旧合同id
        ehsdPurchaseService.updatePurchaseId(tempId,oldPurchaseId,SecurityUtils.getUserId());
        ehsdPurchaseService.update(q -> q
                .eq(BaseIdPo::getId, tempId)
                .set(EhsdPurchase::getOldPurchaseId, businessId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseProductService.update(q -> q
                .eq(EhsdPurchaseProduct::getPurchaseId, tempId)
                .set(EhsdPurchaseProduct::getPurchaseId, oldPurchaseId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseProjectService.update(q -> q
                .eq(EhsdPurchaseProject::getPurchaseId, tempId)
                .set(EhsdPurchaseProject::getPurchaseId, oldPurchaseId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
        ehsdPurchaseArrivalService.update(q -> q
                .eq(EhsdPurchaseArrival::getPurchaseId, tempId)
                .set(EhsdPurchaseArrival::getPurchaseId, oldPurchaseId)
                .set(BasePo::getUpdateTime, new Date())
                .set(BasePo::getUpdateUser, SecurityUtils.getUserId())
        );
    }

}
