"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VectorDatabaseMonitoring = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * Vector Database Monitoring Component
 *
 * Displays real-time health status and performance metrics for registered vector databases.
 */
const react_1 = require("react");
const ui_1 = require("../ui");
const icons_1 = require("../icons");
/**
 * Vector Database Monitoring Component
 */
const VectorDatabaseMonitoring = ({ refreshInterval = 30, maxDatabases = 10, showDetailedMetrics = true, allowRegister = true, allowUnregister = true, allowManualChecks = true, variant = 'default', apiEndpointBase = '/api/experience-builder', }) => {
    const theme = (0, ui_1.useTheme)();
    // State for database statuses
    const [loading, setLoading] = (0, react_1.useState)(true);
    const [error, setError] = (0, react_1.useState)(null);
    const [databases, setDatabases] = (0, react_1.useState)([]);
    const [lastUpdated, setLastUpdated] = (0, react_1.useState)(null);
    const [selectedDatabase, setSelectedDatabase] = (0, react_1.useState)(null);
    const [metricsDialogOpen, setMetricsDialogOpen] = (0, react_1.useState)(false);
    const [metricsData, setMetricsData] = (0, react_1.useState)(null);
    const [refreshing, setRefreshing] = (0, react_1.useState)(false);
    // Format timestamp
    const formatTimestamp = (timestamp) => {
        if (!timestamp)
            return 'Never';
        const date = new Date(timestamp * 1000);
        return date.toLocaleString();
    };
    // Get status color
    const getStatusColor = (status) => {
        switch (status) {
            case 'healthy':
                return theme.palette.success.main;
            case 'error':
            case 'connection_failed':
            case 'invalid_configuration':
                return theme.palette.error.main;
            case 'warning':
                return theme.palette.warning.main;
            default:
                return theme.palette.grey[500];
        }
    };
    // Get status icon
    const getStatusIcon = (status) => {
        switch (status) {
            case 'healthy':
                return (0, jsx_runtime_1.jsx)(icons_1.CheckCircle, { fontSize: "small" });
            case 'error':
            case 'connection_failed':
            case 'invalid_configuration':
                return (0, jsx_runtime_1.jsx)(icons_1.Error, { fontSize: "small" });
            case 'warning':
                return (0, jsx_runtime_1.jsx)(icons_1.Warning, { fontSize: "small" });
            default:
                return (0, jsx_runtime_1.jsx)(icons_1.Help, { fontSize: "small" });
        }
    };
    // Fetch database statuses
    const fetchDatabaseStatuses = (0, react_1.useCallback)(async () => {
        try {
            setRefreshing(true);
            const response = await fetch(`${apiEndpointBase}/vector/monitoring/statuses`);
            if (!response.ok) {
                throw new icons_1.Error(`API error: ${response.status}`);
            }
            const data = await response.json();
            if (data.databases) {
                // Convert object to array and sort by status (errors first)
                const databaseArray = Object.values(data.databases);
                databaseArray.sort((a, b) => {
                    // Sort by status - errors first, then healthy, then the rest
                    if (a.status === 'error' && b.status !== 'error')
                        return -1;
                    if (a.status !== 'error' && b.status === 'error')
                        return 1;
                    if (a.status === 'healthy' && b.status !== 'healthy')
                        return 1;
                    if (a.status !== 'healthy' && b.status === 'healthy')
                        return -1;
                    // Then sort by last check time - most recent first
                    return (b.last_check || 0) - (a.last_check || 0);
                });
                setDatabases(databaseArray.slice(0, maxDatabases));
                setLastUpdated(new Date());
                setError(null);
            }
        }
        catch (err) {
            setError(err.message);
        }
        finally {
            setLoading(false);
            setRefreshing(false);
        }
    }, [apiEndpointBase, maxDatabases]);
    // Fetch metrics for a database
    const fetchDatabaseMetrics = (0, react_1.useCallback)(async (id) => {
        try {
            const response = await fetch(`${apiEndpointBase}/vector/monitoring/metrics/${id}`);
            if (!response.ok) {
                throw new icons_1.Error(`API error: ${response.status}`);
            }
            const data = await response.json();
            setMetricsData(data.metrics || {});
            setSelectedDatabase(id);
            setMetricsDialogOpen(true);
        }
        catch (err) {
            setError(err.message);
        }
    }, [apiEndpointBase]);
    // Check database health
    const checkDatabaseHealth = (0, react_1.useCallback)(async (id) => {
        try {
            const response = await fetch(`${apiEndpointBase}/vector/monitoring/check-health/${id}`, {
                method: 'POST',
            });
            if (!response.ok) {
                throw new icons_1.Error(`API error: ${response.status}`);
            }
            // Refresh all statuses
            fetchDatabaseStatuses();
        }
        catch (err) {
            setError(err.message);
        }
    }, [apiEndpointBase, fetchDatabaseStatuses]);
    // Unregister a database
    const unregisterDatabase = (0, react_1.useCallback)(async (id) => {
        if (!window.confirm(`Are you sure you want to unregister database ${id}?`)) {
            return;
        }
        try {
            const response = await fetch(`${apiEndpointBase}/vector/monitoring/unregister/${id}`, {
                method: 'DELETE',
            });
            if (!response.ok) {
                throw new icons_1.Error(`API error: ${response.status}`);
            }
            // Refresh all statuses
            fetchDatabaseStatuses();
        }
        catch (err) {
            setError(err.message);
        }
    }, [apiEndpointBase, fetchDatabaseStatuses]);
    // Schedule health checks for all databases
    const scheduleHealthChecks = (0, react_1.useCallback)(async () => {
        try {
            const response = await fetch(`${apiEndpointBase}/vector/monitoring/schedule-checks`, {
                method: 'POST',
            });
            if (!response.ok) {
                throw new icons_1.Error(`API error: ${response.status}`);
            }
            const data = await response.json();
            if (data.success) {
                // Show temporary success message
                setError(null);
                // Refresh after a short delay to allow checks to process
                setTimeout(fetchDatabaseStatuses, 2000);
            }
        }
        catch (err) {
            setError(err.message);
        }
    }, [apiEndpointBase, fetchDatabaseStatuses]);
    // Initial load and auto-refresh
    (0, react_1.useEffect)(() => {
        // Initial fetch
        fetchDatabaseStatuses();
        // Set up auto-refresh if enabled
        if (refreshInterval > 0) {
            const intervalId = setInterval(fetchDatabaseStatuses, refreshInterval * 1000);
            // Clean up
            return () => clearInterval(intervalId);
        }
    }, [fetchDatabaseStatuses, refreshInterval]);
    // Render metrics dialog
    const renderMetricsDialog = () => {
        if (!selectedDatabase || !metricsData) {
            return null;
        }
        const database = databases.find(db => db.id === selectedDatabase);
        if (!database) {
            return null;
        }
        return ((0, jsx_runtime_1.jsxs)(ui_1.Dialog, { open: metricsDialogOpen, onClose: () => setMetricsDialogOpen(false), maxWidth: "md", fullWidth: true, children: [(0, jsx_runtime_1.jsx)(ui_1.DialogTitle, { children: (0, jsx_runtime_1.jsxs)(ui_1.Box, { display: "flex", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(icons_1.Timeline, { sx: { mr: 1 } }), database.type, " Metrics: ", database.collection] }) }), (0, jsx_runtime_1.jsxs)(ui_1.DialogContent, { children: [Object.keys(metricsData).length === 0 ? ((0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: "info", children: "No metrics available for this database." })) : ((0, jsx_runtime_1.jsxs)(ui_1.Grid, { container: true, spacing: 3, children: [metricsData.vectorCount !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "Vector Count" }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h4", children: metricsData.vectorCount.toLocaleString() })] }) })), metricsData.avgSearchLatency !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "Avg Search Latency" }), (0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "h4", children: [metricsData.avgSearchLatency, " ms"] })] }) })), metricsData.indexSize !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "Index Size" }), (0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "h4", children: [(metricsData.indexSize / (1024 * 1024)).toFixed(2), " MB"] })] }) })), metricsData.memoryUsage !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "Memory Usage" }), (0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "h4", children: [metricsData.memoryUsage, "%"] }), (0, jsx_runtime_1.jsx)(ui_1.LinearProgress, { variant: "determinate", value: metricsData.memoryUsage, sx: { mt: 1 }, color: metricsData.memoryUsage > 80 ? "error" : "primary" })] }) })), metricsData.cpuUsage !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "CPU Usage" }), (0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "h4", children: [metricsData.cpuUsage, "%"] }), (0, jsx_runtime_1.jsx)(ui_1.LinearProgress, { variant: "determinate", value: metricsData.cpuUsage, sx: { mt: 1 }, color: metricsData.cpuUsage > 80 ? "error" : "primary" })] }) })), metricsData.uptime !== undefined && ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: "Uptime" }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h4", children: formatUptime(metricsData.uptime) })] }) })), Object.entries(metricsData)
                                    .filter(([key]) => !['vectorCount', 'avgSearchLatency', 'indexSize', 'memoryUsage', 'cpuUsage', 'uptime'].includes(key))
                                    .map(([key, value]) => ((0, jsx_runtime_1.jsx)(ui_1.Grid, { item: true, xs: 12, sm: 6, md: 4, children: (0, jsx_runtime_1.jsxs)(ui_1.Paper, { sx: { p: 2 }, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle2", color: "textSecondary", children: formatMetricName(key) }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h4", children: typeof value === 'number' ? value.toLocaleString() : value.toString() })] }) }, key)))] })), database.errors && database.errors.length > 0 && ((0, jsx_runtime_1.jsxs)(ui_1.Box, { mt: 4, children: [(0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "subtitle1", gutterBottom: true, children: "Errors" }), (0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: "error", children: (0, jsx_runtime_1.jsx)("ul", { style: { margin: 0, paddingLeft: 16 }, children: database.errors.map((error, index) => ((0, jsx_runtime_1.jsx)("li", { children: error }, index))) }) })] }))] }), (0, jsx_runtime_1.jsxs)(ui_1.DialogActions, { children: [allowManualChecks && ((0, jsx_runtime_1.jsx)(ui_1.Button, { onClick: () => {
                                checkDatabaseHealth(selectedDatabase);
                                setMetricsDialogOpen(false);
                            }, color: "primary", children: "Run Health Check" })), (0, jsx_runtime_1.jsx)(ui_1.Button, { onClick: () => setMetricsDialogOpen(false), color: "primary", children: "Close" })] })] }));
    };
    // Render the component
    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.jsxs)(ui_1.Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, children: [(0, jsx_runtime_1.jsxs)(ui_1.Box, { display: "flex", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(icons_1.NetworkCheck, { sx: { mr: 1 } }), (0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "h5", children: "Vector Database Monitoring" })] }), (0, jsx_runtime_1.jsxs)(ui_1.Box, { children: [allowManualChecks && ((0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "Schedule Health Checks for All Databases", children: (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "outlined", size: "small", onClick: scheduleHealthChecks, sx: { mr: 1 }, children: "Check All" }) })), allowRegister && ((0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "Register New Database", children: (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "outlined", size: "small", startIcon: (0, jsx_runtime_1.jsx)(icons_1.AddCircleOutline, {}), onClick: () => window.location.href = '/admin/config/experience-builder/components/dashboard', sx: { mr: 1 }, children: "Register" }) })), (0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "Refresh Status", children: (0, jsx_runtime_1.jsx)(ui_1.IconButton, { onClick: fetchDatabaseStatuses, color: "primary", disabled: refreshing, children: (0, jsx_runtime_1.jsx)(icons_1.Refresh, {}) }) })] })] }), loading ? ((0, jsx_runtime_1.jsx)(ui_1.LinearProgress, {})) : error ? ((0, jsx_runtime_1.jsx)(ui_1.Alert, { severity: "error", children: error })) : databases.length === 0 ? ((0, jsx_runtime_1.jsxs)(ui_1.Alert, { severity: "info", children: ["No vector databases registered for monitoring.", allowRegister && ((0, jsx_runtime_1.jsx)(ui_1.Box, { mt: 2, children: (0, jsx_runtime_1.jsx)(ui_1.Button, { variant: "outlined", size: "small", startIcon: (0, jsx_runtime_1.jsx)(icons_1.AddCircleOutline, {}), onClick: () => window.location.href = '/admin/config/experience-builder/components/dashboard', children: "Register Database" }) }))] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ui_1.TableContainer, { component: ui_1.Paper, variant: "outlined", children: (0, jsx_runtime_1.jsxs)(ui_1.Table, { size: variant === 'compact' ? 'small' : 'medium', children: [(0, jsx_runtime_1.jsx)(ui_1.TableHead, { children: (0, jsx_runtime_1.jsxs)(ui_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: "Status" }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: "Type" }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: "Collection" }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: "Last Checked" }), variant === 'expanded' && ((0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: "Metrics" })), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { align: "right", children: "Actions" })] }) }), (0, jsx_runtime_1.jsx)(ui_1.TableBody, { children: databases.map(database => ((0, jsx_runtime_1.jsxs)(ui_1.TableRow, { children: [(0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: (0, jsx_runtime_1.jsx)(ui_1.Chip, { icon: getStatusIcon(database.status), label: database.status, size: "small", sx: {
                                                            color: 'white',
                                                            bgcolor: getStatusColor(database.status),
                                                        } }) }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: database.type }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: database.collection }), (0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: formatTimestamp(database.last_check) }), variant === 'expanded' && ((0, jsx_runtime_1.jsx)(ui_1.TableCell, { children: database.metrics && Object.keys(database.metrics).length > 0 ? ((0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "body2", children: [database.metrics.vectorCount &&
                                                                `${database.metrics.vectorCount.toLocaleString()} vectors`, database.metrics.avgSearchLatency &&
                                                                ` • ${database.metrics.avgSearchLatency}ms`] })) : ((0, jsx_runtime_1.jsx)(ui_1.Typography, { variant: "body2", color: "textSecondary", children: "No metrics available" })) })), (0, jsx_runtime_1.jsxs)(ui_1.TableCell, { align: "right", children: [(0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "View Detailed Metrics", children: (0, jsx_runtime_1.jsx)(ui_1.IconButton, { size: "small", onClick: () => fetchDatabaseMetrics(database.id), color: "primary", children: (0, jsx_runtime_1.jsx)(icons_1.Timeline, { fontSize: "small" }) }) }), allowManualChecks && ((0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "Check Health Now", children: (0, jsx_runtime_1.jsx)(ui_1.IconButton, { size: "small", onClick: () => checkDatabaseHealth(database.id), color: "primary", children: (0, jsx_runtime_1.jsx)(icons_1.Refresh, { fontSize: "small" }) }) })), allowUnregister && ((0, jsx_runtime_1.jsx)(ui_1.Tooltip, { title: "Unregister Database", children: (0, jsx_runtime_1.jsx)(ui_1.IconButton, { size: "small", onClick: () => unregisterDatabase(database.id), color: "error", children: (0, jsx_runtime_1.jsx)(icons_1.DeleteOutline, { fontSize: "small" }) }) }))] })] }, database.id))) })] }) }), lastUpdated && ((0, jsx_runtime_1.jsxs)(ui_1.Typography, { variant: "caption", color: "textSecondary", sx: { mt: 1, display: 'block' }, children: ["Last updated: ", lastUpdated.toLocaleString()] }))] })), renderMetricsDialog()] }) }));
};
exports.VectorDatabaseMonitoring = VectorDatabaseMonitoring;
// Helper function to format metric names
function formatMetricName(key) {
    // Convert camelCase to Title Case Words
    return key
        // Insert space before capital letters
        .replace(/([A-Z])/g, ' $1')
        // Capitalize first letter
        .replace(/^./, str => str.toUpperCase())
        // Handle special cases
        .replace('Avg', 'Average')
        .replace('Cpu', 'CPU')
        .replace('Gpu', 'GPU')
        .replace('Io', 'I/O')
        .replace('Api', 'API');
}
// Helper function to format uptime
function formatUptime(seconds) {
    const days = Math.floor(seconds / 86400);
    const hours = Math.floor((seconds % 86400) / 3600);
    const minutes = Math.floor(((seconds % 86400) % 3600) / 60);
    if (days > 0) {
        return `${days}d ${hours}h ${minutes}m`;
    }
    else if (hours > 0) {
        return `${hours}h ${minutes}m`;
    }
    else {
        return `${minutes}m`;
    }
}
exports.default = exports.VectorDatabaseMonitoring;
//# sourceMappingURL=index.js.map