"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VectorDatabaseConfig = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * Vector Database Configuration Component
 *
 * A comprehensive React component for configuring and validating vector database settings
 * with real-time validation and provider-specific configuration options.
 */
const react_1 = require("react");
const ui_1 = require("../ui");
const icons_1 = require("../icons");
// Debounce function for performance optimization
function debounce(func, wait) {
    let timeout;
    const debouncedFunction = function (...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
    };
    debouncedFunction.cancel = function () {
        clearTimeout(timeout);
    };
    return debouncedFunction;
}
// Import validation schemas from MCP
const vector_model_dimensions_1 = require("./vector-model-dimensions");
// Vector database types
const VECTOR_DATABASE_TYPES = [
    { value: 'pinecone', label: 'Pinecone', description: 'Cloud-based vector database with high scalability' },
    { value: 'qdrant', label: 'Qdrant', description: 'High-performance vector similarity search engine' },
    { value: 'weaviate', label: 'Weaviate', description: 'Knowledge graph with vector capabilities' },
    { value: 'elasticsearch', label: 'Elasticsearch', description: 'Full-text search with vector support' },
    { value: 'pgvector', label: 'PGVector', description: 'Vector extension for PostgreSQL' },
    { value: 'redis', label: 'Redis Vector', description: 'Vector functionality in Redis' },
    { value: 'faiss', label: 'FAISS', description: 'Facebook AI Similarity Search' },
    { value: 'local', label: 'Local Storage', description: 'File-based vector storage for development' },
    { value: 'memory', label: 'Memory Storage', description: 'In-memory vector storage for testing' },
    { value: 'drupal', label: 'Drupal Integration', description: 'Drupal vector storage integration' }
];
// Embedding models
const EMBEDDING_MODELS = [
    { value: 'text-embedding-ada-002', label: 'OpenAI Ada 002', provider: 'openai', dimensions: 1536 },
    { value: 'text-embedding-3-small', label: 'OpenAI Text Embedding 3 Small', provider: 'openai', dimensions: 1536 },
    { value: 'text-embedding-3-large', label: 'OpenAI Text Embedding 3 Large', provider: 'openai', dimensions: 3072 },
    { value: 'bfllm-embeddings-en', label: 'BFLLM English', provider: 'bfllm', dimensions: 1024 },
    { value: 'bfllm-embeddings-multi', label: 'BFLLM Multilingual', provider: 'bfllm', dimensions: 1536 },
    { value: 'bfllm-embeddings-image', label: 'BFLLM Image', provider: 'bfllm', dimensions: 2048 },
    { value: 'sentence-transformers/all-mpnet-base-v2', label: 'MPNet Base v2', provider: 'huggingface', dimensions: 768 },
    { value: 'native-ai-embeddings-base', label: 'Native AI Base', provider: 'native-ai', dimensions: 768 },
    { value: 'native-ai-embeddings-large', label: 'Native AI Large', provider: 'native-ai', dimensions: 1536 }
];
// Distance metrics
const DISTANCE_METRICS = [
    { value: 'cosine', label: 'Cosine Similarity', description: 'Measures the cosine of the angle between vectors' },
    { value: 'euclidean', label: 'Euclidean Distance', description: 'Measures the straight-line distance between vectors' },
    { value: 'dot', label: 'Dot Product', description: 'Measures the product of corresponding vector elements' }
];
/**
 * Vector Database Configuration Component
 */
