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

import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
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.procure.BpmOAProcureListEditReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procure.BpmOAProcurePageReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.procure.BpmOAProcureSaveReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.upload.UploadUserFile;
import cn.iocoder.yudao.module.bpm.convert.oa.BpmOAProcureConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAProcureDO;
import cn.iocoder.yudao.module.bpm.dal.dataobject.oa.BpmOAReimbursementDO;
import cn.iocoder.yudao.module.bpm.dal.mysql.oa.BpmOAProcureMapper;
import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * OA 采购申请 Service 实现类
 *
 * @author 姚君
 */
@Service
@Validated
public class BpmOAProcureServiceImpl extends BpmOABaseService implements BpmOAProcureService {

    @Resource
    private BpmOAProcureMapper bpmOaProcureMapper;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;
    /**
     * OA 采购申请对应的流程定义 KEY
     */
    public static final String PROCESS_KEY = "oa_procure";

    @Override
    public Long createOaProcure(BpmOAProcureSaveReqVO createReqVO) {
        Long userId = WebFrameworkUtils.getLoginUserId();
        // 插入
        BpmOAProcureDO oaProcure = BpmOAProcureConvert.INSTANCE.convert(createReqVO).setUserId(userId)
                .setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
        bpmOaProcureMapper.insert(oaProcure);

        // 发起 BPM 流程
        Map<String, Object> processInstanceVariables = new HashMap<>();
        String processInstanceId = processInstanceApi.createProcessInstance(userId,
                new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(PROCESS_KEY)
                        .setVariables(processInstanceVariables).setBusinessKey(String.valueOf(oaProcure.getId()))).getCheckedData();

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

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

    @Override
    public void updateOaProcure(BpmOAProcureSaveReqVO updateReqVO) {
        // 校验存在
        validateOaProcureExists(updateReqVO.getId());
        // 更新
        BpmOAProcureDO updateObj = BeanUtils.toBean(updateReqVO, BpmOAProcureDO.class);
        bpmOaProcureMapper.updateById(updateObj);
    }

    @Override
    public void deleteOaProcure(Long id) {
        // 校验存在
        validateOaProcureExists(id);
        // 删除
        bpmOaProcureMapper.deleteById(id);
    }

    private void validateOaProcureExists(Long id) {
        if (bpmOaProcureMapper.selectById(id) == null) {
            throw exception(GlobalErrorCodeConstants.OA_PROCURE_NOT_EXISTS);
        }
    }

    @Override
    public BpmOAProcureDO getOaProcure(Long id) {
        return bpmOaProcureMapper.selectById(id);
    }

    @Override
    public PageResult<BpmOAProcureDO> getOaProcurePage(BpmOAProcurePageReqVO pageReqVO) {
        return bpmOaProcureMapper.selectPage(pageReqVO);
    }

    @Override
    public void updatePayFlagByIds(BpmOAProcureListEditReqVO vo) {
        bpmOaProcureMapper.update(new BpmOAProcureDO().setPayFlag(vo.getPayFlag()),
                new LambdaQueryWrapperX<BpmOAProcureDO>()
                        .inIfPresent(BpmOAProcureDO::getId, vo.getProcureIds()));
    }

    @Override
    public void updateEvectionResult(Long id, Integer result) {
        bpmOaProcureMapper.updateById(new BpmOAProcureDO().setId(id).setResult(result));
    }

}
