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

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.biz.sys.dict.data.model.domain.SysDictData;
import com.testor.common.model.UpdateProcessStatusReq;
import com.testor.module.contractor.common.model.constant.ContractorProcessStatus;
import com.testor.module.contractor.enums.ConditionReviewContentEnum;
import com.testor.module.contractor.enums.ContractorFlowTypeEnum;
import com.testor.module.contractor.enums.GeneralStatusEnum;
import com.testor.module.contractor.manage.dao.TContractorConditionReviewDao;
import com.testor.module.contractor.manage.model.domain.TContractorConditionReview;
import com.testor.module.contractor.manage.model.domain.TContractorConditionReviewDetail;
import com.testor.module.contractor.manage.model.dto.ContractorConditionReviewDto;
import com.testor.module.contractor.manage.model.dto.TContractorConditionReviewParam;
import com.testor.module.contractor.manage.model.dto.TContractorSafetyBriefParam;
import com.testor.module.contractor.manage.service.TContractorConditionReviewDetailService;
import com.testor.module.contractor.manage.service.TContractorConditionReviewService;
import com.testor.module.contractor.manage.service.TContractorSafetyBriefService;
import com.testor.module.sys.service.NewSysDictDataService;
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.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 承包商管理-条件审查Service业务层处理
 * 
 * @author testor-framework
 * @date 2024-11-26 10:39:58
 */
@Service
public class TContractorConditionReviewServiceImpl extends SuperServiceImpl<TContractorConditionReviewDao, TContractorConditionReview> implements TContractorConditionReviewService
{
    @Autowired(required = false)
    private TContractorConditionReviewDao tContractorConditionReviewDao;

    @Autowired
    private NewSysDictDataService newSysDictDataService;

    @Autowired
    private TContractorConditionReviewDetailService tContractorConditionReviewDetailService;

    @Autowired
    private ProcessDefinitionController processDefinitionController;

    @Autowired
    private WfTaskController wfTaskController;

    @Autowired
    private TContractorSafetyBriefService tContractorSafetyBriefService;

    @Override
    public Page<ContractorConditionReviewDto> pageList(TContractorConditionReviewParam 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<TContractorConditionReview> resultPage  = new Page<>(page,limit);
        UserInfo loginUser = ContextUtils.getLoginUser();
        param.setOrgId(loginUser.getOrgId());
        return tContractorConditionReviewDao.pageList(resultPage, param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TContractorConditionReview addEntity(TContractorConditionReviewParam addRequest) {
        String id = IdHelper.getId32bit();
        TContractorConditionReview data= BeanHelper.beanToBean(addRequest,  TContractorConditionReview.class);
        data.setId(id);
        data.setProcessStatus(ContractorProcessStatus.PENDING_SUBMISSION.getValue());
        boolean result= save(data);
        if(result){
            // 初始化条件审查内容明细表数据
            List<SysDictData> dictDataList = newSysDictDataService.getDictByType("contractor_condition_review_content");
            List<TContractorConditionReviewDetail> detailList = dictDataList.stream().map(dict ->{
                TContractorConditionReviewDetail detail = new TContractorConditionReviewDetail();
                detail.setReviewId(data.getId());
                detail.setCode(dict.getDictKey());
                detail.setContent(dict.getDictValue());
                detail.setTreeSort(dict.getTreeSort());
                String reviewStatus = GeneralStatusEnum.UNPASSED.getCode();
                // 如果审查内容是“C01-合同信息”或者“C02-承包商资质”，则审查状态默认为通过
                if(ConditionReviewContentEnum.C01.getCode().equals(dict.getDictKey()) || ConditionReviewContentEnum.C02.getCode().equals(dict.getDictKey())){
                    reviewStatus = GeneralStatusEnum.PASSED.getCode();
                }
                detail.setReviewStatus(reviewStatus);
                return detail;
            }).collect(Collectors.toList());
            tContractorConditionReviewDetailService.saveBatch(detailList);
            return data;
        }
        return null;
    }

    @Override
    public boolean updateEntity(TContractorConditionReviewParam updateRequest) {
        TContractorConditionReview data=BeanHelper.beanToBean(updateRequest, TContractorConditionReview.class);
        boolean result= this.updateById(data);
        if(result){
            List<TContractorConditionReviewDetail> detailList = updateRequest.getReviewDetails();
            if(StringHelper.isNotEmpty(detailList)){
                tContractorConditionReviewDetailService.updateBatchById(detailList);
            }
        }
        return result;
    }

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

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeProcess(TContractorConditionReviewParam 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();
        // 创建一个TContractorConditionReview对象
        TContractorConditionReview tContractorConditionReview = new TContractorConditionReview();
        // 设置id为updateRequest的id
        tContractorConditionReview.setId(updateRequest.getId());
        // 设置processStatus
        tContractorConditionReview.setProcessStatus(processStatus);
        if(ContractorProcessStatus.REJECTED.getValue().equals(processStatus)){
            String rejectOpinion = vars.get("rejectOpinion") == null ? "" : vars.get("rejectOpinion").toString();
            tContractorConditionReview.setRejectOpinion(rejectOpinion);
        }
        // 调用tContractorConditionReviewService的updateById方法，更新tContractorConditionReview对象
        boolean result = this.updateById(tContractorConditionReview);
        if(result && ContractorProcessStatus.APPROVED.getValue().equals(processStatus)){
            tContractorConditionReview = this.getById(updateRequest.getId());
            TContractorSafetyBriefParam safetyBriefParam = new TContractorSafetyBriefParam();
            safetyBriefParam.setContractorId(tContractorConditionReview.getContractorId());
            safetyBriefParam.setProjId(tContractorConditionReview.getProjId());
            safetyBriefParam.setBizId(tContractorConditionReview.getBizId());
            safetyBriefParam.setOrgId(tContractorConditionReview.getOrgId());
            tContractorSafetyBriefService.addEntity(safetyBriefParam);
        }
    }
}
