package com.cf.imes.module.system.service.datasource;

import cn.hutool.core.collection.CollUtil;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.cf.imes.framework.common.enums.MachineTypeEnum;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.es.core.service.ESDocumentService;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.module.executor.api.plan.OrderPlanApi;
import com.cf.imes.module.system.controller.admin.datasource.dataQuery.DataQuery;
import com.cf.imes.module.system.controller.admin.datasource.vo.*;
import com.cf.imes.module.system.dal.dataobject.datasource.DataSourceDO;
import com.cf.imes.module.system.dal.dataobject.datasource.DataSourceFiledDO;
import com.cf.imes.module.system.dal.mysql.datasource.DataSourceFiledMapper;
import com.cf.imes.module.system.dal.mysql.datasource.DataSourceMapper;
import com.cf.imes.module.system.dal.mysql.machine.MachineMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.*;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.object.BeanUtils.toBean;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.DATA_SOURCE_NOT_EXISTS;

/**
 * 系统数据源 Service 实现类
 *
 * @author 晨丰科技
 */
@Service
@Validated
@Slf4j
public class DataSourceServiceImpl implements DataSourceService {

    @Resource
    private DataSourceMapper dataSourceMapper;

    @Resource
    private DataSourceFiledMapper dataSourceFiledMapper;

    @Resource
    private MachineMapper machineMapper;

    @Resource
    private ESDocumentService esDocumentService;

    @Resource
    private ElasticsearchClient elasticsearchClient;

    @Resource
    private OrderPlanApi orderPlanApi;

    @Resource
    private DataQuery dataQuery;


    String MACHINE_DATA_SOURCE = "imes_machine_data_source";

    private static final String FIELD_MACHINEID = "machineId";

    @Override
    public void createDataSource(List<DataSourceSaveReqVO> createReqVO) {


        // 提取 SourceField 中的 key 列表
        List<String> keyList = createReqVO.stream()
                .map(DataSourceSaveReqVO::getKeyName)
                .collect(Collectors.toList());

        // 根据 key 列表查询对应的 DataSourceFiledDO 列表并转换为 Map
        Map<String, List<DataSourceFiledDO>> dataSourceFiledDoMap = dataSourceFiledMapper
                .selectFiledListByKey(keyList)
                .stream()
                .collect(Collectors.groupingBy(DataSourceFiledDO::getKeyName));

        List<DataSourceFiledDO> insertFiledDoS = new ArrayList<>();

        List<DataSourceFiledDO> updateFiledDoS = new ArrayList<>();

        // 遍历 SourceFields 进行插入或更新操作
        for (DataSourceSaveReqVO sourceField : createReqVO) {

            List<DataSourceFiledDO> existingFiledDoS = dataSourceFiledDoMap.get(sourceField.getKeyName());

            if (existingFiledDoS != null) {
                DataSourceFiledDO dataSourceFiledDO = existingFiledDoS.get(0);
                if (shouldUpdate(dataSourceFiledDO, sourceField)) {
                    dataSourceFiledDO.setSourceId(dataSourceFiledDO.getSourceId() + "," + sourceField.getParentId());
                    updateFiledDoS.add(dataSourceFiledDO);

                }

            } else {

                insertFiledDoS.add(DataSourceFiledDO.builder()
                        .keyName(sourceField.getKeyName())
                        .sourceId(String.valueOf(sourceField.getParentId()))
                        .name(sourceField.getName())
                        .build());
            }
        }

        // 批量插入和更新 DataSourceFiledDO 列表
        if (!insertFiledDoS.isEmpty()) {
            dataSourceFiledMapper.insertBatch(insertFiledDoS);
        }
        if (!updateFiledDoS.isEmpty()) {
            dataSourceFiledMapper.updateBatch(updateFiledDoS);
        }


    }


