package cn.fateverse.query.service;

import cn.fateverse.common.core.result.page.TableDataInfo;
import cn.fateverse.query.entity.DynamicPage;
import cn.fateverse.query.entity.UniCon;
import cn.fateverse.query.entity.UniQuery;
import cn.fateverse.query.entity.bo.SqlSelect;
import cn.fateverse.query.entity.bo.TopologySelect;
import cn.fateverse.query.mapper.UniConMapper;
import cn.fateverse.query.entity.dto.UniConDto;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 动态数据查询
 *
 * @author Clay
 * @date 2023-08-05
 */
@Slf4j
@Service
public class DynamicDataSearchService {

    private final UniConMapper uniConMapper;

    private final DynamicDataSourceTableService dynamicDataSourceTableService;

    public DynamicDataSearchService(UniConMapper uniConMapper,
                                    DynamicDataSourceTableService dynamicDataSourceTableService) {
        this.uniConMapper = uniConMapper;
        this.dynamicDataSourceTableService = dynamicDataSourceTableService;
    }

    /**
     * 查询数据信息
     *
     * @param list  查询条件列表
     * @param query 查询对象
     * @return 查询结果
     */
    public TableDataInfo<Map<String, Object>> searchData(List<UniConDto> list, UniQuery query) {
        return searchData(list, query, null, Boolean.TRUE);
    }

    /**
     * 查询数据信息 (可以设置是否分页)
     *
     * @param list   查询条件列表
     * @param query  查询对象
     * @param page   分页信息
     * @param paging 是否分页
     * @return 查询结果
     */
    public TableDataInfo<Map<String, Object>> searchData(List<UniConDto> list, UniQuery query, DynamicPage page, Boolean paging) {
        List<Long> ids = new ArrayList<>();
        Map<Long, Object> queryMap = new HashMap<>();
        list.forEach(con -> {
            ids.add(con.getUcId());
            queryMap.put(con.getUcId(), con.getQuery());
        });
        List<UniCon> uniConList;
        if (ids.isEmpty()) {
            uniConList = new ArrayList<>();
        } else {
            uniConList = uniConMapper.selectByQueryIdAndUcIdList(query.getId(), ids);
        }
        uniConList = uniConList.stream().filter(uniCon -> null != queryMap.get(uniCon.getUcId()))
                .peek(uniCon -> uniCon.setUcMock(queryMap.get(uniCon.getUcId())))
                .collect(Collectors.toList());
        if (query.getType() == 1) {
            SqlSelect select = new SqlSelect();
            select.setSelectSql(query.getUqSql());
            select.setUniCons(uniConList);
            return dynamicDataSourceTableService.uniQuerySql(select, page, paging, query.getDataSourceId());
        } else {
            List<String> relevance = JSON.parseArray(query.getRelevance(), String.class);
            TopologySelect select = TopologySelect.builder()
                    .selectKey(query.getSelectKey())
                    .tableInfo(query.getTableInfo())
                    .single(query.getSingle())
                    .relevance(relevance)
                    .uniCons(uniConList)
                    .build();
            return dynamicDataSourceTableService.uniQueryTopology(select, page, paging, query.getDataSourceId());
        }
    }

}
