package com.cube.sql;

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

/**
 * Enhanced ParsedSQL with Cubic Index support
 */
public class IndexedParsedSQL {
    
    private final SQLParser.SQLType type;
    private final String table;
    private final String keyspace;
    private final Map<String, String> columns;
    private final Map<String, String> whereClause;
    private final List<String> selectColumns;
    private final Map<String, String> columnDefinitions;
    private final String primaryKey;
    
    // Index-specific fields
    private final String indexName;
    private final String indexColumn;
    private final IndexType indexType;
    private final String originalSQL;
    
    public enum IndexType {
        PRIMARY,    // Primary key index (automatic)
        SECONDARY,  // Secondary index on column
        CUBIC,      // Cubic Index Tree
        COMPOSITE   // Composite index on multiple columns
    }
    
    public IndexedParsedSQL(SQLParser.SQLType type, String keyspace, String table,
                           Map<String, String> columns, Map<String, String> whereClause,
                           List<String> selectColumns, Map<String, String> columnDefinitions,
                           String primaryKey, String indexName, String indexColumn,
                           IndexType indexType, String originalSQL) {
        this.type = type;
        this.keyspace = keyspace;
        this.table = table;
        this.columns = columns != null ? columns : new LinkedHashMap<>();
        this.whereClause = whereClause != null ? whereClause : new LinkedHashMap<>();
        this.selectColumns = selectColumns != null ? selectColumns : new ArrayList<>();
        this.columnDefinitions = columnDefinitions != null ? columnDefinitions : new LinkedHashMap<>();
        this.primaryKey = primaryKey;
        this.indexName = indexName;
        this.indexColumn = indexColumn;
        this.indexType = indexType;
        this.originalSQL = originalSQL;
    }
    
    // Getters
    public SQLParser.SQLType getType() { return type; }
    public String getTable() { return table; }
    public String getKeyspace() { return keyspace; }
    public String getFullTableName() { return keyspace + "." + table; }
    public Map<String, String> getColumns() { return columns; }
    public Map<String, String> getWhereClause() { return whereClause; }
    public List<String> getSelectColumns() { return selectColumns; }
    public Map<String, String> getColumnDefinitions() { return columnDefinitions; }
    public String getPrimaryKey() { return primaryKey; }
    public String getIndexName() { return indexName; }
    public String getIndexColumn() { return indexColumn; }
    public IndexType getIndexType() { return indexType; }
    public String getOriginalSQL() { return originalSQL; }
    
    // Helper methods
    public boolean hasWhereClause() {
        return whereClause != null && !whereClause.isEmpty();
    }
    
    public String getWhereColumn() {
        return hasWhereClause() ? whereClause.keySet().iterator().next() : null;
    }
    
    public String getWhereValue() {
        return hasWhereClause() ? whereClause.values().iterator().next() : null;
    }
    
    public List<String> getColumnNames() {
        return new ArrayList<>(columns.keySet());
    }
    
    public List<String> getValues() {
        return new ArrayList<>(columns.values());
    }
    
    public boolean isIndexedQuery() {
        return indexName != null || indexColumn != null;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("IndexedParsedSQL{");
        sb.append("type=").append(type);
        sb.append(", table=").append(keyspace).append(".").append(table);
        if (indexName != null) {
            sb.append(", index=").append(indexName);
        }
        if (indexColumn != null) {
            sb.append(", indexColumn=").append(indexColumn);
        }
        sb.append("}");
        return sb.toString();
    }
    
    // Builder for easier construction
    public static class Builder {
        private SQLParser.SQLType type;
        private String table;
        private String keyspace = "default";
        private Map<String, String> columns = new LinkedHashMap<>();
        private Map<String, String> whereClause = new LinkedHashMap<>();
        private List<String> selectColumns = new ArrayList<>();
        private Map<String, String> columnDefinitions = new LinkedHashMap<>();
        private String primaryKey;
        private String indexName;
        private String indexColumn;
        private IndexType indexType = IndexType.PRIMARY;
        private String originalSQL;
        
        public Builder type(SQLParser.SQLType type) {
            this.type = type;
            return this;
        }
        
        public Builder table(String table) {
            this.table = table;
            return this;
        }
        
        public Builder keyspace(String keyspace) {
            this.keyspace = keyspace;
            return this;
        }
        
        public Builder columns(Map<String, String> columns) {
            this.columns = columns;
            return this;
        }
        
        public Builder whereClause(Map<String, String> whereClause) {
            this.whereClause = whereClause;
            return this;
        }
        
        public Builder selectColumns(List<String> selectColumns) {
            this.selectColumns = selectColumns;
            return this;
        }
        
        public Builder columnDefinitions(Map<String, String> columnDefinitions) {
            this.columnDefinitions = columnDefinitions;
            return this;
        }
        
        public Builder primaryKey(String primaryKey) {
            this.primaryKey = primaryKey;
            return this;
        }
        
        public Builder indexName(String indexName) {
            this.indexName = indexName;
            return this;
        }
        
        public Builder indexColumn(String indexColumn) {
            this.indexColumn = indexColumn;
            return this;
        }
        
        public Builder indexType(IndexType indexType) {
            this.indexType = indexType;
            return this;
        }
        
        public Builder originalSQL(String originalSQL) {
            this.originalSQL = originalSQL;
            return this;
        }
        
        public IndexedParsedSQL build() {
            return new IndexedParsedSQL(type, keyspace, table, columns, whereClause,
                selectColumns, columnDefinitions, primaryKey, indexName, indexColumn,
                indexType, originalSQL);
        }
    }
}
