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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.common.util.BeanConverUtil;
import com.testor.module.contractor.common.model.constant.ContractorProcessStatus;
import com.testor.module.contractor.enums.*;
import com.testor.module.contractor.ledger.model.domain.TContractorMaterial;
import com.testor.module.contractor.ledger.model.domain.TContractorProtectiveEquipment;
import com.testor.module.contractor.ledger.model.domain.TContractorTools;
import com.testor.module.contractor.ledger.service.TContractorMaterialService;
import com.testor.module.contractor.ledger.service.TContractorProtectiveEquipmentService;
import com.testor.module.contractor.ledger.service.TContractorToolsService;
import com.testor.module.contractor.manage.dao.TContractorDailyPlanDao;
import com.testor.module.contractor.manage.model.domain.*;
import com.testor.module.contractor.manage.model.dto.TContractorDailyPlanDTO;
import com.testor.module.contractor.manage.model.dto.TContractorDailyPlanParam;
import com.testor.module.contractor.manage.service.*;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
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.stereotype.Service;
import com.tongtech.tfw.backend.common.models.supers.SuperServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
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-28 15:21:05
 */
@Service
public class TContractorDailyPlanServiceImpl extends SuperServiceImpl<TContractorDailyPlanDao, TContractorDailyPlan> implements TContractorDailyPlanService
{
    @Autowired(required = false)
    private TContractorDailyPlanDao tContractorDailyPlanDao;

    @Autowired
    private TContractorDailyPlanContentService tContractorDailyPlanContentService;

    @Autowired
    private ProcessDefinitionController processDefinitionController;

    @Autowired
    private WfTaskController wfTaskController;

    @Autowired
    private TContractorDailyPlanMaterialService tContractorDailyPlanMaterialService;

    @Autowired
    private TContractorDailyPlanProtectiveService tContractorDailyPlanProtectiveService;

    @Autowired
    private TContractorDailyPlanToolsService tContractorDailyPlanToolsService;

    @Autowired
    private TContractorDailyPlanChangeService tContractorDailyPlanChangeService;

    @Autowired
    private TContractorDailyPlanStopRestartWorkService tContractorDailyPlanStopRestartWorkService;

    @Autowired
    private TContractorMaterialService tContractorMaterialService;

    @Autowired
    private TContractorProtectiveEquipmentService tContractorProtectiveEquipmentService;

    @Autowired
    private TContractorToolsService tContractorToolsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TContractorDailyPlan addEntity(TContractorDailyPlanDTO addRequest) {
        tContractorDailyPlanContentService.remove(new LambdaQueryWrapper<TContractorDailyPlanContent>().eq(TContractorDailyPlanContent::getPlanId, addRequest.getId()));
        tContractorDailyPlanMaterialService.remove(new LambdaQueryWrapper<TContractorDailyPlanMaterial>().eq(TContractorDailyPlanMaterial::getPlanId, addRequest.getId()));
        tContractorDailyPlanProtectiveService.remove(new LambdaQueryWrapper<TContractorDailyPlanProtective>().eq(TContractorDailyPlanProtective::getPlanId, addRequest.getId()));
        tContractorDailyPlanToolsService.remove(new LambdaQueryWrapper<TContractorDailyPlanTools>().eq(TContractorDailyPlanTools::getPlanId, addRequest.getId()));
        TContractorDailyPlan data= BeanHelper.beanToBean(addRequest,  TContractorDailyPlan.class);
        data.setProcessStatus(ProcessStatusEnum.WAITING_AUDIT.getValue());
        data.setWorkStatus("0");
        this.saveOrUpdate(data);
        String id = data.getId();
        List<TContractorDailyPlanContent> safetyTechnologyManagement = addRequest.getSafetyTechnologyManagement();
        if (safetyTechnologyManagement != null) {
            for (TContractorDailyPlanContent tContractorDailyPlanContent : safetyTechnologyManagement) {
                tContractorDailyPlanContent.setId(IdHelper.getId32bit());
                tContractorDailyPlanContent.setPlanId(id);
                tContractorDailyPlanContentService.save(tContractorDailyPlanContent);
            }
        }
        List<TContractorDailyPlanContent> specialOperationsManagementList = addRequest.getSpecialOperationsManagementList();
        if (specialOperationsManagementList != null) {
            for (TContractorDailyPlanContent tContractorDailyPlanContent : specialOperationsManagementList) {
                tContractorDailyPlanContent.setId(IdHelper.getId32bit());
                tContractorDailyPlanContent.setPlanId(id);
                tContractorDailyPlanContentService.save(tContractorDailyPlanContent);
            }
        }

        String[] materialIds = addRequest.getAllowMaterialId().split(",");
        if (materialIds != null) {
            for (String materialId : materialIds) {
                TContractorDailyPlanMaterial tContractorDailyPlanMaterial = new TContractorDailyPlanMaterial();
                tContractorDailyPlanMaterial.setId(IdHelper.getId32bit());
                tContractorDailyPlanMaterial.setPlanId(id);
                tContractorDailyPlanMaterial.setMaterialId(materialId);
                tContractorDailyPlanMaterialService.save(tContractorDailyPlanMaterial);
            }
        }
        String[] protectiveIds = addRequest.getAllowProtectiveId().split(",");
        if (protectiveIds != null) {
            for (String protectiveId : protectiveIds) {
                TContractorDailyPlanProtective tContractorDailyPlanProtective = new TContractorDailyPlanProtective();
                tContractorDailyPlanProtective.setId(IdHelper.getId32bit());
                tContractorDailyPlanProtective.setPlanId(id);
                tContractorDailyPlanProtective.setProtectiveId(protectiveId);
                tContractorDailyPlanProtectiveService.save(tContractorDailyPlanProtective);
            }
        }
        String[] toolsIds = addRequest.getAllowToolsId().split(",");
        if (toolsIds != null) {
            for (String toolsId : toolsIds) {
                TContractorDailyPlanTools tContractorDailyPlanTools = new TContractorDailyPlanTools();
                tContractorDailyPlanTools.setId(IdHelper.getId32bit());
                tContractorDailyPlanTools.setPlanId(id);
                tContractorDailyPlanTools.setToolsId(toolsId);
                tContractorDailyPlanToolsService.save(tContractorDailyPlanTools);
            }
        }
        return data;
    }