    private boolean shouldUpdate(DataSourceFiledDO existingFiledDO, DataSourceSaveReqVO sourceField) {
        return existingFiledDO.getId() > 1000 &&
                Objects.equals(existingFiledDO.getName(), sourceField.getName()) &&
                !conversion(existingFiledDO.getSourceId()).contains(sourceField.getParentId());
    }


//
//    @Override
//    public void createDataSource(List<DataSourceSaveReqVO> createReqVO) {
//        // 获取请求中的 SourceFields 列表
//        List<DataSourceSaveReqVO.SourceField> sourceFields = createReqVO.getSourceFields();
//
//        // 提取 SourceField 中的 key 列表
//        List<String> keyList = sourceFields.stream()
//                .map(DataSourceSaveReqVO.SourceField::getKey)
//                .collect(Collectors.toList());
//
//        // 根据 key 列表查询对应的 DataSourceFiledDO 列表并转换为 Map
//        Map<String, List<DataSourceFiledDO>> dataSourceFiledDOMap = dataSourceFiledMapper
//                .selectFiledListByKey(keyList)
//                .stream()
//                .collect(Collectors.groupingBy(DataSourceFiledDO::getKey));
//
//        List<DataSourceFiledDO> insertFiledDOS = new ArrayList<>();
//        List<DataSourceFiledDO> updateFiledDOS = new ArrayList<>();
//
//        // 遍历 SourceFields 进行插入或更新操作
//        for (DataSourceSaveReqVO.SourceField sourceField : sourceFields) {
//            List<DataSourceFiledDO> existingFiledDOS = dataSourceFiledDOMap.get(sourceField.getKey());
//
//            if (existingFiledDOS != null) {
//                DataSourceFiledDO dataSourceFiledDO = existingFiledDOS.get(0);
//                if (shouldUpdate(dataSourceFiledDO, sourceField)) {
//                    dataSourceFiledDO.setSourceId(dataSourceFiledDO.getSourceId() + "," + sourceField.getParentId());
//                    updateFiledDOS.add(dataSourceFiledDO);
//                }
//
//            } else {
//                insertFiledDOS.add(DataSourceFiledDO.builder()
//                        .key(sourceField.getKey())
//                        .sourceId(String.valueOf(sourceField.getParentId()))
//                        .name(sourceField.getName())
//                        .build());
//            }
//        }
//
//        // 批量插入和更新 DataSourceFiledDO 列表
//        if (!insertFiledDOS.isEmpty()) {
//            dataSourceFiledMapper.insertBatch(insertFiledDOS);
//        }
//        if (!updateFiledDOS.isEmpty()) {
//            dataSourceFiledMapper.updateBatch(updateFiledDOS);
//        }
//    }
//
//    private boolean shouldUpdate(DataSourceFiledDO existingFiledDO, DataSourceSaveReqVO.SourceField sourceField) {
//        return existingFiledDO.getId() > 1000 &&
//                Objects.equals(existingFiledDO.getName(), sourceField.getName()) &&
//                !conversion(existingFiledDO.getSourceId()).contains(sourceField.getParentId());
//    }


//
//    @Override
//    public void createDataSource(DataSourceSaveReqVO createReqVO) {
//        // 获取请求中的 SourceFields 列表
//        List<DataSourceSaveReqVO.SourceField> sourceFields = createReqVO.getSourceFields();
//
//        List<DataSourceFiledDO> insertFiledDOS = new ArrayList<>();
//
//        List<DataSourceFiledDO> updateFiledDOS = new ArrayList<>();
//
//        // 提取 SourceField 中的 key 列表
//        List<String> keyList = sourceFields.stream().map(DataSourceSaveReqVO.SourceField::getKey).toList();
//
//        // 根据 key 列表查询对应的 DataSourceFiledDO 列表
//        List<DataSourceFiledDO> dataSourceFiledDOS = dataSourceFiledMapper.selectFiledListByKey(keyList);
//
//        if (!dataSourceFiledDOS.isEmpty()) {
//
//            // 提取已存在的 DataSourceFiledDO 的 key 列表
//            List<String> keys = dataSourceFiledDOS.stream().map(DataSourceFiledDO::getKey).toList();
//
//            StringBuilder data = new StringBuilder();
//
//            for (DataSourceSaveReqVO.SourceField sourceField : sourceFields) {
//                // 过滤出符合条件的 DataSourceFiledDO
//                List<DataSourceFiledDO> sourceFiledDOS = dataSourceFiledDOS.stream()
//                        .filter(f -> Objects.equals(f.getKey(), sourceField.getKey()))
//                        .filter(f->Objects.equals(f.getName(),sourceField.getName()))
//                        .filter(f -> !conversion(f.getSourceId()).contains(sourceField.getParentId()))
//                        .filter(f -> f.getId() > 1000)
//                        .toList();
//
//                if (!sourceFiledDOS.isEmpty()) {
//
//                    data.append(",").append(sourceField.getParentId());
//
//                    DataSourceFiledDO dataSourceFiledDO = BeanUtils.toBean(sourceFiledDOS.get(0), DataSourceFiledDO.class);
//                    dataSourceFiledDO.setSourceId(dataSourceFiledDO.getSourceId() + data);
//                    updateFiledDOS.add(dataSourceFiledDO);
//
//                }
//
//                // 如果 key 不存在于已查询的列表中，新增一个 DataSourceFiledDO
//                if (!keys.contains(sourceField.getKey())) {
//                    insertFiledDOS.add(DataSourceFiledDO.builder()
//                            .key(sourceField.getKey())
//                            .sourceId(String.valueOf(sourceField.getParentId()))
//                            .name(sourceField.getName())
//                            .build());
//                }
//            }
//
//            dataSourceFiledMapper.updateBatch(updateFiledDOS);
//
//        } else {
//            // 如果查询结果为空，直接将所有 sourceFields 转换为 DataSourceFiledDO 并添加到列表中
//            insertFiledDOS.addAll(sourceFields.stream()
//                    .map(m -> DataSourceFiledDO.builder()
//                            .key(m.getKey())
//                            .sourceId(String.valueOf(m.getParentId()))
//                            .name(m.getName())
//                            .build())
//                    .toList());
//        }
//
//        // 批量插入 DataSourceFiledDO 列表
//        dataSourceFiledMapper.insertBatch(insertFiledDOS);
//
//
//    }


