package com.agent.management.rag.structured;

import com.agent.management.rag.capability.SqlSchemaSnapshot;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/** Text2SQL 单次请求使用的最小、真实数据库上下文。 */
public record StructuredQueryContext(
        Long dataSourceId,
        String dialect,
        String schemaVersion,
        String schemaFingerprint,
        String profileVersion,
        List<String> selectedTables,
        String minimalDdl,
        List<SqlSchemaSnapshot.ForeignKey> foreignKeys,
        List<StructuredRelationship> relationships,
        Map<String, List<Object>> sampledValues,
        Map<String, List<Map<String, Object>>> referenceRows,
        List<String> entityMentions,
        List<String> warnings) {

    public StructuredQueryContext {
        selectedTables = List.copyOf(selectedTables == null ? List.of() : selectedTables);
        foreignKeys = List.copyOf(foreignKeys == null ? List.of() : foreignKeys);
        relationships = List.copyOf(relationships == null ? List.of() : relationships);
        sampledValues = immutableMap(sampledValues);
        referenceRows = immutableRows(referenceRows);
        entityMentions = List.copyOf(entityMentions == null ? List.of() : entityMentions);
        warnings = List.copyOf(warnings == null ? List.of() : warnings);
    }

    public List<String> sampledValueFields() { return List.copyOf(sampledValues.keySet()); }

    public List<String> referenceTables() { return List.copyOf(referenceRows.keySet()); }

    private static Map<String, List<Object>> immutableMap(Map<String, List<Object>> source) {
        Map<String, List<Object>> result = new LinkedHashMap<>();
        if (source != null) source.forEach((key, value) -> result.put(key, List.copyOf(value)));
        return Map.copyOf(result);
    }

    private static Map<String, List<Map<String, Object>>> immutableRows(
            Map<String, List<Map<String, Object>>> source) {
        Map<String, List<Map<String, Object>>> result = new LinkedHashMap<>();
        if (source != null) source.forEach((key, rows) -> result.put(key,
                rows.stream().map(row -> Map.copyOf(new LinkedHashMap<>(row))).toList()));
        return Map.copyOf(result);
    }
}