    @Override
    public Page<TContractorDailyPlanDTO> listEntity(TContractorDailyPlanParam 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<TContractorDailyPlanDTO> resultPage=new Page<>(page,limit);
        return tContractorDailyPlanDao.listEntity(resultPage,param);
    }

    @Override
    public void submit(TContractorDailyPlanDTO tContractorDailyPlanDTO) {
        ProcessDefStartParam processDefStartParam = new ProcessDefStartParam("contractor");
        processDefStartParam.setBizKey(tContractorDailyPlanDTO.getId());
        String approvalType = tContractorDailyPlanDTO.getApprovalType();
        Map<String, Object> map = new HashMap<>();
        map.put("type", approvalType);
        if (tContractorDailyPlanDTO.getMap() != null) {
            map.putAll(tContractorDailyPlanDTO.getMap());
        }
        processDefStartParam.setVariables(map);
        String result = processDefinitionController.startProcessIns(processDefStartParam).getData().getResult();
        TContractorDailyPlan tContractorDailyPlan = BeanConverUtil.conver(tContractorDailyPlanDTO, TContractorDailyPlan.class);
        if (approvalType.equals(ContractorFlowTypeEnum.PLAN_APPROVALS.getCode())) {
            tContractorDailyPlan.setProcessId(result);
            tContractorDailyPlan.setProcessStatus(ContractorProcessStatus.UNDER_REVIEW.getValue());
        }else if (approvalType.equals(ContractorFlowTypeEnum.CHANGE.getCode())) {
            tContractorDailyPlan.setChangeProcessId(result);
            tContractorDailyPlan.setChangeProcessStatus(ContractorProcessStatus.UNDER_REVIEW.getValue());
        }else if (approvalType.equals(ContractorFlowTypeEnum.STOPPAGES.getCode()) || approvalType.equals(ContractorFlowTypeEnum.RETURN_WORK.getCode())) {
            tContractorDailyPlan.setStopStartProcessId(result);
            tContractorDailyPlan.setStopStartProcessStatus(ContractorProcessStatus.UNDER_REVIEW.getValue());
        }
        this.updateById(tContractorDailyPlan);
    }