    // 目前不对重复添加的数据进行删选处理,后续有需求再处理
//        List<DataSourceFiledDO> dataSourceFiledDO = dataSourceFiledMapper.selectFiled(sourceFields);
//
//        List<DataSourceSaveReqVO.SourceField> fieldList  = new ArrayList<>();
//
//        if(! dataSourceFiledDO.isEmpty()){
//
//            List<String> sourceIds = dataSourceFiledDO.stream().map(m -> m.getSourceId()).toList();
//
//            for (String sourceId : sourceIds) {
//                fieldList.addAll(sourceFields.stream()
//                        .filter(f -> !conversion(sourceId).contains(f.getParentId()))
//                        .toList());
//            }
//
//        }


    @Override
    public void updateDataSource(DataSourceSaveReqVO updateReqVO) {
        // 校验存在
        validateDataSourceExists(updateReqVO.getId());
        // 更新
        DataSourceDO updateObj = toBean(updateReqVO, DataSourceDO.class);
        dataSourceMapper.updateById(updateObj);
    }

    @Override
    public void deleteDataSource(Long id) {
        // 校验存在
        validateDataSourceExists(id);
        // 删除
        dataSourceMapper.deleteById(id);
    }

    private void validateDataSourceExists(Long id) {
        if (dataSourceMapper.selectById(id) == null) {
            throw exception(DATA_SOURCE_NOT_EXISTS);
        }
    }

    @Override
    public DataSourceDO getDataSource(Long id) {
        return dataSourceMapper.selectById(id);
    }

