package com.docus.server.service.impl;

import com.docus.core.util.DateUtil;
import com.docus.core.util.ListUtils;
import com.docus.core.util.json.JSON;
import com.docus.core.util.property.Setters;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.infrastructure.web.exception.ApiException;
import com.docus.infrastructure.web.exception.ExceptionCode;
import com.docus.infrastructure.web.request.SearchDTO;
import com.docus.infrastructure.web.response.PageResult;
import com.docus.server.convert.SchCollectRecordConvert;
import com.docus.server.convert.SchCollectRecordRetryLogConvert;
import com.docus.server.dto.scheduling.management.schcollector.task.ReportDownTwoDTO;
import com.docus.server.dto.scheduling.management.schcollectrecord.AddSchCollectRecordDTO;
import com.docus.server.dto.scheduling.management.schcollectrecord.DeleteSchCollectRecordDTO;
import com.docus.server.dto.scheduling.management.schcollectrecord.EditSchCollectRecordDTO;
import com.docus.server.dto.scheduling.management.schterminator.NettyTerminatorDTO;
import com.docus.server.entity.scheduling.management.SchCollectRecord;
import com.docus.server.entity.scheduling.management.SchCollectRecordRetryLog;
import com.docus.server.entity.scheduling.management.SchSystemParams;
import com.docus.server.enums.RetryTaskEnum;
import com.docus.server.enums.SubStateEnum;
import com.docus.server.infrastructure.dao.ISchCollectRecordDao;
import com.docus.server.infrastructure.dao.ISchCollectRecordRetryLogDao;
import com.docus.server.infrastructure.dao.ISchSystemParamsDao;
import com.docus.server.infrastructure.dao.ISchTerminatorDao;
import com.docus.server.service.ISchCollectRecordService;
import com.docus.server.vo.scheduling.management.schcollectrecord.SchCollectRecordVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 采集记录表 服务实现类
 *
 * @author AutoGenerator
 * @since 2023-07-15
 */
@Service
public class SchCollectRecordServiceImpl implements ISchCollectRecordService {
    @Resource
    private ISchCollectRecordDao iSchCollectRecordDao;
    @Resource
    private ISchTerminatorDao iSchTerminatorDao;
    @Resource
    private ISchCollectRecordRetryLogDao iSchCollectRecordRetryLogDao;
    @Resource
    private ISchSystemParamsDao iSchSystemParamsDao;
    @Resource
    private IdService idService;

    /**
     * 按主键查询
     *
     * @param id 主键Id
     * @return 实体
     */
    @Override
    public SchCollectRecordVO findById(String id) {
        return SchCollectRecordConvert.INSTANCE.convertVO(iSchCollectRecordDao.findById(id));
    }