    @Override
    public void completeProcess(TContractorDailyPlanDTO tContractorDailyPlanDTO) {
        TContractorDailyPlan tContractorDailyPlan = this.getById(tContractorDailyPlanDTO.getId());
        String processStatus = tContractorDailyPlanDTO.getProcessStatus();
        CompleteTask completeTask = new CompleteTask();
        completeTask.setBizId(tContractorDailyPlanDTO.getId());
        completeTask.setTaskId(tContractorDailyPlanDTO.getTaskId());
        Map<String, Object> map = new HashMap<>();
        map.put("processStatus", processStatus);
        if (tContractorDailyPlanDTO.getMap() != null) {
            map.putAll(tContractorDailyPlanDTO.getMap());
        }
        completeTask.setVars(map);
        wfTaskController.completeTask(completeTask).getData().getResult();
        String approvalType = tContractorDailyPlanDTO.getApprovalType();
        if (approvalType.equals(ContractorFlowTypeEnum.PLAN_APPROVALS.getCode())) {
            tContractorDailyPlan.setProcessStatus(processStatus);
        }else if (approvalType.equals(ContractorFlowTypeEnum.CHANGE.getCode())) {
            tContractorDailyPlan.setChangeProcessStatus(processStatus);
        }else if (approvalType.equals(ContractorFlowTypeEnum.STOPPAGES.getCode())) {
            tContractorDailyPlan.setStopStartProcessStatus(processStatus);
            if (ContractorProcessStatus.APPROVED.getValue().equals(processStatus)) {
                tContractorDailyPlan.setWorkStatus(DailyPlanStatusEnum.STOPPAGES.getValue());
            }
        }else if (approvalType.equals(ContractorFlowTypeEnum.RETURN_WORK.getCode())) {
            tContractorDailyPlan.setStopStartProcessStatus(processStatus);
            //如果是5是审核中
            if ("4".equals(processStatus)) {
                tContractorDailyPlan.setWorkStatus(DailyPlanStatusEnum.JOB.getValue());
                tContractorDailyPlan.setStopStartProcessStatus(ProcessStatusEnum.AUDIT_PASS.getValue());
            }else if ("5".equals(processStatus)) {
                tContractorDailyPlan.setStopStartProcessStatus(ProcessStatusEnum.DISMISSED.getValue());
            }else {
                tContractorDailyPlan.setStopStartProcessStatus(ProcessStatusEnum.UNDER_REVIEW.getValue());
            }
        }
        this.updateById(tContractorDailyPlan);
        
    }

    @Override
    public TContractorDailyPlanDTO getDetails(String id) {
        // Step 1: 查询TContractorDailyPlan对象并转换为DTO
        TContractorDailyPlan data = this.getById(id);
        TContractorDailyPlanDTO tContractorDailyPlanDTO = BeanConverUtil.conver(data, TContractorDailyPlanDTO.class);

        // Step 2: 获取特殊作业管理和安全科技管理列表
        loadSpecialOperationsManagement(tContractorDailyPlanDTO, id);
        loadSafetyTechnologyManagement(tContractorDailyPlanDTO, id);

        // Step 3: 获取计划变更和工作停复工信息
        loadPlanChangeInfo(tContractorDailyPlanDTO, id);

        // Step 4: 获取防护设备和工具、物料信息并拼接为逗号分隔的字符串
        loadProtectiveEquipment(tContractorDailyPlanDTO, id);
        loadTools(tContractorDailyPlanDTO, id);
        loadMaterials(tContractorDailyPlanDTO, id);

        return tContractorDailyPlanDTO;
    }

    // 加载特殊作业管理
    private void loadSpecialOperationsManagement(TContractorDailyPlanDTO dto, String id) {
        List<TContractorDailyPlanContent> specialOperationsManagementList =
                tContractorDailyPlanContentService.getByIdAndType(id, DailyPlanContentEnum.SPECIAL_WORK_MANAGEMENT.getValue());
        dto.setSpecialOperationsManagementList(specialOperationsManagementList);
    }

    // 加载安全科技管理
    private void loadSafetyTechnologyManagement(TContractorDailyPlanDTO dto, String id) {
        List<TContractorDailyPlanContent> safetyTechnologyManagement =
                tContractorDailyPlanContentService.getByIdAndType(id, DailyPlanContentEnum.PENDING_SUBMISSION.getValue());
        dto.setSafetyTechnologyManagement(safetyTechnologyManagement);
    }

