package cn.iocoder.yudao.module.bpm.service.oa;

import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.UploadUserFile;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.supplier.BpmOASupplierPageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.supplier.BpmOASupplierSaveReqVO;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOASupplierConvert;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOaSupplierProductConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASupplierDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOASupplierProductDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOASupplierMapper;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOASupplierProductMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import cn.iocoder.yudao.module.bpm.service.task.BpmHistoryProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.system.api.supplier.SupplierApi;
import cn.iocoder.yudao.module.system.api.supplier.dto.SupplierProductRpcDTO;
import cn.iocoder.yudao.module.system.api.supplier.dto.SupplierRpcDTO;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * OA供应商审核 Service 实现类
 *
 * @author 艾楷
 */
@Service
@Validated
public class BpmOaSupplierServiceImpl extends BpmOABaseService implements BpmOASupplierService {

    @Resource
    private BpmOASupplierMapper oaSupplierMapper;
    @Resource
    private BpmOASupplierProductMapper oaSupplierProductMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    @Resource
    @Lazy // 解决循环依赖
    private BpmHistoryProcessInstanceService historyProcessInstanceService;
    @Resource
    private BpmProcessInstanceService processInstanceService;
    @Resource
    private SupplierApi supplierApi;
    /**
     * OA 供应商审核 KEY
     */
    public static final String PROCESS_KEY = "oa_supplier_2";

    @Override
    public Long createOaSupplier(BpmOASupplierSaveReqVO createReqVO) {
        Long userId = WebFrameworkUtils.getLoginUserId();
        createReqVO.setUserId(userId);
        // 采购支付对象转换
        BpmOASupplierDO oaSupplier = BpmOASupplierConvert.INSTANCE.convert(createReqVO);
        oaSupplierMapper.insert(oaSupplier);

        // 子列表转换
        List<BpmOASupplierProductDO> items = BpmOaSupplierProductConvert.INSTANCE.convert(createReqVO.getItems());
        for (BpmOASupplierProductDO item : items) {
            item.setOaSupplierId(oaSupplier.getId());
            item.setUserId(userId);
        }
        oaSupplierProductMapper.insertBatch(items);
        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        String processInstanceId = processInstanceApi.createProcessInstance(userId,
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                        .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(oaSupplier.getId()))).getCheckedData();

        // 将工作流的编号，更新到 OA 采购单中
        oaSupplierMapper.updateById(new BpmOASupplierDO().setId(oaSupplier.getId()).setProcessInstanceId(processInstanceId));

        // 判断是否为重新发起的流程
        if (createReqVO.getProcessInstanceId() != null && createReqVO.getResult() == 3) {
            historyProcessInstanceService.createHistoryProcessInstance(processInstanceId, createReqVO.getProcessInstanceId());
        }

        List<UploadUserFile> fileItems = createReqVO.getFileItems();
        //这里的逻辑，如果fileItems不为空，且有数据，那么说明是上传了附件的，则需要更工作流文件表对应的实例Id
        if (fileItems != null && !fileItems.isEmpty()) {
            uploadBpmFileProcessInstanceId(processInstanceId, fileItems);
        }
        // 返回
        return oaSupplier.getId();
    }

    @Override
    public void updateOaSupplier(BpmOASupplierSaveReqVO updateReqVO) {
        // 更新
        BpmOASupplierDO updateObj = BeanUtils.toBean(updateReqVO, BpmOASupplierDO.class);
        oaSupplierMapper.updateById(updateObj);
    }

    @Override
    public void deleteOaSupplier(Long id) {
        // 删除
        oaSupplierMapper.deleteById(id);
    }

    @Override
    public BpmOASupplierDO getOaSupplier(Long id) {
        return oaSupplierMapper.selectById(id);
    }

    @Override
    public PageResult<BpmOASupplierDO> getOaSupplierPage(BpmOASupplierPageReqVO pageReqVO) {
        return oaSupplierMapper.selectPage(pageReqVO);
    }

    @Override
    public void updateSupplierResult(String processInstanceId, Long id, Integer result) {
        //审核通过 （最后节点）
        if (BpmProcessInstanceResultEnum.APPROVE.getResult().equals(result)) {
            ProcessInstance instance = processInstanceService.getProcessInstance(processInstanceId);
            if (instance.isEnded()) {
                // -- 获取到供应商和商品的信息 - 插入到具体到业务表中
                BpmOASupplierDO bpmOASupplierDO = oaSupplierMapper.selectById(id);
                List<BpmOASupplierProductDO> bpmOASupplierProductDOList = oaSupplierProductMapper.selectList(BpmOASupplierProductDO::getOaSupplierId, id);
                SupplierRpcDTO supplierRpcDTO = BeanUtil.copyProperties(bpmOASupplierDO, SupplierRpcDTO.class);
                supplierRpcDTO.setId(bpmOASupplierDO.getSupplierId());
                List<SupplierProductRpcDTO> item = new ArrayList<>();
                if (!bpmOASupplierProductDOList.isEmpty()) {
                    for (BpmOASupplierProductDO bpmOASupplierProductDO : bpmOASupplierProductDOList) {
                        SupplierProductRpcDTO supplierProductRpcDTO = BeanUtil.copyProperties(bpmOASupplierProductDO, SupplierProductRpcDTO.class);
                        supplierProductRpcDTO.setSupplierId(supplierRpcDTO.getId());
                        supplierProductRpcDTO.setId(bpmOASupplierProductDO.getSupplierProductId());
                        item.add(supplierProductRpcDTO);
                    }
                }
                supplierRpcDTO.setItems(item);
                supplierApi.saveOrEdit(supplierRpcDTO);
            }
        }
        oaSupplierMapper.updateById(new BpmOASupplierDO().setId(id).setResult(result).setProcessInstanceId(processInstanceId));
    }

}