    @Override
    public PageResult<DataSourceDO> getDataSourcePage(DataSourcePageReqVO pageReqVO) {
        return dataSourceMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DataSourceDO> list(Integer type) {
        return dataSourceMapper.selectList(new LambdaQueryWrapperX<DataSourceDO>().eqIfPresent(DataSourceDO::getType, type));
    }

    @Override
    public List<DataSourceRespVO> list() {
        return dataSourceMapper.selectListVO();
    }


//
//    @Override
//    public List<DataSourceFiledReqVO> getList(Integer type) {
//
//
//        List<DataSourceDO> dataSourceDOS = dataSourceMapper.selectByType();
//
//
//        List<DataSourceFiledReqVO> bean = BeanUtils.toBean(dataSourceDOS, DataSourceFiledReqVO.class);
//
//
//        List<Long> ids = dataSourceDOS.stream().map(DataSourceDO::getId).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS = dataSourceFiledMapper.selectFiledList(ids);
//
//
//        List<Long> list = dataSourceFiledDOS.stream().filter(f -> f.getKey() == null).map(m -> m.getId()).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS1 = dataSourceFiledMapper.selectFiledList(list);
//
//
//        List<Long> list1 = dataSourceFiledDOS1.stream().filter(f -> f.getKey() == null).map(m -> m.getId()).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS2 = dataSourceFiledMapper.selectFiledList(list1);
//
//
//        List<Long> list2 = dataSourceFiledDOS2.stream().filter(f -> f.getKey() == null).map(m -> m.getId()).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS3 = dataSourceFiledMapper.selectFiledList(list2);
//
//
//        List<Long> list3 = dataSourceFiledDOS3.stream().filter(f -> f.getKey() == null).map(m -> m.getId()).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS4 = dataSourceFiledMapper.selectFiledList(list3);
//
//
//        List<Long> list4 = dataSourceFiledDOS4.stream().filter(f -> f.getKey() == null).map(m -> m.getId()).toList();
//
//
//        List<DataSourceFiledReqVO> dataSourceFiledDOS5 = dataSourceFiledMapper.selectFiledList(list4);
//
//
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledDOS4) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS5.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledDOS3) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS4.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledDOS2) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS3.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledDOS1) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS2.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledDOS) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS1.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//
//
//        for (DataSourceFiledReqVO dataSourceFiledDO : bean) {
//            dataSourceFiledDO.setChildren(dataSourceFiledDOS.stream().filter(f->conversion(f.getSourceId()).contains(dataSourceFiledDO.getId())).toList());
//
//        }
//
//        return bean;
//
//    }


    @Override
    public List<DataSourceFiledReqVO> getList(Integer type) {

        List<DataSourceDO> dataSourceDOS = dataSourceMapper.selectByType();

        List<DataSourceFiledReqVO> dataSourceFiledReqVOS = toBean(dataSourceDOS, DataSourceFiledReqVO.class);

        List<Long> ids = dataSourceDOS.stream().map(DataSourceDO::getId).toList();

        // 获取字段列表
        List<DataSourceFiledReqVO> dataSourceFiledDOS = dataSourceFiledMapper.selectFiledList(ids);

        // 递归填充子节点
        populateChildren(dataSourceFiledDOS);

        // 为根节点填充子节点
        for (DataSourceFiledReqVO dataSourceFiledDO : dataSourceFiledReqVOS) {
            dataSourceFiledDO.setChildren(dataSourceFiledDOS.stream()
                    .filter(f -> conversion(f.getSourceId()).contains(dataSourceFiledDO.getId()))
                    .toList());
        }

        return dataSourceFiledReqVOS;

    }


    /**
     * 递归填充子节点
     *
     * @param parentList 父节点列表
     */
    private void populateChildren(List<DataSourceFiledReqVO> parentList) {
        if (parentList == null || parentList.isEmpty()) {
            return;
        }

        // 获取没有key的节点ID
        List<Long> ids = parentList.stream()
//                .filter(f -> f.getKeyName() == null)
                .map(DataSourceFiledReqVO::getId)
                .distinct()
                .toList();

        if (ids.isEmpty()) {
            return;
        }

        // 获取子节点列表
        List<DataSourceFiledReqVO> childList = dataSourceFiledMapper.selectFiledList(ids);
        if (childList.isEmpty()) {
            return;
        }

        // 为每个父节点填充子节点并递归处理子节点
        for (DataSourceFiledReqVO parent : parentList) {
            List<DataSourceFiledReqVO> children = childList.stream()
                    .filter(f -> conversion(f.getSourceId()).contains(parent.getId()))
                    .toList();
            parent.setChildren(children);

            // 递归处理子节点
            populateChildren(children);
        }
    }




    @Override
    public String getKeyNameData(Long machineId,Long planId)  {


        StringBuilder data = new StringBuilder();

        List<Integer> parentSourceId = new ArrayList<>();

        List<MachineDataSourceDO> dataSourceDOS = buildMachineDataSourceByMachineId(machineId, MACHINE_DATA_SOURCE);


        for (MachineDataSourceDO dataSourceDO : dataSourceDOS) {

            parentSourceId.addAll(dataSourceDO.getDataSource().stream().map(DataSource::getParentSourceId).toList());

        }

        parentSourceId = parentSourceId.stream().distinct().toList();


        for (Integer aLong : parentSourceId) {

            switch (aLong) {

                // 生产单基础信息
                // 生产单经销商信息
                // 生产单终端客户信息
                case 1543, 68, 80 -> {
                    String machineDataSourceKeyName = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiDataGetPlan(planId, machineDataSourceKeyName));
                }


                // 生产单组织信息
                case 61 -> {
                    String machineDataSourceKeyName1 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(dataQuery.dataGetOrgan(machineDataSourceKeyName1));
                }


                // 生产单业务员信息
                // 生产单拆单员信息
                case 74, 92 -> {
                    String machineDataSourceKeyName2 = getMachineDataSourceKeyName(machineId, aLong);
                    List<String> nameList = orderPlanApi.apiGetOrders(planId, aLong == 74);
                    data.append(dataQuery.dataGetUser(machineDataSourceKeyName2, nameList));
                }


                // 排单基础信息
                case 98 -> {
                    String machineDataSourceKeyName3 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.getPlan(planId, machineDataSourceKeyName3));
                }


                // 排单板材的大板用量信息
                case 110 -> {
                    List<String> machineDataSourceKeyName4 = buildMachineDataSourceByParentSourceId(machineId, aLong, MACHINE_DATA_SOURCE)
                            .get(0)
                            .getDataSource()
                            .stream().map(DataSource::getKeyName).toList();
                    data.append(orderPlanApi.apiGetEsPlan(planId, machineDataSourceKeyName4));
                }


                // 排单板材的余料板用量信息
                // 物料(商品)板材信息的余料信息
                case 119, 822 -> {
                    String machineDataSourceKeyName5 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiGetPlanRemainPlate(planId, machineDataSourceKeyName5));
                }


                // 排单板件的基础信息
                // 排单板件的规格尺寸的成品尺寸信息
                // 排单板件的规格尺寸的拆单尺寸信息
                // 雕刻机加工概要信息
                // 排单钻孔机(大板上下钻)加工信息概要
                // 排单钻孔机(小板)加工信息概要
                // 板件中板材基础信息
                // 板件中的基础信息的成品尺寸
                case 140, 204, 209, 446, 552, 657, 846, 907 -> {
                    String machineDataSourceKeyName6 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiGetPlanPlate(planId, machineDataSourceKeyName6));
                }


                // 排单板件的备注信息
                // 排单板件的规格尺寸的开料尺寸信息
                // 板件中板材基础信息的备注信息
                // 板件中基础信息的开料尺寸
                case 141, 213, 853, 908 -> {
                    List<String> machineDataSourceKeyName7 = buildMachineDataSourceByParentSourceId(machineId, aLong, MACHINE_DATA_SOURCE)
                            .get(0)
                            .getDataSource()
                            .stream().map(DataSource::getKeyName).toList();
                    data.append(orderPlanApi.apiGetEsPlate(planId, machineDataSourceKeyName7));
                }


                // 生产单中的房间信息
                // 生产单中的柜体信息
                // 板件中的基础信息的房间信息
                // 板件中的基础信息的柜体信息
                case  1544,1545, 881, 889 -> {
                    String machineDataSourceKeyName8 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiGetPlanBodyOrRoom(planId, machineDataSourceKeyName8));
                }



                // 板件信息的加工组信息
                case  897 -> {
                    String machineDataSourceKeyName9 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiGetPlanGroup(planId, machineDataSourceKeyName9));
                }


                // 物料(商品)的板材信息
                // 排单排版信息-大板信息
                case 808, 416 -> {
                    String machineDataSourceKeyName10 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.getGoods(planId, machineDataSourceKeyName10));
                }


                // 物料(商品)的配件信息
                case 809 -> {
                    String machineDataSourceKeyName11 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(orderPlanApi.apiGetPlanParts(planId, machineDataSourceKeyName11));
                }


                // 物料(商品)的配件备注信息
                case 840 -> {
                    List<String> machineDataSourceKeyName12 = buildMachineDataSourceByParentSourceId(machineId, aLong, MACHINE_DATA_SOURCE)
                            .get(0)
                            .getDataSource()
                            .stream().map(DataSource::getKeyName).toList();
                    data.append(orderPlanApi.apiGetEsParts(planId, machineDataSourceKeyName12));
                }

                // 排单信息的生产线信息
                case 1483  -> {
                    Integer machineType = machineMapper.selectById(machineId).getMachineType();
                    if (machineType.equals(MachineTypeEnum.CUTTING.getType())){
                        String machineDataSourceKeyName13 = getMachineDataSourceKeyName(machineId, aLong);
                        data.append(dataQuery.dataGetMachine(machineDataSourceKeyName13,machineId));
                    }
                }

                // 排单信息的机台信息
                case 1487 -> {

                    String machineDataSourceKeyName14 = getMachineDataSourceKeyName(machineId, aLong);
                    data.append(dataQuery.dataGetMachine(machineDataSourceKeyName14,machineId));
                }

                default -> {
                    // do nothing
                }
            }
        }

        return data.toString();


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveMachineKeyName(List<MachineDataSourceDO> machineDataSourceDOS) {

        Long machineId = machineDataSourceDOS.stream().map(MachineDataSourceDO::getMachineId).distinct().toList().get(0);
        /*
        * 目前数据源保存有两种方式:
        * 1. 每回保存全都传过来,先将机台的原数据源删除,再重新保存
        * 2. 传过来的时候将新增的和删除的区分开来,我这边做数据处理
        *
        * */
        // todo 目前先实现第一种：每回保存时传入全部数据，先删除原机台字段信息，再保存
        deleteByMachineId(machineId,MACHINE_DATA_SOURCE);
        batchSaveMachineDataSource(machineDataSourceDOS);

        return Boolean.TRUE;

    }


    public static List<String> convertToSnakeCase(List<String> camelCaseList) {
        List<String> snakeCaseList = new ArrayList<>();

        // 字段ID改成数据库的形式
        camelCaseList = camelCaseList.stream().map(key -> key.replace("_", "")).toList();


        for (String camelCaseStr : camelCaseList) {
            StringBuilder snakeCaseStr = new StringBuilder();

            for (int i = 0; i < camelCaseStr.length(); i++) {
                char c = camelCaseStr.charAt(i);
                // 如果字符是大写字母，并且不是第一个字符，则添加下划线
                if (Character.isUpperCase(c) && i != 0) {
                    snakeCaseStr.append('_');
                }
                // 转换字符为小写
                snakeCaseStr.append(Character.toLowerCase(c));
            }

            snakeCaseList.add(snakeCaseStr.toString());
        }

        return snakeCaseList;
    }


    public void batchSaveMachineDataSource(List<MachineDataSourceDO> machineDataSourceDOS) {
        try {
            BulkResponse bulkResponse = esDocumentService.bulkCreate(MACHINE_DATA_SOURCE, machineDataSourceDOS);
            boolean errors = bulkResponse.errors();
            if (errors) {
                log.error(bulkResponse.items().toString());
                throw new ServiceException(500, "未知异常");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }

    }






    private String getMachineDataSourceKeyName(Long machineId, Integer parentSourceId) {

        return convertToSnakeCase(buildMachineDataSourceByParentSourceId(machineId, parentSourceId, MACHINE_DATA_SOURCE)
                .get(0)
                .getDataSource()
                .stream().map(DataSource::getKeyName).toList())
                .toString();

    }



    // 根据机台ID和父级ID，查询对应的数据源字段
    private List<MachineDataSourceDO> buildMachineDataSourceByParentSourceId(Long machineId,Integer parentSourceId, String index) {

        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index);

        builder.query(q -> q.bool(b -> b
                .must(m->m.term(t->t.field(FIELD_MACHINEID).value(machineId)))
                .must(m->m.match(t->t.field("dataSource.parentSourceId").query(parentSourceId)))));

        try {
            SearchResponse<MachineDataSourceDO> search = elasticsearchClient.search(builder.build(), MachineDataSourceDO.class);
            List<Hit<MachineDataSourceDO>> hits = search.hits().hits();
            if (CollUtil.isNotEmpty(hits)) {
                return hits.stream().map(Hit::source).collect(Collectors.toList());
            }
            return new ArrayList<>();
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new ServiceException(INTERNAL_SERVER_ERROR);
        }
    }



    // 根据机台ID查询机台对应的数据源字段信息
    private List<MachineDataSourceDO> buildMachineDataSourceByMachineId(Long machineId, String index) {

        SearchRequest.Builder builder = new SearchRequest.Builder();
        builder.index(index);
        builder.query(q -> q.term(b -> b.field(FIELD_MACHINEID).value(machineId)));

        try {
            SearchResponse<MachineDataSourceDO> search = elasticsearchClient.search(builder.build(), MachineDataSourceDO.class);
            List<Hit<MachineDataSourceDO>> hits = search.hits().hits();
            if (CollUtil.isNotEmpty(hits)) {
                return hits.stream().map(Hit::source).collect(Collectors.toList());
            }
            return new ArrayList<>();
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new ServiceException(INTERNAL_SERVER_ERROR);
        }
    }



    // 根据机台ID删除对应的数据源ES信息
    public void deleteByMachineId(Long machineId, String index) {
        DeleteByQueryRequest.Builder builder = new DeleteByQueryRequest.Builder();
        builder.index(index);
        builder.query(q -> q.term(t -> t.field(FIELD_MACHINEID).value(machineId)));
        try {
            DeleteByQueryResponse response = elasticsearchClient.deleteByQuery(builder.build());
            log.info("Deleted {} documents with planId {}", response.deleted(), machineId);
        } catch (IOException e) {
            log.error("Error deleting documents with planId {}: {}", machineId, e.getMessage());
            throw new ServiceException(ES_DATA_ERROR);
        }
    }



    private List<Long> conversion(String sourceId) {

        return Arrays.stream(sourceId.split(","))
                .map(Long::parseLong)
                .toList();
    }

}