const VectorDatabaseConfig = ({ initialConfig = {}, onChange, showValidation = true, enableTesting = true, showEmbeddingConfig = true, enableAiSuggestions = false, variant = 'default', helpText, }) => {
    // State for configuration
    const [config, setConfig] = (0, react_1.useState)({
        type: 'memory',
        collection: '',
        dimensions: 1536,
        url: '',
        apiKey: '',
        metric: 'cosine',
        hybridSearch: false,
        options: {},
        ...initialConfig
    });
    // State for embedding model
    const [embeddingModel, setEmbeddingModel] = (0, react_1.useState)(initialConfig?.embeddingModel || 'text-embedding-ada-002');
    // Validation state
    const [errors, setErrors] = (0, react_1.useState)({});
    const [validationStatus, setValidationStatus] = (0, react_1.useState)('untested');
    const [isValid, setIsValid] = (0, react_1.useState)(false);
    const [activeTab, setActiveTab] = (0, react_1.useState)(0);
    // Testing state
    const [isTesting, setIsTesting] = (0, react_1.useState)(false);
    const [testResult, setTestResult] = (0, react_1.useState)(null);
    // Validation function
    const validateConfig = () => {
        const newErrors = {};
        let valid = true;
        // Validate common required fields
        if (!config.collection) {
            newErrors.collection = 'Collection/index name is required';
            valid = false;
        }
        if (!config.dimensions) {
            newErrors.dimensions = 'Dimensions are required';
            valid = false;
        }
        else if (!Number.isInteger(config.dimensions) || config.dimensions <= 0) {
            newErrors.dimensions = 'Dimensions must be a positive integer';
            valid = false;
        }
        // Check if dimensions match embedding model
        if (showEmbeddingConfig && embeddingModel && vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel]) {
            const expectedDimensions = vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel];
            if (config.dimensions !== expectedDimensions) {
                newErrors.dimensions = `Must be ${expectedDimensions} to match selected model`;
                valid = false;
            }
        }
        // Provider-specific validation
        switch (config.type) {
            case 'pinecone':
                if (!config.url) {
                    newErrors.url = 'Pinecone URL is required';
                    valid = false;
                }
                if (!config.apiKey) {
                    newErrors.apiKey = 'API key is required for Pinecone';
                    valid = false;
                }
                // Validate options
                if (!config.options?.environment) {
                    newErrors['options.environment'] = 'Environment is required for Pinecone';
                    valid = false;
                }
                if (!config.options?.projectId) {
                    newErrors['options.projectId'] = 'Project ID is required for Pinecone';
                    valid = false;
                }
                break;
            case 'qdrant':
                if (!config.url) {
                    newErrors.url = 'Qdrant URL is required';
                    valid = false;
                }
                break;
            case 'weaviate':
                if (!config.url) {
                    newErrors.url = 'Weaviate URL is required';
                    valid = false;
                }
                if (!config.options?.schemaClass) {
                    newErrors['options.schemaClass'] = 'Schema class is required for Weaviate';
                    valid = false;
                }
                else if (!/^[A-Z][a-zA-Z0-9]*$/.test(config.options.schemaClass)) {
                    newErrors['options.schemaClass'] = 'Schema class must start with a capital letter and contain only alphanumeric characters';
                    valid = false;
                }
                break;
            case 'elasticsearch':
                if (!config.url) {
                    newErrors.url = 'Elasticsearch URL is required';
                    valid = false;
                }
                if (!config.options?.index) {
                    newErrors['options.index'] = 'Index name is required for Elasticsearch';
                    valid = false;
                }
                break;
            case 'pgvector':
                if (!config.url) {
                    newErrors.url = 'PostgreSQL connection string is required';
                    valid = false;
                }
                else if (!config.url.startsWith('postgres://') && !config.url.startsWith('postgresql://')) {
                    newErrors.url = 'Must be a valid PostgreSQL connection string';
                    valid = false;
                }
                if (!config.options?.tableName) {
                    newErrors['options.tableName'] = 'Table name is required for PGVector';
                    valid = false;
                }
                break;
            case 'redis':
                if (!config.url) {
                    newErrors.url = 'Redis connection string is required';
                    valid = false;
                }
                else if (!config.url.startsWith('redis://') && !config.url.startsWith('rediss://')) {
                    newErrors.url = 'Must be a valid Redis connection string';
                    valid = false;
                }
                break;
            case 'drupal':
                if (!config.url) {
                    newErrors.url = 'Drupal API endpoint is required';
                    valid = false;
                }
                if (!config.options?.endpoint) {
                    newErrors['options.endpoint'] = 'API endpoint is required for Drupal integration';
                    valid = false;
                }
                break;
        }
        setErrors(newErrors);
        setIsValid(valid);
        setValidationStatus(valid ? 'success' : 'error');
        if (onChange) {
            onChange(config, valid);
        }
        return valid;
    };
    // Server-side validation function
    const validateWithServer = async () => {
        if (!showValidation)
            return;
        try {
            setValidationStatus('pending');
            // Call the validation API
            const response = await fetch('/api/experience-builder/vector/validate', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    config,
                    embeddingModel: showEmbeddingConfig ? embeddingModel : undefined
                }),
            });
            const result = await response.json();
            if (result.valid) {
                setErrors({});
                setIsValid(true);
                setValidationStatus('success');
            }
            else {
                const newErrors = {};
                // Map server errors to form fields
                if (result.errors && Array.isArray(result.errors)) {
                    result.errors.forEach(error => {
                        if (typeof error === 'string') {
                            // Handle generic errors
                            if (error.includes('dimensions'))
                                newErrors.dimensions = error;
                            else if (error.includes('collection'))
                                newErrors.collection = error;
                            else if (error.includes('URL'))
                                newErrors.url = error;
                            else if (error.includes('API key'))
                                newErrors.apiKey = error;
                            else
                                newErrors._generic = error;
                        }
                        else if (error.field) {
                            // Handle structured errors with field information
                            newErrors[error.field] = error.message;
                        }
                    });
                }
                setErrors(newErrors);
                setIsValid(false);
                setValidationStatus('error');
            }
            return result.valid;
        }
        catch (error) {
            console.error('Error validating configuration:', error);
            // Fall back to client-side validation
            return validateConfigClient();
        }
    };
    // Client-side validation (fallback)
    const validateConfigClient = () => {
        const newErrors = {};
        let valid = true;
        // Validate common required fields
        if (!config.collection) {
            newErrors.collection = 'Collection/index name is required';
            valid = false;
        }
        if (!config.dimensions) {
            newErrors.dimensions = 'Dimensions are required';
            valid = false;
        }
        else if (!Number.isInteger(config.dimensions) || config.dimensions <= 0) {
            newErrors.dimensions = 'Dimensions must be a positive integer';
            valid = false;
        }
        // Check if dimensions match embedding model
        if (showEmbeddingConfig && embeddingModel && vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel]) {
            const expectedDimensions = vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel];
            if (config.dimensions !== expectedDimensions) {
                newErrors.dimensions = `Must be ${expectedDimensions} to match selected model`;
                valid = false;
            }
        }
        // Provider-specific validation
        switch (config.type) {
            case 'pinecone':
                if (!config.url) {
                    newErrors.url = 'Pinecone URL is required';
                    valid = false;
                }
                if (!config.apiKey) {
                    newErrors.apiKey = 'API key is required for Pinecone';
                    valid = false;
                }
                break;
            case 'qdrant':
                if (!config.url) {
                    newErrors.url = 'Qdrant URL is required';
                    valid = false;
                }
                break;
            case 'weaviate':
                if (!config.url) {
                    newErrors.url = 'Weaviate URL is required';
                    valid = false;
                }
                break;
            case 'elasticsearch':
                if (!config.url) {
                    newErrors.url = 'Elasticsearch URL is required';
                    valid = false;
                }
                break;
            case 'pgvector':
                if (!config.url) {
                    newErrors.url = 'PostgreSQL connection string is required';
                    valid = false;
                }
                break;
            case 'redis':
                if (!config.url) {
                    newErrors.url = 'Redis connection string is required';
                    valid = false;
                }
                break;
            case 'drupal':
                if (!config.url) {
                    newErrors.url = 'Drupal API endpoint is required';
                    valid = false;
                }
                break;
        }
        setErrors(newErrors);
        setIsValid(valid);
        setValidationStatus(valid ? 'success' : 'error');
        if (onChange) {
            onChange(config, valid);
        }
        return valid;
    };
    // Combined validation function
    const validateConfig = async () => {
        try {
            // Try server-side validation first
            return await validateWithServer();
        }
        catch (error) {
            // Fall back to client-side validation
            console.error('Server validation failed, using client-side validation:', error);
            return validateConfigClient();
        }
    };
    // Throttled validation for better performance
    const debouncedValidate = (0, react_1.useCallback)(debounce(() => {
        validateConfig();
    }, 500), [config, embeddingModel, showValidation]);
    // Validate when config changes
    (0, react_1.useEffect)(() => {
        if (showValidation) {
            debouncedValidate();
        }
        return () => {
            debouncedValidate.cancel();
        };
    }, [config, embeddingModel, showValidation, debouncedValidate]);
    // Update dimensions when model changes
    (0, react_1.useEffect)(() => {
        if (showEmbeddingConfig && embeddingModel && vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel]) {
            const modelDimensions = vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel];
            if (config.dimensions !== modelDimensions) {
                handleInputChange('dimensions', modelDimensions);
            }
        }
    }, [embeddingModel]);
    // Input change handler
    const handleInputChange = (field, value) => {
        if (field.includes('.')) {
            // Handle nested fields (options)
            const [parent, child] = field.split('.');
            setConfig({
                ...config,
                [parent]: {
                    ...(config[parent] || {}),
                    [child]: value,
                },
            });
        }
        else {
            setConfig({ ...config, [field]: value });
        }
        // Set validation status to pending
        setValidationStatus('pending');
    };
    // Get recommended configuration from server
    const getRecommendedConfig = async () => {
        try {
            const response = await fetch(`/api/experience-builder/vector/recommended-config/${config.type}/${embeddingModel}`, {
                method: 'GET',
                headers: {
                    'Accept': 'application/json',
                },
            });
            const result = await response.json();
            if (result.config) {
                // Apply recommended configuration while preserving user's selection
                const recommendedConfig = result.config;
                // Merge configurations, prioritizing recommended settings
                // but keeping user's type, collection if already set, and dimensions
                setConfig({
                    ...recommendedConfig,
                    type: config.type, // Keep the current type
                    collection: config.collection || recommendedConfig.collection,
                    dimensions: vector_model_dimensions_1.MODEL_DIMENSIONS[embeddingModel] || recommendedConfig.dimensions
                });
                // Show success notification
                setTestResult({
                    success: true,
                    timestamp: new Date().toISOString(),
                    message: 'Applied recommended configuration',
                    details: {
                        type: config.type,
                        status: 'recommendation_applied'
                    }
                });
                // Validate new configuration
                setTimeout(() => {
                    validateConfig();
                }, 100);
            }
        }
        catch (error) {
            console.error('Error getting recommended configuration:', error);
            // Show error notification
            setTestResult({
                success: false,
                timestamp: new Date().toISOString(),
                message: 'Could not get recommended configuration',
                details: { error: error.message }
            });
        }
    };
    // Test connection using server API
    const testConnection = async () => {
        setIsTesting(true);
        try {
            // Validate configuration first
            const isValid = await validateConfig();
            if (!isValid) {
                setTestResult({
                    success: false,
                    timestamp: new Date().toISOString(),
                    message: 'Cannot test connection with invalid configuration. Please fix validation errors.',
                    details: { status: 'validation_failed', errors }
                });
                setIsTesting(false);
                return;
            }
            // Call the test connection API
            const response = await fetch('/api/experience-builder/vector/test-connection', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    config,
                }),
            });
            const result = await response.json();
            setTestResult({
                ...result,
                timestamp: new Date().toISOString(),
            });
        }
        catch (error) {
            console.error('Error testing connection:', error);
            setTestResult({
                success: false,
                timestamp: new Date().toISOString(),
                message: 'An error occurred while testing the connection',
                details: { error: error.message }
            });
        }
        finally {
            setIsTesting(false);
        }
    };
    // Get provider-specific options
    const renderProviderOptions = () => {
        switch (config.type) {
            case 'pinecone':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.environment']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Environment" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.environment || '', onChange: e => handleInputChange('options.environment', e.target.value), placeholder: "e.g. us-west1-gcp", error: Boolean(errors['options.environment']), helperText: errors['options.environment'] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Pinecone environment (e.g., us-west1-gcp)" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.projectId']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Project ID" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.projectId || '', onChange: e => handleInputChange('options.projectId', e.target.value), error: Boolean(errors['options.projectId']), helperText: errors['options.projectId'] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Pinecone project ID" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Namespace (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.namespace || '', onChange: e => handleInputChange('options.namespace', e.target.value), placeholder: "e.g. my-namespace" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Optional namespace for data partitioning" })] }) })] }));
            case 'weaviate':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.schemaClass']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Schema Class" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.schemaClass || '', onChange: e => handleInputChange('options.schemaClass', e.target.value), placeholder: "e.g. Document", error: Boolean(errors['options.schemaClass']), helperText: errors['options.schemaClass'] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Must start with capital letter (CamelCase)" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Text Property (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.textKey || '', onChange: e => handleInputChange('options.textKey', e.target.value), placeholder: "e.g. content" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Property name for text storage (defaults to \"text\")" })] }) })] }));
            case 'elasticsearch':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.index']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Index Name" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.index || '', onChange: e => handleInputChange('options.index', e.target.value), placeholder: "e.g. vector-index", error: Boolean(errors['options.index']), helperText: errors['options.index'] || 'Must be lowercase without spaces' })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Text Field (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.textField || '', onChange: e => handleInputChange('options.textField', e.target.value), placeholder: "e.g. content" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Field name for text (defaults to \"text\")" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Refresh Interval" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.refreshInterval || '', onChange: e => handleInputChange('options.refreshInterval', e.target.value), placeholder: "e.g. 1s" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Index refresh interval (e.g., 1s, 30s, 1m)" })] }) })] }));
            case 'pgvector':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.tableName']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Table Name" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.tableName || '', onChange: e => handleInputChange('options.tableName', e.target.value), placeholder: "e.g. vector_embeddings", error: Boolean(errors['options.tableName']), helperText: errors['options.tableName'] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Database table for vector storage" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Vector Column" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.vectorColumnName || '', onChange: e => handleInputChange('options.vectorColumnName', e.target.value), placeholder: "e.g. embedding" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Defaults to \"embedding\"" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Text Column" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.textColumnName || '', onChange: e => handleInputChange('options.textColumnName', e.target.value), placeholder: "e.g. content" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Defaults to \"content\"" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Metadata Column" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.metadataColumnName || '', onChange: e => handleInputChange('options.metadataColumnName', e.target.value), placeholder: "e.g. metadata" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Defaults to \"metadata\"" })] }) })] }));
            case 'redis':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Key Prefix (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.keyPrefix || '', onChange: e => handleInputChange('options.keyPrefix', e.target.value), placeholder: "e.g. vector:" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Prefix for Redis keys" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Vector Key Prefix (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.vectorKeyPrefix || '', onChange: e => handleInputChange('options.vectorKeyPrefix', e.target.value), placeholder: "e.g. embedding:" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Prefix for vector keys" })] }) })] }));
            case 'faiss':
                return ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Index Path (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.indexPath || '', onChange: e => handleInputChange('options.indexPath', e.target.value), placeholder: "e.g. /path/to/faiss/index" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Path to save/load FAISS index" })] }) }));
            case 'local':
                return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Storage Path (optional)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.storagePath || '', onChange: e => handleInputChange('options.storagePath', e.target.value), placeholder: "e.g. /path/to/vector/storage" }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Path to store vectors on disk" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Persist to File" }), (0, jsx_runtime_1.jsx)(ui_1.Switch, { checked: config.options?.persistToFile || false, onChange: e => handleInputChange('options.persistToFile', e.target.checked) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Whether to persist vectors to disk" })] }) })] }));
            case 'drupal':
                return ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors['options.endpoint']), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "API Endpoint" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.options?.endpoint || '', onChange: e => handleInputChange('options.endpoint', e.target.value), placeholder: "e.g. /api/vector-database", error: Boolean(errors['options.endpoint']), helperText: errors['options.endpoint'] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "API endpoint for vector operations" })] }) }));
            default:
                return null;
        }
    };
    // Render UI
    return ((0, jsx_runtime_1.jsx)(ui_1.Card, { variant: variant === 'compact' ? 'outlined' : 'elevation', children: (0, jsx_runtime_1.jsxs)(ui_1.CardContent, { children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h5", gutterBottom: true, children: "Vector Database Configuration" }), helpText && ((0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: "info", sx: { mb: 2 }, children: helpText })), (0, jsx_runtime_1.jsxs)(ui_1.Tabs, { value: activeTab, onChange: (_, value) => setActiveTab(value), sx: { mb: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Tab, { label: "Basic Configuration" }), (0, jsx_runtime_1.jsx)(ui_1.Tab, { label: "Advanced Options" }), enableTesting && (0, jsx_runtime_1.jsx)(ui_1.Tab, { label: "Connection Test" })] }), activeTab === 0 && ((0, jsx_runtime_1.jsxs)(ui_1.Grid, { container: true, spacing: 3, children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Vector Database Type" }), (0, jsx_runtime_1.jsx)(ui_1.Select, { value: config.type, onChange: e => handleInputChange('type', e.target.value), children: VECTOR_DATABASE_TYPES.map(option => ((0, jsx_runtime_1.jsx)(ui_1.MenuItem, { value: option.value, children: (0, jsx_runtime_1.jsxs)(ui_1.Box, { children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "body1", children: option.label }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "caption", color: "textSecondary", children: option.description })] }) }, option.value))) })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors.collection), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Collection Name" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.collection, onChange: e => handleInputChange('collection', e.target.value), placeholder: "e.g. my-vectors", error: Boolean(errors.collection), helperText: errors.collection }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Collection or index name" })] }) }), showEmbeddingConfig && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Embedding Model" }), (0, jsx_runtime_1.jsx)(ui_1.Select, { value: embeddingModel, onChange: e => setEmbeddingModel(e.target.value), children: EMBEDDING_MODELS.map(model => ((0, jsx_runtime_1.jsx)(ui_1.MenuItem, { value: model.value, children: (0, jsx_runtime_1.jsxs)(ui_1.Box, { children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "body1", children: model.label }), (0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "caption", color: "textSecondary", children: [model.dimensions, " dimensions \u2022 ", model.provider] })] }) }, model.value))) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "The model used for generating embeddings" })] }) })), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors.dimensions), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Dimensions" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { type: "number", value: config.dimensions, onChange: e => handleInputChange('dimensions', parseInt(e.target.value)), InputProps: {
                                            inputProps: { min: 1 }
                                        }, error: Boolean(errors.dimensions), helperText: errors.dimensions }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Number of dimensions in embedding vectors" })] }) }), config.type !== 'memory' && config.type !== 'local' && config.type !== 'faiss' && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors.url), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Connection URL" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { value: config.url, onChange: e => handleInputChange('url', e.target.value), placeholder: getUrlPlaceholder(config.type), error: Boolean(errors.url), helperText: errors.url }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: getUrlHelperText(config.type) })] }) })), (config.type === 'pinecone' ||
                            config.type === 'weaviate' ||
                            config.type === 'elasticsearch' ||
                            config.type === 'drupal') && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, error: Boolean(errors.apiKey), children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "API Key" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { type: "password", value: config.apiKey, onChange: e => handleInputChange('apiKey', e.target.value), error: Boolean(errors.apiKey), helperText: errors.apiKey }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "API key for authentication" })] }) })), renderProviderOptions()] })), activeTab === 1 && ((0, jsx_runtime_1.jsxs)(ui_1.Grid, { container: true, spacing: 3, children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Distance Metric" }), (0, jsx_runtime_1.jsx)(ui_1.Select, { value: config.metric || 'cosine', onChange: e => handleInputChange('metric', e.target.value), children: DISTANCE_METRICS.map(option => ((0, jsx_runtime_1.jsx)(ui_1.MenuItem, { value: option.value, children: (0, jsx_runtime_1.jsxs)(ui_1.Box, { children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "body1", children: option.label }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "caption", color: "textSecondary", children: option.description })] }) }, option.value))) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Metric for measuring vector similarity" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Hybrid Search" }), (0, jsx_runtime_1.jsx)(ui_1.Switch, { checked: config.hybridSearch || false, onChange: e => handleInputChange('hybridSearch', e.target.checked) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Enable hybrid search (text + vector)" })] }) }), (0, jsx_runtime_1.jsxs)(ui_1.Grid, { item: true, xs: 12, children: [(0, jsx_runtime_1.jsx)(ui_1.Divider, { sx: { my: 2 } }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h6", gutterBottom: true, children: "Advanced Caching" }), (0, jsx_runtime_1.jsxs)(ui_1.Grid, { container: true, spacing: 2, children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Enable Cache" }), (0, jsx_runtime_1.jsx)(ui_1.Switch, { checked: config.cache?.enabled || false, onChange: e => handleInputChange('cache.enabled', e.target.checked) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Enable caching for vector operations" })] }) }), config.cache?.enabled && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Cache TTL (seconds)" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { type: "number", value: config.cache?.ttl || 300, onChange: e => handleInputChange('cache.ttl', parseInt(e.target.value)), InputProps: {
                                                                    inputProps: { min: 1 },
                                                                    endAdornment: (0, jsx_runtime_1.jsx)(ui_1.InputAdornment, { position: "end", children: "sec" })
                                                                } }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Time-to-live for cached items" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Max Cache Items" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { type: "number", value: config.cache?.maxItems || 1000, onChange: e => handleInputChange('cache.maxItems', parseInt(e.target.value)), InputProps: {
                                                                    inputProps: { min: 1 }
                                                                } }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Maximum number of items to cache" })] }) })] }))] })] }), (0, jsx_runtime_1.jsxs)(ui_1.Grid, { item: true, xs: 12, children: [(0, jsx_runtime_1.jsx)(ui_1.Divider, { sx: { my: 2 } }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h6", gutterBottom: true, children: "Replication Settings" }), (0, jsx_runtime_1.jsxs)(ui_1.Grid, { container: true, spacing: 2, children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Enable Replication" }), (0, jsx_runtime_1.jsx)(ui_1.Switch, { checked: config.replication?.enabled || false, onChange: e => handleInputChange('replication.enabled', e.target.checked) }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Enable replication to secondary databases" })] }) }), config.replication?.enabled && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Replication Mode" }), (0, jsx_runtime_1.jsxs)(ui_1.Select, { value: config.replication?.mode || 'async', onChange: e => handleInputChange('replication.mode', e.target.value), children: [(0, jsx_runtime_1.jsx)(ui_1.MenuItem, { value: "sync", children: "Synchronous" }), (0, jsx_runtime_1.jsx)(ui_1.MenuItem, { value: "async", children: "Asynchronous" })] }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "How replication is performed" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, children: (0, jsx_runtime_1.jsxs)(ui_1.FormControl, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.FormLabel, { children: "Batch Size" }), (0, jsx_runtime_1.jsx)(ui_1.TextField, { type: "number", value: config.replication?.batchSize || 100, onChange: e => handleInputChange('replication.batchSize', parseInt(e.target.value)), InputProps: {
                                                                    inputProps: { min: 1 }
                                                                } }), (0, jsx_runtime_1.jsx)(ui_1.FormHelperText, { children: "Records per batch for async replication" })] }) })] }))] })] })] })), activeTab === 2 && enableTesting && ((0, jsx_runtime_1.jsxs)(ui_1.Box, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h6", gutterBottom: true, children: "Connection Test" }), (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "contained", color: "primary", onClick: testConnection, disabled: isTesting || !isValid, startIcon: isTesting ? (0, jsx_runtime_1.jsx)(ui_1.CircularProgress, { size: 20 }) : null, sx: { mb: 2 }, children: isTesting ? 'Testing Connection...' : 'Test Connection' }), testResult && ((0, jsx_runtime_1.jsxs)(ui_1.Box, { sx: { mt: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: testResult.success ? 'success' : 'error', sx: { mb: 2 }, children: testResult.message }), testResult.details && ((0, jsx_runtime_1.jsxs)(ui_1.Box, { sx: {
                                        p: 2,
                                        bgcolor: 'background.paper',
                                        borderRadius: 1,
                                        border: 1,
                                        borderColor: 'divider'
                                    }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", children: "Test Details:" }), (0, jsx_runtime_1.jsx)("pre", { style: { whiteSpace: 'pre-wrap' }, children: JSON.stringify(testResult.details, null, 2) })] }))] }))] })), showValidation && ((0, jsx_runtime_1.jsx)(ui_1.Collapse, { in: validationStatus !== 'untested', children: (0, jsx_runtime_1.jsx)(ui_1.Box, { sx: { mt: 3 }, children: (0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: validationStatus === 'success' ? 'success' : 'error', icon: validationStatus === 'success' ? (0, jsx_runtime_1.jsx)(icons_1.CheckCircle, {}) : (0, jsx_runtime_1.jsx)(icons_1.Error, {}), children: validationStatus === 'success'
                                ? 'Configuration is valid'
                                : 'Please fix the validation errors' }) }) })), enableAiSuggestions && ((0, jsx_runtime_1.jsxs)(ui_1.Box, { sx: { mt: 3, p: 2, bgcolor: 'background.paper', borderRadius: 1, border: 1, borderColor: 'divider' }, children: [(0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "subtitle1", sx: { display: 'flex', alignItems: 'center', mb: 1 }, children: [(0, jsx_runtime_1.jsx)(icons_1.Info, { fontSize: "small", sx: { mr: 1, color: 'primary.main' } }), "AI Suggestions"] }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "body2", children: getSuggestionForProvider(config.type) }), (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "outlined", size: "small", sx: { mt: 2 }, onClick: getRecommendedConfig, children: "Get Recommended Configuration" })] }))] }) }));
};
exports.VectorDatabaseConfig = VectorDatabaseConfig;
/**
 * Helper function to get URL placeholder based on provider
 */
