package com.zt.plat.module.qms.common.data.service;

import cn.hutool.core.collection.CollUtil;
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.common.data.controller.vo.DataFormPageReqVO;
import com.zt.plat.module.qms.common.data.controller.vo.DataFormRespVO;
import com.zt.plat.module.qms.common.data.controller.vo.DataFormSaveReqVO;
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.common.data.dal.dataobject.DataCollectionDO;
import com.zt.plat.module.qms.common.data.dal.dataobject.DataFormDO;
import com.zt.plat.module.qms.common.data.dal.mapper.DataFormMapper;
import com.zt.plat.module.qms.enums.ErrorCodeConstants;
import com.zt.plat.module.qms.enums.QmsBpmConstant;
import com.alibaba.fastjson.JSONObject;
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.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.module.qms.enums.ErrorCodeConstants.DATA_FORM_NOT_EXISTS;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.ERROR_CODE_MODULE_COMMON;
import static com.zt.plat.module.qms.enums.QmsBpmConstant.BPM_CALLBACK_BEAN_NAME;

/**
 * 通用数据 Service 实现类
 *
 * @author 后台管理
 */
@Service("dataFormService")
@Validated
public class DataFormServiceImpl implements DataFormService, BMPCallbackInterface {

    @Resource private DataFormMapper dataFormMapper;
    @Resource private DataCollectionService dataCollectionService;
    @Resource private BpmProcessInstanceApi bpmProcessInstanceApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataFormRespVO createProcessInstance(DataFormSaveReqVO entity) {
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        Long id = entity.getId();
        DataFormDO dataForm = getDataForm(id);
        Long dataCollectionId = dataForm.getDataCollectionId();
        DataCollectionDO dataCollection = dataCollectionService.getDataCollection(dataCollectionId);
        if(dataCollection == null)
            throw exception(ErrorCodeConstants.DATA_FORM_EMPTY_COLLECTION_ID);
        if(ObjectUtils.isEmpty(dataCollection.getFlowKey()))
            throw exception(ErrorCodeConstants.DATA_COLLECTION_EMPTY_WF_KEY);
        JSONObject formData = new JSONObject();
        if(dataForm.getFormData() != null)
            formData = JSONObject.parseObject(dataForm.getFormData());
        formData.put("mainId",  id);
        formData.put("applyUser",  dataForm.getApplyUser());
        formData.put("applyUserId",  dataForm.getApplyUserId());
        formData.put("applyDepartment",  dataForm.getApplyDepartment());
        formData.put("applyDepartmentId",  dataForm.getApplyDepartmentId());
        formData.put("applyTime",  dataForm.getApplyTime());
        Map<String, Object> variables = formData.toJavaObject(Map.class);
        variables.put(BPM_CALLBACK_BEAN_NAME, "dataFormService");
        BpmProcessInstanceCreateReqDTO reqDTO = new BpmProcessInstanceCreateReqDTO();
        reqDTO.setBusinessKey(String.valueOf(id));
        reqDTO.setProcessDefinitionKey(dataCollection.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();
        dataForm.setFlowInstanceId(wfInsId);
        dataFormMapper.updateById(dataForm);
        return BeanUtils.toBean(dataForm, DataFormRespVO.class);
    }

    @Override
    public DataFormRespVO createDataForm(DataFormSaveReqVO createReqVO) {
        // 插入
        DataFormDO dataForm = BeanUtils.toBean(createReqVO, DataFormDO.class);
        dataFormMapper.insert(dataForm);
        // 返回
        return BeanUtils.toBean(dataForm, DataFormRespVO.class);
    }

    @Override
    public void updateDataForm(DataFormSaveReqVO updateReqVO) {
        // 校验存在
        validateDataFormExists(updateReqVO.getId());
        // 更新
        DataFormDO updateObj = BeanUtils.toBean(updateReqVO, DataFormDO.class);
        dataFormMapper.updateById(updateObj);
    }

    @Override
    public void deleteDataForm(Long id) {
        // 校验存在
        validateDataFormExists(id);
        // 删除
        dataFormMapper.deleteById(id);
    }

    @Override
        public void deleteDataFormListByIds(List<Long> ids) {
        // 校验存在
        validateDataFormExists(ids);
        // 删除
        dataFormMapper.deleteByIds(ids);
        }

    private void validateDataFormExists(List<Long> ids) {
        List<DataFormDO> list = dataFormMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(DATA_FORM_NOT_EXISTS);
        }
    }

    private void validateDataFormExists(Long id) {
        if (dataFormMapper.selectById(id) == null) {
            throw exception(DATA_FORM_NOT_EXISTS);
        }
    }

    @Override
    public DataFormDO getDataForm(Long id) {
        return dataFormMapper.selectById(id);
    }

    @Override
    public PageResult<DataFormDO> getDataFormPage(DataFormPageReqVO pageReqVO) {
        return dataFormMapper.selectPage(pageReqVO);
    }

    @Override
    public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
        JSONObject variables = reqDTO.getVariables();
        String PROCESS_STATUS = variables.getString(QmsBpmConstant.PROCESS_INSTANCE_VARIABLE_STATUS);   //todo 流程状态  3-拒绝

        JSONObject ret = new JSONObject();




        return CommonResult.success(ret);
    }
}