package com.zt.plat.module.qms.business.reportdoc.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;
import com.zt.plat.framework.security.core.LoginUser;
import com.zt.plat.framework.security.core.util.SecurityFrameworkUtils;
import com.zt.plat.module.bpm.api.task.BpmProcessInstanceApi;
import com.zt.plat.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import com.zt.plat.module.qms.api.task.BMPCallbackInterface;
import com.zt.plat.module.qms.api.task.dto.QmsBpmDTO;
import com.zt.plat.module.qms.business.bus.dal.dataobject.BusinessAssayReportDataDO;
import com.zt.plat.module.qms.business.bus.service.BusinessAssayReportDataService;
import com.zt.plat.module.qms.business.reportdoc.controller.vo.*;
import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentDataDO;
import com.zt.plat.module.qms.business.reportdoc.dal.mapper.ReportDocumentMainMapper;
import com.zt.plat.module.qms.business.reportdoc.dal.dataobject.ReportDocumentMainDO;
import com.zt.plat.module.qms.core.constant.CommonConstant;
import com.zt.plat.module.qms.enums.ErrorCodeConstants;
import com.zt.plat.module.qms.enums.QmsBpmConstant;
import com.zt.plat.module.qms.enums.QmsCommonConstant;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static com.zt.plat.framework.common.pojo.CommonResult.error;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.*;
import static com.zt.plat.module.qms.enums.QmsBpmConstant.BPM_CALLBACK_BEAN_NAME;

/**
 * 检测报告业务 Service 实现类
 *
 * @author 后台管理
 */
@Service("reportDocumentMainService")
@Validated
public class ReportDocumentMainServiceImpl implements ReportDocumentMainService, BMPCallbackInterface {

