package com.ycwl.basic.puzzle.fill.datasource;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 数据源解析器
 * 使用策略模式,根据dataSource类型动态选择解析策略
 */
@Slf4j
@Component
public class DataSourceResolver {

    private final Map<String, DataSourceStrategy> strategyMap;
    private final ObjectMapper objectMapper;

    @Autowired
    public DataSourceResolver(List<DataSourceStrategy> strategies, ObjectMapper objectMapper) {
        this.strategyMap = strategies.stream()
                .collect(Collectors.toMap(
                        DataSourceStrategy::getSupportedType,
                        Function.identity()
                ));
        this.objectMapper = objectMapper;
        log.info("初始化数据源解析器,已注册{}个策略: {}", strategyMap.size(), strategyMap.keySet());
    }

    /**
     * 解析数据源,返回填充值
     *
     * @param dataSource 数据源类型
     * @param sourceFilterJson 过滤条件(JSON字符串)
     * @param sortStrategy 排序策略
     * @param fallbackValue 降级默认值
     * @param context 解析上下文
     * @return 填充值
     */
    public String resolve(String dataSource,
                          String sourceFilterJson,
                          String sortStrategy,
                          String fallbackValue,
                          DataSourceContext context) {
        DataSourceStrategy strategy = strategyMap.get(dataSource);

        if (strategy == null) {
            log.warn("未找到数据源类型[{}]对应的解析策略", dataSource);
            return fallbackValue;
        }

        try {
            JsonNode sourceFilter = null;
            if (sourceFilterJson != null && !sourceFilterJson.isEmpty()) {
                sourceFilter = objectMapper.readTree(sourceFilterJson);
            }

            String value = strategy.resolve(sourceFilter, sortStrategy, context);

            if (value == null || value.isEmpty()) {
                log.debug("数据源[{}]解析结果为空,使用降级值: {}", dataSource, fallbackValue);
                return fallbackValue;
            }

            return value;
        } catch (Exception e) {
            log.error("数据源[{}]解析异常,使用降级值: {}", dataSource, fallbackValue, e);
            return fallbackValue;
        }
    }
}
