package digital.laboratory.platform.inspection.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.inspection.enums.TestRecordFileUrl;
import digital.laboratory.platform.inspection.dto.DataSolutionSampleDTO;
import digital.laboratory.platform.inspection.dto.DeleteTestAtlasDTO;
import digital.laboratory.platform.inspection.mapper.TestRecordSampleDataMapper;
import digital.laboratory.platform.inspection.service.TestAtlasService;
import digital.laboratory.platform.inspection.service.TestRecordService;
import digital.laboratory.platform.inspetion.api.entity.TestRecord;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ChenJiangBao
 * @version 1.0
 * @description: 实验图谱相关接口 相关实现类
 * @date 2025/3/18 14:57
 */
@Service
public class TestAtlasServiceImpl implements TestAtlasService {

    @Resource
    private OssFile ossFile;

    @Resource
    private TestRecordService testRecordService;

    @Resource
    private TestRecordSampleDataMapper testRecordSampleDataMapper;


    /**
     * 上传实验图谱
     *
     * @param testId
     * @param file
     * @return
     */
    @Override
    public R uploadTestAtlas(String testId, MultipartFile file) {
        TestRecord testRecord = testRecordService.getById(testId);
        if (testRecord == null) {
            throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
        }
        // 取已上传过的实验图谱
        JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
        // 获取文件名list
        List<String> fileNameList = new ArrayList<>();
        for (int i = 0; i < testAtlas.size(); i++) {
            JSONObject jsonObject = testAtlas.getJSONObject(i);
            fileNameList.add(jsonObject.getString("fileName"));
        }
        // 拼接上传的路径,以实验id为文件夹
        String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();

        // 生成一个文件id
        String fileId = IdWorker.getIdStr();
        boolean upload = ossFile.fileUpload(file, commonPath);
        String fileName = FileNameUtil.getName(file.getOriginalFilename());
        String type = file.getContentType();
        if (!upload) {
            // 上传失败
            Map<String, String> resultData = new HashMap<>();
            resultData.put("fileName", fileName);
            resultData.put("path", commonPath);
            return R.failed(resultData, "上传实验图谱失败");
        }
//        if (testAtlas.size() > 0) {
//            // 删除之前上传的
//            JSONObject oldObject = testAtlas.getJSONObject(0);
//            ossFile.fileDelete(oldObject.getString("path"));
//            testAtlas = new JSONArray();
//        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("fileId", fileId);
        jsonObject.put("fileName", fileName);
        jsonObject.put("type", type);
        jsonObject.put("path", commonPath + "/" + fileName);
        testAtlas.add(jsonObject);

        testRecord.setTestAtlas(testAtlas.toJSONString());
        if (testRecordService.updateById(testRecord)) {
            return R.ok("上传实验图谱成功!");
        } else {
            return R.failed("上传实验图谱失败!");
        }
    }

    /**
     * 上传实验图谱
     *
     * @param testId
     * @param files
     * @return
     */
    @Override
    public R uploadTestAtlasBatch(String testId, List<MultipartFile> files) {
        TestRecord testRecord = testRecordService.getById(testId);
        if (testRecord == null) {
            throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
        }
        // 取已上传过的实验图谱
        JSONArray testAtlas = StrUtil.isBlank(testRecord.getTestAtlas()) ? new JSONArray() : JSONArray.parseArray(testRecord.getTestAtlas());
        // 获取文件名list
        List<String> fileNameList = new ArrayList<>();
        for (int i = 0; i < testAtlas.size(); i++) {
            JSONObject jsonObject = testAtlas.getJSONObject(i);
            fileNameList.add(jsonObject.getString("fileName"));
        }
        // 拼接上传的路径,以实验id为文件夹
        String commonPath = TestRecordFileUrl.TEST_ATLAS_PATH.getFileUrl() + testRecord.getId();
        // 这里遍历要上传的文件
        for (MultipartFile file : files) {
            // 获取id来防止因为文件名重复导致的问题
            String fileId = IdWorker.getIdStr();
            /*String filePath = commonPath + "/" + fileId + "/";*/
            boolean upload = ossFile.fileUpload(file, commonPath);
            String fileName = FileNameUtil.getName(file.getOriginalFilename());
            String type = file.getContentType();
            if (!upload) {
                // 上传失败
                Map<String, String> resultData = new HashMap<>();
                resultData.put("fileName", fileName);
                resultData.put("path", commonPath);
                return R.failed(resultData, "上传实验图谱删除失败");
            }
            if (fileNameList.contains(fileName)) {
                // 文件名存在则不用在添加一个json对象
                continue;
            }
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("fileId", fileId);
            jsonObject.put("fileName", fileName);
            jsonObject.put("type", type);
            jsonObject.put("path", commonPath + "/" + fileName);
            testAtlas.add(jsonObject);
        }
        testRecord.setTestAtlas(testAtlas.toJSONString());
        if (testRecordService.updateById(testRecord)) {
            return R.ok("上传实验图谱成功!");
        } else {
            return R.failed("上传实验图谱失败!");
        }
    }