function getUrlPlaceholder(type) {
    switch (type) {
        case 'pinecone':
            return 'https://index-name-project.svc.environment.pinecone.io';
        case 'qdrant':
            return 'http://localhost:6333';
        case 'weaviate':
            return 'http://localhost:8080';
        case 'elasticsearch':
            return 'http://localhost:9200';
        case 'pgvector':
            return 'postgres://username:password@localhost:5432/database';
        case 'redis':
            return 'redis://localhost:6379';
        case 'drupal':
            return 'http://example.com';
        default:
            return '';
    }
}
/**
 * Helper function to get URL helper text based on provider
 */
function getUrlHelperText(type) {
    switch (type) {
        case 'pinecone':
            return 'Pinecone API endpoint from your Pinecone console';
        case 'qdrant':
            return 'URL to your Qdrant server instance';
        case 'weaviate':
            return 'URL to your Weaviate server instance';
        case 'elasticsearch':
            return 'URL to your Elasticsearch server';
        case 'pgvector':
            return 'PostgreSQL connection string';
        case 'redis':
            return 'Redis connection string';
        case 'drupal':
            return 'Drupal site base URL';
        default:
            return 'Connection URL';
    }
}
/**
 * Helper function to get AI suggestions based on provider
 */
function getSuggestionForProvider(type) {
    switch (type) {
        case 'pinecone':
            return 'Pinecone works best for production applications with high scalability needs. Consider using namespaces to partition data by topic or user.';
        case 'qdrant':
            return 'Qdrant is a good self-hosted option with excellent performance. For production, consider using the cosine distance metric with filters for metadata.';
        case 'weaviate':
            return 'Weaviate excels at complex data relationships. Use schema classes that match your domain entities for best organization.';
        case 'elasticsearch':
            return 'Elasticsearch is ideal when you need both vector search and text search capabilities. Consider using hybrid search for best results.';
        case 'pgvector':
            return 'PGVector works well when you already use PostgreSQL. Consider adding indexes for improved search performance.';
        case 'redis':
            return 'Redis Vector is perfect for low-latency requirements. Use key prefixes to organize your vectors logically.';
        case 'faiss':
            return 'FAISS is optimized for speed and works well for local development. Consider saving the index to disk for persistence.';
        case 'local':
            return 'Local storage is suitable for development and testing. Enable persistToFile for data that should survive application restarts.';
        case 'memory':
            return 'Memory storage is fastest but ephemeral - data will be lost on application restart. Use only for testing.';
        case 'drupal':
            return 'Drupal integration works best when embedding content entities. Ensure the Vector Database module is enabled in your Drupal installation.';
        default:
            return 'Configure your vector database based on your use case, expected data volume, and performance requirements.';
    }
}
exports.default = exports.VectorDatabaseConfig;
//# sourceMappingURL=index.js.map