    @Resource private ReportDocumentMainMapper reportDocumentMainMapper;
    @Resource private BusinessAssayReportDataService businessAssayReportDataService;
    @Resource private ReportDocumentDataService reportDocumentDataService;
    @Resource private BpmProcessInstanceApi bpmProcessInstanceApi;
    /***
     * 增加报表数据
     * 传入：报告id、 报表数据ids
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> execAddData(ReportDocumentMainSaveReqVO reqVO) {
        Long id = reqVO.getId();
        String businessAssayReportDataIds = reqVO.getBusinessAssayReportDataIds();
        List<Long> addReportDataIdList = new ArrayList<>();
        if(!ObjectUtils.isEmpty(businessAssayReportDataIds)){
            String[] split = businessAssayReportDataIds.split(",");
            for (String s : split) {
                Long aLong = Long.valueOf(s);
                addReportDataIdList.add(aLong);
            }
        }
        if(ObjectUtils.isEmpty(businessAssayReportDataIds) || addReportDataIdList.isEmpty())
            return error(REPORT_DOCUMENT_DATA_NOT_EXISTS.getCode(), "缺少businessAssayReportDataIds参数，请刷新后重试");
        List<ReportDocumentDataDO> savedDataList = reportDocumentDataService.listByMainDataId(id).getData();
        List<Long> hasIds = savedDataList.stream().map(ReportDocumentDataDO::getSourceId).toList();
        boolean isExist = false;
        for (Long addReportDataId : addReportDataIdList) {
            if(hasIds.contains(addReportDataId)){
                isExist = true;
                break;
            }
        }
        if(isExist)
            return error(REPORT_DOCUMENT_DATA_NOT_EXISTS.getCode(), "报表数据已在本报告使用，请勿重复添加");
        List<BusinessAssayReportDataDO> assayReportDataList = businessAssayReportDataService.listByIds(addReportDataIdList);
        List<ReportDocumentDataDO> insertList = new ArrayList<>();
        for (BusinessAssayReportDataDO assayReportData : assayReportDataList) {
            ReportDocumentDataDO reportDocumentDataDO = new ReportDocumentDataDO();
            reportDocumentDataDO.setMainId(id);
            reportDocumentDataDO.setSourceId(assayReportData.getId());
            reportDocumentDataDO.setDocumentContent(assayReportData.getAssayData());
            insertList.add(reportDocumentDataDO);
        }
        if(!insertList.isEmpty())
            reportDocumentDataService.insertBatch(insertList);

        ReportDocumentMainDO reportDocumentMainDO = reportDocumentMainMapper.selectById(id);
        updateCommonField(reportDocumentMainDO);

        return CommonResult.success("操作成功");
    }

    @Override
    public void updateCommonField(ReportDocumentMainDO reportDocumentMainDO) {
        if(reportDocumentMainDO == null)
            return;
        if(reportDocumentMainDO.getCancelFlag() == null || reportDocumentMainDO.getCancelFlag().equals("-1"))
            reportDocumentMainDO.setCancelFlag("0");
    }

    /***
     * 增加报表数据
     * 传入：报告id、 报告明细数据id
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<String> execRemoveData(ReportDocumentMainSaveReqVO reqVO) {
        Long id = reqVO.getId();
        String reportDocumentDataIds = reqVO.getReportDocumentDataIds();
        List<Long> reportDocumentDataIdsList = new ArrayList<>();
        if(!ObjectUtils.isEmpty(reportDocumentDataIds)){
            String[] split = reportDocumentDataIds.split(",");
            for (String s : split) {
                Long aLong = Long.valueOf(s);
                reportDocumentDataIdsList.add(aLong);
            }
        }
        if(ObjectUtils.isEmpty(reportDocumentDataIds) || reportDocumentDataIdsList.isEmpty())
            return error(REPORT_DOCUMENT_DATA_NOT_EXISTS, "缺少reportDocumentDataIds参数，请刷新后重试");
        return reportDocumentDataService.removeByMainIdAndDetailIds(id, reportDocumentDataIdsList);
    }

    @Override
    public ReportDocumentMainRespVO createReportDocumentMain(ReportDocumentMainSaveReqVO createReqVO) {
        // 插入
        ReportDocumentMainDO reportDocumentMain = BeanUtils.toBean(createReqVO, ReportDocumentMainDO.class);
        reportDocumentMainMapper.insert(reportDocumentMain);
        // 返回
        return BeanUtils.toBean(reportDocumentMain, ReportDocumentMainRespVO.class);
    }

    @Override
    public void updateReportDocumentMain(ReportDocumentMainSaveReqVO updateReqVO) {
        // 校验存在
        validateReportDocumentMainExists(updateReqVO.getId());
        // 更新
        ReportDocumentMainDO updateObj = BeanUtils.toBean(updateReqVO, ReportDocumentMainDO.class);
        reportDocumentMainMapper.updateById(updateObj);
    }

    @Override
    public void deleteReportDocumentMain(Long id) {
        // 校验存在
        validateReportDocumentMainExists(id);
        // 删除
        reportDocumentMainMapper.deleteById(id);
    }

    @Override
    public void deleteReportDocumentMainListByIds(List<Long> ids) {
        // 校验存在
        validateReportDocumentMainExists(ids);
        // 删除
        reportDocumentMainMapper.deleteByIds(ids);
    }

    private void validateReportDocumentMainExists(List<Long> ids) {
        List<ReportDocumentMainDO> list = reportDocumentMainMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(REPORT_DOCUMENT_MAIN_NOT_EXISTS);
        }
    }

    private void validateReportDocumentMainExists(Long id) {
        if (reportDocumentMainMapper.selectById(id) == null) {
            throw exception(REPORT_DOCUMENT_MAIN_NOT_EXISTS);
        }
    }

    @Override
    public ReportDocumentMainDO getReportDocumentMain(Long id) {
        return reportDocumentMainMapper.selectById(id);
    }

    @Override
    public PageResult<ReportDocumentMainDO> getReportDocumentMainPage(ReportDocumentMainPageReqVO pageReqVO) {
        return reportDocumentMainMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<ReportDocumentMainRespVO> createProcessInstance(ReportDocumentMainSaveReqVO param) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        //当前登录用户昵称
        String nickName = SecurityFrameworkUtils.getLoginUserNickname();
        Long id = param.getId();
        ReportDocumentMainDO entity = getReportDocumentMain(id);
        JSONObject formData = new JSONObject();
        if(entity.getFormData() != null)
            formData = JSONObject.parseObject(entity.getFormData());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        formData.put("mainId",  id);
        formData.put("applyUser",  nickName);
        formData.put("applyUserId",  loginUser.getId());
        formData.put("applyDepartment",  loginUser.getVisitDeptName());
        formData.put("applyDepartmentId",  loginUser.getVisitDeptId());
        formData.put("applyTime",  sdf.format(new Date()));
        Map<String, Object> variables = formData.toJavaObject(Map.class);
        variables.put(BPM_CALLBACK_BEAN_NAME, "reportDocumentMainService"); //流程回调时使用的service
        BpmProcessInstanceCreateReqDTO reqDTO = new BpmProcessInstanceCreateReqDTO();
        reqDTO.setBusinessKey(String.valueOf(id));
        reqDTO.setProcessDefinitionKey(entity.getFlowKey());
        reqDTO.setVariables(variables);
        CommonResult<String> result = bpmProcessInstanceApi.createProcessInstance(loginUser.getId(), reqDTO);
        if(!result.isSuccess()){
            throw exception0(ERROR_CODE_MODULE_COMMON, result.getMsg());
        }
        String wfInsId = result.getData();
        entity.setFlowInstanceId(wfInsId);
        entity.setFlowStatus(QmsCommonConstant.IN_PROGRESS);
        reportDocumentMainMapper.updateById(entity);
        ReportDocumentMainRespVO respVO = BeanUtils.toBean(entity, ReportDocumentMainRespVO.class);
        return CommonResult.success(respVO);
    }

    //流程回调
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
        JSONObject variables = reqDTO.getVariables();
        //流程状态  3-拒绝   1-通过  2-完成
        String PROCESS_STATUS = variables.getString(QmsBpmConstant.PROCESS_INSTANCE_VARIABLE_STATUS);
        String mainId = variables.getString("mainId");
        ReportDocumentMainDO entity = getReportDocumentMain(Long.valueOf(mainId));
        if("3".equals(PROCESS_STATUS)){
            //驳回
            entity.setFlowStatus(QmsCommonConstant.REJECT);
        }
        if("2".equals(PROCESS_STATUS)){
            //完成
            entity.setFlowStatus(QmsCommonConstant.COMPLETED);
        }
        //todo 处理意见和签名

        reportDocumentMainMapper.updateById(entity);
        JSONObject ret = new JSONObject();


        return CommonResult.success(ret);
    }
}
