package com.testor.module.contractor.manage.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.common.constant.StatusEnum;
import com.testor.common.model.UpdateProcessStatusReq;
import com.testor.module.contractor.common.model.constant.ContractorProcessStatus;
import com.testor.module.contractor.enums.ContractorFlowTypeEnum;
import com.testor.module.contractor.ledger.model.domain.TContractorProject;
import com.testor.module.contractor.ledger.service.TContractorProjectService;
import com.testor.module.contractor.manage.dao.TContractorPreparationDao;
import com.testor.module.contractor.manage.model.domain.TContractorPreparation;
import com.testor.module.contractor.manage.model.dto.ContractorPreparationDto;
import com.testor.module.contractor.manage.model.dto.TContractorConditionReviewParam;
import com.testor.module.contractor.manage.model.dto.TContractorPreparationParam;
import com.testor.module.contractor.manage.service.TContractorConditionReviewService;
import com.testor.module.contractor.manage.service.TContractorPreparationService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import com.tongtech.tfw.backend.core.helper.IdHelper;
import com.tongtech.tfw.backend.core.helper.StringHelper;
import com.tongtech.tfw.backend.core.helper.bean.BeanHelper;
import com.tongtech.tfw.workflow.apis.definition.controller.ProcessDefinitionController;
import com.tongtech.tfw.workflow.apis.definition.model.dto.ProcessDefStartParam;
import com.tongtech.tfw.workflow.apis.task.controller.WfTaskController;
import com.tongtech.tfw.workflow.apis.task.model.dto.CompleteTask;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;

/**
 * 开工准备Service业务层处理
 * 
 * @author testor-framework
 * @date 2024-11-24 13:19:04
 */
@Service
public class TContractorPreparationServiceImpl extends SuperServiceImpl<TContractorPreparationDao, TContractorPreparation> implements TContractorPreparationService
{
    @Autowired(required = false)
    private TContractorPreparationDao tContractorPreparationDao;

    @Autowired
    private ProcessDefinitionController processDefinitionController;

    @Autowired
    private WfTaskController wfTaskController;

    @Autowired
    private TContractorConditionReviewService tContractorConditionReviewService;

    @Autowired
    private TContractorProjectService tContractorProjectService;

    @Override
    public TContractorPreparation getByCtractorIdAndProjIdAndBizId(String contractorId, String projectId, String bizId) {
        QueryWrapper<TContractorPreparation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(TContractorPreparation.CONTRACTOR_ID, contractorId);
        queryWrapper.eq(TContractorPreparation.PROJ_ID, projectId);
        queryWrapper.eq(TContractorPreparation.BIZ_ID, bizId);
        queryWrapper.ne(TContractorPreparation.STATUS, StatusEnum.DELETE.getCode());
        return this.getOne(queryWrapper,false);
    }