    /**
     * 关键字搜索
     *
     * @param searchDTO 搜索参数
     * @return 分页列表
     */
    @Override
    public PageResult<SchCollectRecordVO> search(SearchDTO searchDTO) {
        PageResult<SchCollectRecordVO> result = SchCollectRecordConvert.INSTANCE.convertVO(iSchCollectRecordDao.search(searchDTO));

        if (CollectionUtils.isEmpty(result.getList())) {
            return new PageResult<>();
        }

        List<SchSystemParams> schSystemParams = iSchSystemParamsDao.findBy("paramValue", ListUtils.distinctSelect(result.getList(), SchCollectRecordVO::getCollectorId));
        Map<String, SchSystemParams> taskConfigRetryLogMap = ListUtils.toMap(schSystemParams, SchSystemParams::getParamValue);

        Setters.<SchCollectRecordVO>instance().list(result.getList()).cycleSetProperties(p -> {
            String collectorId = String.valueOf(p.getCollectorId());
            if (taskConfigRetryLogMap.containsKey(collectorId)) {
                p.setCollectorName(taskConfigRetryLogMap.get(collectorId).getParamName());
            }
        });

        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public SchCollectRecord saveOrUpdateRecord(NettyTerminatorDTO terminal, ReportDownTwoDTO messageContent) {
        //新增采集记录表
        AddSchCollectRecordDTO addSchCollectRecordDTO = new AddSchCollectRecordDTO();
        addSchCollectRecordDTO.setId(idService.getDateSeq());
        addSchCollectRecordDTO.setCollectorId(Long.valueOf(messageContent.getTasks().get(0).getCollectorId()));
        addSchCollectRecordDTO.setTerminatorId(terminal.getId());
        addSchCollectRecordDTO.setTaskId(messageContent.getTasks().get(0).getTaskId());
        SchSystemParams params = iSchSystemParamsDao.findOneBy("paramValue", messageContent.getTasks().get(0).getCollectorId());
        addSchCollectRecordDTO.setTaskName(String.format("%s%s%s", messageContent.getPatient().getName(), params.getParamName(), "采集"));
        addSchCollectRecordDTO.setTaskMemo(String.format("%s%s%s", messageContent.getPatient().getName(), params.getParamName(), "采集"));
        addSchCollectRecordDTO.setStartTime(DateUtil.now());
        addSchCollectRecordDTO.setTaskDetailInfo(String.format("病案号：%s，姓名：%s，采集类型：%s", messageContent.getPatientId(), messageContent.getPatient().getName(), params.getParamName()));
        addSchCollectRecordDTO.setSubTaskExecState(SubStateEnum.RECEIVE);
        addSchCollectRecordDTO.setTaskOriginJson(JSON.toJSON(messageContent));

        return this.add(addSchCollectRecordDTO);
    }

    /**
     * 新增
     *
     * @param addSchCollectRecordDTO 编辑参数
     * @return 成功或失败
     */
    @Override
    public SchCollectRecord add(AddSchCollectRecordDTO addSchCollectRecordDTO) {
        SchCollectRecord schCollectRecord = SchCollectRecordConvert.INSTANCE.convertDO(addSchCollectRecordDTO);
        iSchCollectRecordDao.add(schCollectRecord);
        return schCollectRecord;
    }

    /**
     * 编辑
     *
     * @param editSchCollectRecordDTO 编辑参数
     * @return 成功或失败
     */
    @Override
    public boolean edit(EditSchCollectRecordDTO editSchCollectRecordDTO) {
        RetryTaskEnum isRetryTask = editSchCollectRecordDTO.getIsRetryTask();
        Long id = editSchCollectRecordDTO.getId();

        if (RetryTaskEnum.NO_RETRY_TASK.equals(isRetryTask)) {
            //不是重试任务
            SchCollectRecord schCollectRecord = iSchCollectRecordDao.findById(id);

            if (null == schCollectRecord) {
                throw new ApiException(ExceptionCode.ParamIllegal.getCode(), "不重复任务采集记录不存在！" + id);
            }

            schCollectRecord = SchCollectRecordConvert.INSTANCE.convertDO(editSchCollectRecordDTO, schCollectRecord);

            return iSchCollectRecordDao.updateById(schCollectRecord);
        } else {
            //重试任务
            SchCollectRecordRetryLog schCollectRecordRetryLog = iSchCollectRecordRetryLogDao.findById(id);

            if (null == schCollectRecordRetryLog) {
                throw new ApiException(ExceptionCode.ParamIllegal.getCode(), "不重复任务采集记录不存在！" + id);
            }
            schCollectRecordRetryLog = SchCollectRecordRetryLogConvert.INSTANCE.convertDO(editSchCollectRecordDTO, schCollectRecordRetryLog);
            return iSchCollectRecordRetryLogDao.updateById(schCollectRecordRetryLog);
        }
    }

    /**
     * 批量删除
     *
     * @param deleteSchCollectRecordDTO 删除参数
     * @return 成功或失败
     */
    @Override
    public int delete(DeleteSchCollectRecordDTO deleteSchCollectRecordDTO) {
        return iSchCollectRecordDao.delete(deleteSchCollectRecordDTO.getIds());
    }
}