    /**
     * 获取该实验id的实验图谱
     *
     * @param testId
     * @return
     */
    @Override
    public R getTestAtlasList(String testId) {
        TestRecord testRecord = testRecordService.getById(testId);
        if (testRecord == null) {
            throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", testId));
        }
        if (StrUtil.isBlank(testRecord.getTestAtlas())) {
            return R.ok();
        }

        return R.ok(JSONArray.parseArray(testRecord.getTestAtlas()), "获取实验图谱列表成功！");
    }

    /**
     * 删除实验图谱
     *
     * @param dto
     * @return
     */
    @Override
    public R deleteTestAtlas(DeleteTestAtlasDTO dto) throws Exception {
        TestRecord testRecord = testRecordService.getById(dto.getTestId());
        if (testRecord == null) {
            throw new RuntimeException(String.format("实验id为 %s 的数据在系统中不存在!", dto.getTestId()));
        }
        JSONArray array = JSONArray.parseArray(testRecord.getTestAtlas());
        if (CollUtil.isEmpty(array)) {
            throw new RuntimeException("该实验的图谱为空!");
        }
        // 获取删除的fileid
        List<String> fileIds = dto.getFileIds();
        JSONArray newArray = new JSONArray();
        int size = array.size();
        for (int i = 0; i < size; i++) {
            JSONObject jsonObject = array.getJSONObject(i);
            String fileId = jsonObject.getString("fileId");
            if (fileIds.contains(fileId)) {
                ossFile.fileDelete(jsonObject.getString("path"));
            } else {
                // 不是删除的，就添加到新的数组
                newArray.add(jsonObject);
            }
        }

        // 更新
        testRecord.setTestAtlas(newArray.toJSONString());
        if (testRecordService.updateById(testRecord)) {
            return R.ok(true, "实验图谱删除成功！");
        } else {
            return R.ok(false, "实验图谱删除失败！");
        }
    }

    /**
     * 根据业务id获取实验图谱
     *
     * @param businessId
     * @return
     */
    @Override
    public R getTestAtlasListByBusinessId(String businessId) {
        /**
         * 先根据业务id 查询出检材id
         */
        List<DataSolutionSampleDTO> testDataListByBusiness = testRecordSampleDataMapper
                .queryDataSolutionSampleDTOList(Wrappers.<DataSolutionSampleDTO>query().eq("si.business_id", businessId));
        if (CollUtil.isEmpty(testDataListByBusiness)) {
            return R.ok();
        }
        // 2 根据查询出来的结果，取出实验id
        List<String> testIdList = testDataListByBusiness.stream().map(DataSolutionSampleDTO::getTestId).collect(Collectors.toList());
        // 3 根据实验id 获取实验信息
        List<TestRecord> testRecordList = testRecordService.list(Wrappers.<TestRecord>lambdaQuery()
                .in(TestRecord::getId, testIdList)
                .orderByDesc(TestRecord::getUpdateTime));
        // 最终返回的结果数组
        JSONArray resultArray = new JSONArray();
        for (TestRecord testRecord : testRecordList) {
            if (StrUtil.isNotBlank(testRecord.getTestAtlas())) {
                resultArray.addAll(JSONArray.parseArray(testRecord.getTestAtlas()));
            }
        }
        return R.ok(resultArray, "根据业务id获取列表成功！");
    }


}
