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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.date.TimeRange;
import org.jeecg.modules.database.entity.*;
import org.jeecg.modules.database.mapper.ExperimentRadiationProcessMapper;
import org.jeecg.modules.database.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 辐照过程
 * @Author: jeecg-boot
 * @Date: 2024-10-15
 * @Version: V1.0
 */
@Service
public class ExperimentRadiationProcessServiceImpl extends ServiceImpl<ExperimentRadiationProcessMapper, ExperimentRadiationProcess>
        implements IExperimentRadiationProcessService {
    @Autowired
    private IExperimentSampleInfoService       experimentSampleInfoService;
    @Autowired
    private IExperimentIrradiationBoardService experimentIrradiationBoardService;

    @Override
    public List<ExperimentRadiationProcess> getByExperimentId(String experimentId) {
        List<ExperimentRadiationProcess> list = list(
                new LambdaQueryWrapper<ExperimentRadiationProcess>().eq(ExperimentRadiationProcess::getExperimentId, experimentId));
        list.forEach(this::assembleDetails);
        return list;
    }

    @Override
    public ExperimentRadiationProcess getById(Serializable id) {
        ExperimentRadiationProcess experimentRadiationProcess = super.getById(id);
        if (Objects.isNull(experimentRadiationProcess)) {
            return null;
        }
        assembleDetails(experimentRadiationProcess);
        return experimentRadiationProcess;
    }

    @Override
    public void assembleDetails(ExperimentRadiationProcess experimentRadiationProcess) {
        String sampleInfoIds = experimentRadiationProcess.getSampleInfo();
        List<ExperimentSampleInfo> sampleInfoList;
        if (StringUtils.isNotBlank(sampleInfoIds)) {
            sampleInfoList = Arrays.stream(sampleInfoIds.split(",")).map(sampleInfoId -> experimentSampleInfoService.getById(sampleInfoId))
                    .filter(Objects::nonNull).collect(Collectors.toList());
            experimentRadiationProcess.setSampleInfoList(sampleInfoList);
        }
    }

    @Override
    public void saveWithDetails(ExperimentRadiationProcess experimentRadiationProcess) {

        List<ExperimentSampleInfo> sampleInfoList = experimentRadiationProcess.getSampleInfoList();
        List<String> sampleInfoIds = new ArrayList<>();
        if (sampleInfoList != null && sampleInfoList.size() > 0) {
            for (ExperimentSampleInfo sampleInfo : sampleInfoList) {
                sampleInfo.setExperimentId(experimentRadiationProcess.getExperimentId());
                experimentSampleInfoService.saveOrUpdate(sampleInfo);
                sampleInfoIds.add(sampleInfo.getId());
            }
        }
        List<ExperimentRadiationProcess> radiationProcessList = getByExperimentId(experimentRadiationProcess.getExperimentId());
        if (CollUtil.isNotEmpty(radiationProcessList)) {
            List<TimeRange> list = new ArrayList<>();
            for (ExperimentRadiationProcess process : radiationProcessList) {
                String radiationDetail = process.getRadiationDetail();
                if (StringUtils.isNotBlank(radiationDetail)) {
                    Map<String, List<Map<String, String>>> detailMap = JSONObject.parseObject(radiationDetail,
                            new TypeReference<>() {});
                    detailMap.forEach((key, value) -> value.forEach(v1 -> {
                        String startTime = v1.get("startTime");
                        String endTime = v1.get("endTime");
                        list.add(new TimeRange(DateUtils.parseDatetimeShort(startTime), DateUtils.parseDatetimeShort(endTime)));
                    }));
                }
            }
            Date earliestTime = DateUtils.findEarliestTime(list);
            Date latestTime = DateUtils.findLatestTime(list);
            experimentRadiationProcess.setRadiationStartTime(earliestTime);
            experimentRadiationProcess.setRadiationEndTime(latestTime);
            List<ExperimentIrradiationBoard> irradiationBoardList = experimentIrradiationBoardService.getByExperimentId(
                    experimentRadiationProcess.getExperimentId());
            String mv = DateUtils.formatDate(earliestTime, "yyyy-MM-dd") + "至" + DateUtils.formatDate(latestTime, "yyyy-MM-dd");
            irradiationBoardList.forEach(experimentIrradiationBoard -> {
                experimentIrradiationBoard.setMeasurementValidity(mv);
                experimentIrradiationBoardService.saveOrUpdate(experimentIrradiationBoard);
            });
        }

        experimentRadiationProcess.setSampleInfo(StringUtils.join(sampleInfoIds, ","));
        saveOrUpdate(experimentRadiationProcess);
    }

    @Override
    public void copy(String oldId,String newExperimentId) {
        ExperimentRadiationProcess experiment = new ExperimentRadiationProcess();
        BeanUtil.copyProperties(getById(oldId), experiment);
        experiment.setId(null);
        experiment.setExperimentId(newExperimentId);
        experiment.setRadiationStartTime(null);
        experiment.setRadiationEndTime(null);
        experiment.setCreateTime(new Date());
        String radiationDetail = experiment.getRadiationDetail();
        if (StringUtils.isNotBlank(radiationDetail)) {
            com.alibaba.fastjson2.JSONObject jsonObject = JSON.parseObject(radiationDetail);
            // 遍历所有键
            for (String key : jsonObject.keySet()) {
                JSONArray array = jsonObject.getJSONArray(key);
                for (int i = 0; i < array.size(); i++) {
                    com.alibaba.fastjson2.JSONObject item = array.getJSONObject(i);
                    // 移除 startTime 和 endTime
                    item.remove("startTime");
                    item.remove("endTime");
                }
            }
            experiment.setRadiationDetail(jsonObject.toJSONString());
        }
        List<ExperimentSampleInfo> sampleInfoList = experimentSampleInfoService.getByExperimentId(newExperimentId);
        if (CollUtil.isNotEmpty(sampleInfoList)) {
            experiment.setSampleInfo(sampleInfoList.stream().map(v -> v.getId()).collect(Collectors.joining(",")));
        } else {
            experiment.setSampleInfo(null);
        }
        save(experiment);
    }
}