    @Override
    public Page<ContractorPreparationDto> pageList(TContractorPreparationParam param) {
        Long page=
                StringHelper.isEmpty(param.getPage())? BizConstants.PAGE:Long.valueOf(param.getPage());
        Long limit=
                StringHelper.isEmpty(param.getLimit())?BizConstants.LIMIT:Long.valueOf(param.getLimit());
        Page<TContractorPreparation> resultPage  = new Page<>(page,limit);
        UserInfo loginUser = ContextUtils.getLoginUser();
        param.setOrgId(loginUser.getOrgId());
        return tContractorPreparationDao.pageList(resultPage, param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TContractorPreparation addEntity(TContractorPreparationParam addRequest) {
        String id = IdHelper.getId32bit();
        TContractorPreparation data= BeanHelper.beanToBean(addRequest,  TContractorPreparation.class);
        data.setId(id);
        data.setProcessStatus(ContractorProcessStatus.PENDING_SUBMISSION.getValue());
        String projId =  addRequest.getProjId();
        TContractorProject tContractorProject = tContractorProjectService.getById(projId);
        if(tContractorProject != null){
            data.setPlanStartTime( tContractorProject.getPlanStartTime());
            data.setPlanEndTime( tContractorProject.getPlanEndTime());
        }

        boolean result= save(data);
        if(result){
            return data;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProcessStatus(UpdateProcessStatusReq updateProcessStatusReq) throws Exception {
        if (StringHelper.isEmpty(updateProcessStatusReq.getId()) || StringHelper.isEmpty(updateProcessStatusReq.getProcessStatus())) {
            throw new BusinessException("请求参数有误，请联系管理员！");
        }
        this.lambdaUpdate().set(TContractorPreparation::getProcessStatus, updateProcessStatusReq.getProcessStatus())
                .set(StringUtils.isNotEmpty(updateProcessStatusReq.getProcessId()), TContractorPreparation::getProcessId, updateProcessStatusReq.getProcessId())
                .set(StringUtils.isNotEmpty(updateProcessStatusReq.getRejectOpinion()), TContractorPreparation::getRejectOpinion, updateProcessStatusReq.getRejectOpinion())
                .eq(TContractorPreparation::getId, updateProcessStatusReq.getId()).update();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void startProcess(TContractorPreparationParam updateRequest) {
        // 创建一个ProcessDefStartParam对象，并设置流程定义的key为"contractor"
        ProcessDefStartParam processDefStartParam = new ProcessDefStartParam("contractor");
        // 设置业务主键为updateRequest的id
        processDefStartParam.setBizKey(updateRequest.getId());
        // 创建一个Map对象，并设置type为"start"
        Map<String, Object> map = new HashMap<>();
        map.put("type", ContractorFlowTypeEnum.START.getCode());
        // 将Map对象设置到processDefStartParam的variables属性中
        processDefStartParam.setVariables(map);
        // 调用processDefinitionController的startProcessIns方法，并获取返回结果
        String result = processDefinitionController.startProcessIns(processDefStartParam).getData().getResult();
        // 创建一个TContractorBasicInfo对象
        TContractorPreparation tContractorPreparation = BeanHelper.beanToBean(updateRequest, TContractorPreparation.class);
        // 设置id为updateRequest的id
        tContractorPreparation.setId(updateRequest.getId());
        // 设置processId为result
        tContractorPreparation.setProcessId(result);
        // 设置processStatus为待审核
        tContractorPreparation.setProcessStatus(ContractorProcessStatus.UNDER_REVIEW.getValue());
        // 调用tContractorPreparationService的updateById方法，更新tContractorPreparation对象
        this.updateById(tContractorPreparation);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeProcess(TContractorPreparationParam updateRequest) {
        String processStatus = updateRequest.getProcessStatus();
        CompleteTask completeTask = new CompleteTask();
        completeTask.setBizId(updateRequest.getId());
        completeTask.setTaskId(updateRequest.getTaskId());
        // 创建一个vars参数
        Map<String, Object> vars = StringHelper.isEmpty(updateRequest.getVars()) ? new HashMap<>() : updateRequest.getVars();
        if(!vars.containsKey("processStatus")) {
            vars.put("processStatus", processStatus);
        }
        completeTask.setVars(vars);
        wfTaskController.completeTask(completeTask).getData().getResult();
        // 创建一个TContractorPreparation对象
        TContractorPreparation tContractorPreparation = new TContractorPreparation();
        // 设置id为updateRequest的id
        tContractorPreparation.setId(updateRequest.getId());
        // 设置processStatus
        tContractorPreparation.setProcessStatus(processStatus);
        if(ContractorProcessStatus.REJECTED.getValue().equals(processStatus)){
            String rejectOpinion = vars.get("rejectOpinion") == null ? "" : vars.get("rejectOpinion").toString();
            tContractorPreparation.setRejectOpinion(rejectOpinion);
        }
        // 调用tContractorPreparationService的updateById方法，更新tContractorPreparation对象
        boolean result = this.updateById(tContractorPreparation);
        // 如果是审批完成状态，则需要初始化初始化条件审查数据
        if(result && ContractorProcessStatus.APPROVED.getValue().equals(processStatus)){
            tContractorPreparation =  this.getById(updateRequest.getId());
            TContractorConditionReviewParam reviewParam = new TContractorConditionReviewParam();
            reviewParam.setContractorId(tContractorPreparation.getContractorId());
            reviewParam.setProjId(tContractorPreparation.getProjId());
            reviewParam.setBizId(tContractorPreparation.getBizId());
            reviewParam.setOrgId(tContractorPreparation.getOrgId());
            tContractorConditionReviewService.addEntity(reviewParam);
        }
    }
}
