package org.jeecg.modules.database.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.database.constant.ExperimentStatus;
import org.jeecg.modules.database.entity.*;
import org.jeecg.modules.database.mapper.ExperimentMapper;
import org.jeecg.modules.database.service.*;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description: 试验管理
 * @Author: jeecg-boot
 * @Date: 2024-08-30
 * @Version: V1.0
 */
@Service
public class ExperimentServiceImpl extends ServiceImpl<ExperimentMapper, Experiment> implements IExperimentService {
    @Autowired
    private ISysUserService                      userService;
    @Autowired
    private IExperimentUserService               experimentUserService;
    @Autowired
    private IExperimentSampleInfoService         experimentSampleInfoService;
    @Autowired
    private IExperimentDeviationConditionService experimentDeviationConditionService;
    @Autowired
    private IExperimentDeviationEquipmentService experimentDeviationEquipmentService;
    @Autowired
    private IExperimentIrradiationBoardService   experimentIrradiationBoardService;

    @Autowired
    private IExperimentSequenceService experimentSequenceService;

    @Autowired
    private IExperimentFileService experimentFileService;

    @Override
    public void fetchExperimentDetail(Experiment experiment) {
        if (StringUtils.isNotBlank(experiment.getSupervisor())) {
            SysUser user = userService.getById(experiment.getSupervisor());
            if (Objects.nonNull(user)) {
                experiment.setSupervisorName(user.getRealname());
            }
        }
        List<ExperimentUser> userList = experimentUserService.getByExperimentId(experiment.getId());
        if (CollUtil.isNotEmpty(userList)) {
            userList.forEach(experimentUser -> {
                SysUser sysUser = userService.getById(experimentUser.getUserId());
                if (Objects.nonNull(sysUser)) {
                    experimentUser.setUserName(sysUser.getRealname());
                }
            });
        }
        experiment.setExperimentUserList(userList);
        experiment.setExperimentUser(userList.stream().map(ExperimentUser::getUserId).collect(Collectors.joining(",")));

        List<ExperimentSampleInfo> sampleInfoList = experimentSampleInfoService.getByExperimentId(experiment.getId());
        if (CollUtil.isNotEmpty(sampleInfoList)) {
            experiment.setSampleInfoList(sampleInfoList);
        }

        List<ExperimentDeviationCondition> deviationConditionList = experimentDeviationConditionService.getByExperimentId(
                experiment.getId());
        if (CollUtil.isNotEmpty(deviationConditionList)) {
            experiment.setDeviationConditionList(deviationConditionList);
        }

        List<ExperimentDeviationEquipment> deviationEquipmentList = experimentDeviationEquipmentService.getByExperimentId(
                experiment.getId());
        if (CollUtil.isNotEmpty(deviationEquipmentList)) {
            experiment.setDeviationEquipmentList(deviationEquipmentList);
        }

        List<ExperimentIrradiationBoard> irradiationBoardList = experimentIrradiationBoardService.getByExperimentId(experiment.getId());
        if (CollUtil.isNotEmpty(irradiationBoardList)) {
            experiment.setIrradiationBoardList(irradiationBoardList);
        }

        List<ExperimentFile> experimentFileList = experimentFileService.getByExperimentId(experiment.getId());
        if (CollUtil.isNotEmpty(experimentFileList)) {
            experiment.setFileList(experimentFileList);
        }

    }

