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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.testor.module.contractor.common.model.constant.ContractorProcessStatus;
import com.testor.module.contractor.common.model.domain.TContractorLedgerProject;
import com.testor.module.contractor.common.service.TContractorLedgerProjectService;
import com.testor.module.contractor.enums.ContractorFlowTypeEnum;
import com.testor.module.contractor.manage.dao.TContractorBasicInfoDao;
import com.testor.module.contractor.manage.model.domain.TContractorAllow;
import com.testor.module.contractor.manage.model.domain.TContractorBasicInfo;
import com.testor.module.contractor.manage.model.dto.ContractorInfoDTO;
import com.testor.module.contractor.manage.model.dto.TContractorBasicInfoParam;
import com.testor.module.contractor.manage.service.TContractorAllowService;
import com.testor.module.contractor.manage.service.TContractorBasicInfoService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.exception.BusinessException;
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 lombok.extern.slf4j.Slf4j;
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-22 21:03:04
 */
@Service
@Slf4j
public class TContractorBasicInfoServiceImpl extends SuperServiceImpl<TContractorBasicInfoDao, TContractorBasicInfo> implements TContractorBasicInfoService
{
    @Autowired(required = false)
    private TContractorBasicInfoDao tContractorBasicInfoDao;

    @Autowired
    private TContractorLedgerProjectService tContractorLedgerProjectService;


    @Autowired
    private ProcessDefinitionController processDefinitionController;

    @Autowired
    private WfTaskController wfTaskController;

    @Autowired
    private TContractorAllowService tContractorAllowService;

    @Override
    public Page<ContractorInfoDTO> pageList(TContractorBasicInfoParam 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<TContractorBasicInfo> resultPage=new Page<>(page,limit);

        return tContractorBasicInfoDao.pageList(resultPage,param);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TContractorBasicInfo addEntity(TContractorBasicInfoParam addRequest) {
        String id = IdHelper.getId32bit();
        TContractorBasicInfo data= BeanHelper.beanToBean(addRequest,  TContractorBasicInfo.class);
        data.setId(id);
        data.setProcessStatus(ContractorProcessStatus.PENDING_SUBMISSION.getValue());
        boolean save = this.save(data);
        if (save) {
            List<String> projectIds = addRequest.getProjectIds();
            for (String projectId : projectIds) {
                TContractorLedgerProject tContractorLedgerProject = new TContractorLedgerProject();
                tContractorLedgerProject.setContractorId(addRequest.getContractorId());
                tContractorLedgerProject.setProjectId(projectId);
                tContractorLedgerProject.setBizId(id);
                tContractorLedgerProjectService.save(tContractorLedgerProject);
            }
        }
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TContractorBasicInfo updateEntity(TContractorBasicInfoParam update) {
        // 将update对象转换为TContractorBasicInfo对象
        TContractorBasicInfo data= BeanHelper.beanToBean(update,  TContractorBasicInfo.class);
        // 更新TContractorBasicInfo对象
        boolean b = this.updateById(data);
        // 如果更新成功
        if (b) {
            // 删除TContractorLedgerProject表中bizId等于update.getId()的记录
            tContractorLedgerProjectService.remove(Wrappers.<TContractorLedgerProject>lambdaQuery().eq(TContractorLedgerProject::getBizId, update.getId()));
            // 获取update对象中的projectIds
            List<String> projectIds = update.getProjectIds();
            // 遍历projectIds
            for (String projectId : projectIds) {
                // 创建TContractorLedgerProject对象
                TContractorLedgerProject tContractorLedgerProject = new TContractorLedgerProject();
                // 设置TContractorLedgerProject对象的contractorId
                tContractorLedgerProject.setContractorId(update.getContractorId());
                // 设置TContractorLedgerProject对象的projectId
                tContractorLedgerProject.setProjectId(projectId);
                // 设置TContractorLedgerProject对象的bizId
                tContractorLedgerProject.setBizId(update.getId());
                // 保存TContractorLedgerProject对象
                tContractorLedgerProjectService.save(tContractorLedgerProject);
            }
        }
        return data;
    }

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeProcess(TContractorBasicInfoParam updateRequest) {
        TContractorBasicInfo tContractorBasicInfo = this.getById(updateRequest.getId());
        String processStatus = updateRequest.getProcessStatus();
        CompleteTask completeTask = new CompleteTask();
        completeTask.setBizId(updateRequest.getId());
        completeTask.setTaskId(updateRequest.getTaskId());
        Map<String, Object> map = new HashMap<>();
        map.put("processStatus", processStatus);
        if (updateRequest.getMap() != null){
            map.putAll(updateRequest.getMap());
        }
        completeTask.setVars(map);
        wfTaskController.completeTask(completeTask).getData().getResult();
        // 创建一个TContractorBasicInfo对象
        tContractorBasicInfo.setProcessStatus(processStatus);
        // 调用tContractorBasicInfoService的updateById方法，更新tContractorBasicInfo对象
        this.updateById(tContractorBasicInfo);
        //如果审核状态为通过推送数据到准入管理
        if (processStatus.equals(ContractorProcessStatus.APPROVED.getValue())){
            // 根据tContractorBasicInfo的processId查询TContractorLedgerProject表，获取projectIds
            List<String> projectIds = tContractorLedgerProjectService.list(new LambdaQueryWrapper<TContractorLedgerProject>().eq(TContractorLedgerProject::getBizId,updateRequest.getId()))
                    .stream().map(TContractorLedgerProject::getProjectId).collect(Collectors.toList());
            // 遍历projectIds
            for (String projectId : projectIds) {
                TContractorAllow tContractorAllow = new TContractorAllow();
                tContractorAllow.setBizId(updateRequest.getId());
                tContractorAllow.setContractorId(tContractorBasicInfo.getContractorId());
                tContractorAllow.setProjId(projectId);
                tContractorAllow.setOrgId(tContractorBasicInfo.getOrgId());
                tContractorAllow.setCreateBy(tContractorBasicInfo.getCreateBy());
                tContractorAllow.setUpdateBy(tContractorBasicInfo.getUpdateBy());
                tContractorAllowService.save(tContractorAllow);
            }
        }
    }


    /**
     * 回退基本信息状态为待提交
     */
    @Transactional(rollbackFor = Exception.class)
    public void rollbackToPending(String bizId) throws BusinessException {
        TContractorBasicInfo basicInfo = this.getById(bizId);
        if (basicInfo == null) {
            throw new BusinessException("基本信息数据不存在");
        }

        // 验证当前状态是否可以回退（只有已审批通过的状态可以回退）
        if (!ContractorProcessStatus.APPROVED.getValue().equals(basicInfo.getProcessStatus())) {
            throw new BusinessException("当前状态无法回退，只有已审批通过的状态可以回退");
        }

        // 更新状态为待提交
        basicInfo.setProcessStatus("0"); // 待提交状态值

        this.updateById(basicInfo);

        log.info("基本信息状态回退成功，业务ID: {}, 回退原因: {}", bizId);
    }

    /**
     * 检查是否可以删除准入管理（状态验证）
     */
    public boolean canDeleteAdmission(String bizId) {
        TContractorBasicInfo basicInfo = this.getById(bizId);
        if (basicInfo == null) {
            return false;
        }

        // 只有已审批通过的状态才允许删除准入管理
        return ContractorProcessStatus.APPROVED.getValue().equals(basicInfo.getProcessStatus());
    }

}