    // 加载计划变更和工作停复工信息
    private void loadPlanChangeInfo(TContractorDailyPlanDTO dto, String id) {
        TContractorDailyPlanChange tContractorDailyPlanChange =
                tContractorDailyPlanChangeService.getByPlanId(id);
        dto.setTContractorDailyPlanChange(tContractorDailyPlanChange);

        TContractorDailyPlanStopRestartWork dailyPlanStopWork =
                tContractorDailyPlanStopRestartWorkService.getOne(new LambdaQueryWrapper<TContractorDailyPlanStopRestartWork>()
                        .eq(TContractorDailyPlanStopRestartWork::getPlanId, id)
                        .eq(TContractorDailyPlanStopRestartWork::getType, DailyPlanStopRestartWorkEnum.STOPPAGES.getValue()));
        dto.setTContractorDailyPlanStopWork(dailyPlanStopWork);

        TContractorDailyPlanStopRestartWork dailyPlanRestartWork =
                tContractorDailyPlanStopRestartWorkService.getOne(new LambdaQueryWrapper<TContractorDailyPlanStopRestartWork>()
                        .eq(TContractorDailyPlanStopRestartWork::getPlanId, id)
                        .eq(TContractorDailyPlanStopRestartWork::getType, DailyPlanStopRestartWorkEnum.RETURN_TO_WORK.getValue()));
        dto.setTContractorDailyPlanRestartWork(dailyPlanRestartWork);
    }

    // 加载防护设备并拼接
    private void loadProtectiveEquipment(TContractorDailyPlanDTO dto, String id) {
        List<TContractorDailyPlanProtective> tContractorDailyPlanProtectives =
                tContractorDailyPlanProtectiveService.list(new LambdaQueryWrapper<TContractorDailyPlanProtective>()
                        .eq(TContractorDailyPlanProtective::getPlanId, id));

        List<String> protectiveIds = tContractorDailyPlanProtectives.stream()
                .map(TContractorDailyPlanProtective::getProtectiveId)
                .collect(Collectors.toList());

        if (!protectiveIds.isEmpty()) {
            /*List<TContractorProtectiveEquipment> protectives =
                    tContractorProtectiveEquipmentService.list(new LambdaQueryWrapper<TContractorProtectiveEquipment>()
                            .in(TContractorProtectiveEquipment::getId, protectiveIds));
            String allowProtectiveIds = protectives.stream()
                    .map(TContractorProtectiveEquipment::getName)
                    .collect(Collectors.joining(","));*/

            dto.setAllowProtectiveId(StringUtils.join(protectiveIds,","));
        }
    }

    // 加载工具并拼接
    private void loadTools(TContractorDailyPlanDTO dto, String id) {
        List<TContractorDailyPlanTools> tContractorDailyPlanTools =
                tContractorDailyPlanToolsService.list(new LambdaQueryWrapper<TContractorDailyPlanTools>()
                        .eq(TContractorDailyPlanTools::getPlanId, id));

        List<String> toolsIds = tContractorDailyPlanTools.stream()
                .map(TContractorDailyPlanTools::getToolsId)
                .collect(Collectors.toList());

        if (!toolsIds.isEmpty()) {
            /*List<TContractorTools> tContractorTools =
                    tContractorToolsService.list(new LambdaQueryWrapper<TContractorTools>()
                            .in(TContractorTools::getId, toolsIds));
            String allowToolsId = tContractorTools.stream()
                    .map(TContractorTools::getToolsName)
                    .collect(Collectors.joining(","));*/

            dto.setAllowToolsId(StringUtils.join(toolsIds, ","));
        }
    }

    // 加载物料并拼接
    private void loadMaterials(TContractorDailyPlanDTO dto, String id) {
        List<TContractorDailyPlanMaterial> tContractorDailyPlanMaterials =
                tContractorDailyPlanMaterialService.list(new LambdaQueryWrapper<TContractorDailyPlanMaterial>()
                        .eq(TContractorDailyPlanMaterial::getPlanId, id));

        List<String> materialIds = tContractorDailyPlanMaterials.stream()
                .map(TContractorDailyPlanMaterial::getMaterialId)
                .collect(Collectors.toList());

        if (!materialIds.isEmpty()) {
            /*String allowMaterialId = tContractorMaterialService.list(new LambdaQueryWrapper<TContractorMaterial>()
                            .in(TContractorMaterial::getId, materialIds))
                    .stream()
                    .map(TContractorMaterial::getName)
                    .collect(Collectors.joining(","));*/
            dto.setAllowMaterialId(StringUtils.join(materialIds, ","));
        }
    }

}