    @Override
    public Experiment copy(Experiment oldExperiment) {
        Experiment experiment = new Experiment();
        BeanUtil.copyProperties(this, experiment);
        experiment.setId(null);
        experiment.setExperimentNo(experimentSequenceService.next());
        experiment.setCopyCount(0);
        experiment.setStatus(ExperimentStatus.PRE_TEST);
        experiment.setStartDate(null);
        experiment.setEndDate(null);
        save(experiment);

        List<ExperimentIrradiationBoard> irradiationBoardList = oldExperiment.getIrradiationBoardList();
        if (CollUtil.isNotEmpty(irradiationBoardList)) {
            irradiationBoardList.forEach(board -> {
                ExperimentIrradiationBoard target = new ExperimentIrradiationBoard();
                BeanUtil.copyProperties(board, target);
                target.setId(null);
                target.setMeasurementValidity(null);
                target.setSourceArea(null);
                target.setSampleImage(null);
                target.setExperimentId(experiment.getId());
                experimentIrradiationBoardService.save(target);
            });
        }
        List<ExperimentDeviationEquipment> deviationEquipmentList = oldExperiment.getDeviationEquipmentList();
        if (CollUtil.isNotEmpty(deviationEquipmentList)) {
            deviationEquipmentList.forEach(board -> {
                ExperimentDeviationEquipment target = new ExperimentDeviationEquipment();
                BeanUtil.copyProperties(board, target);

                target.setId(null);
                target.setMeasurementValidity(null);
                target.setSampleImage(null);
                target.setExperimentId(experiment.getId());
                experimentDeviationEquipmentService.save(target);
            });
        }

        List<ExperimentDeviationCondition> deviationConditionList = oldExperiment.getDeviationConditionList();
        if (CollUtil.isNotEmpty(deviationConditionList)) {
            deviationConditionList.forEach(board -> {
                ExperimentDeviationCondition target = new ExperimentDeviationCondition();
                BeanUtil.copyProperties(board, target);
                target.setId(null);
                target.setLoadCapacity(null);
                target.setSampleImage(null);
                target.setExperimentId(experiment.getId());
                experimentDeviationConditionService.save(target);
            });
        }
        return experiment;

    }

    @Override
    public void changeStatus(String experimentId, String status) {
        Experiment dbData = getById(experimentId);
        switch (status) {
            case ExperimentStatus.COMPLETED:
                if (!StringUtils.equals(dbData.getStatus(), ExperimentStatus.PROGRESSING)) {
                    throw new IllegalArgumentException("试验状态不正确!");
                }
                break;
        }
        Experiment experiment = new Experiment();
        experiment.setId(experimentId);
        experiment.setStatus(status);
        updateById(experiment);
    }

    @Override
    public void saveWithDetail(Experiment experiment) {
        saveOrUpdate(experiment);

        String experimentUser = experiment.getExperimentUser();
        if (StringUtils.isNotBlank(experimentUser)) {
            experimentUserService.removeByExperimentId(experiment.getId());
            for (String userId : experimentUser.split(",")) {
                ExperimentUser userDomain = new ExperimentUser();
                userDomain.setExperimentId(experiment.getId());
                userDomain.setUserId(userId);
                userDomain.setType("OPERATOR");
                experimentUserService.save(userDomain);
            }
        }
        List<ExperimentSampleInfo> sampleInfoList = experiment.getSampleInfoList();
        if (CollUtil.isNotEmpty(sampleInfoList)) {
            for (ExperimentSampleInfo sampleInfo : sampleInfoList) {
                sampleInfo.setExperimentId(experiment.getId());
                experimentSampleInfoService.saveOrUpdate(sampleInfo);
            }
        }
        List<ExperimentDeviationCondition> deviationConditionList = experiment.getDeviationConditionList();
        if (CollUtil.isNotEmpty(deviationConditionList)) {
            for (ExperimentDeviationCondition deviationCondition : deviationConditionList) {
                deviationCondition.setExperimentId(experiment.getId());
                experimentDeviationConditionService.saveOrUpdate(deviationCondition);
            }
        }
        List<ExperimentDeviationEquipment> deviationEquipmentList = experiment.getDeviationEquipmentList();
        if (CollUtil.isNotEmpty(deviationEquipmentList)) {
            for (ExperimentDeviationEquipment deviationEquipment : deviationEquipmentList) {
                deviationEquipment.setExperimentId(experiment.getId());
                experimentDeviationEquipmentService.saveOrUpdate(deviationEquipment);
            }
        }
        List<ExperimentIrradiationBoard> irradiationBoardList = experiment.getIrradiationBoardList();
        if (CollUtil.isNotEmpty(irradiationBoardList)) {
            for (ExperimentIrradiationBoard irradiationBoard : irradiationBoardList) {
                irradiationBoard.setExperimentId(experiment.getId());
                experimentIrradiationBoardService.saveOrUpdate(irradiationBoard);
            }
        }

    }
}
