"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModelRegistry = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const ModelRegistryProvider_js_1 = require("./ModelRegistryProvider.js");
const ModelCard_js_1 = require("./ModelCard.js");
const ModelForm_js_1 = require("./ModelForm.js");
const ModelDeploymentForm_js_1 = require("./ModelDeploymentForm.js");
const ModelVersions_js_1 = require("./ModelVersions.js");
const ModelRegistryHeader_js_1 = require("./ModelRegistryHeader.js");
const ModelRegistryFilters_js_1 = require("./ModelRegistryFilters.js");
const Alert_js_1 = __importDefault(require("../feedback/Alert.js"));
const Modal_js_1 = __importDefault(require("../feedback/Modal.js"));
const Loader_js_1 = __importDefault(require("../feedback/Loader.js"));
/**
 * ModelRegistry Component
 *
 * Main component for LLM model management with comprehensive features:
 * - Model listing with search and filtering
 * - Model creation, editing, and deletion
 * - Model deployment and version management
 * - Error handling and loading states
 * - TypeScript integration with bfapi endpoints
 */
const ModelRegistry = ({ className = '', onModelSelect, onModelCreate, onModelUpdate, onModelDelete, showActions = true, searchable = true, filterable = true, pageSize = 12 }) => {
    // Context and state management
    const { models, loading, error, filters, createModel, updateModel, deleteModel, deployModel, setFilters, clearError } = (0, ModelRegistryProvider_js_1.useModelRegistry)();
    // Local state for UI interactions
    const [showCreateModal, setShowCreateModal] = (0, react_1.useState)(false);
    const [showEditModal, setShowEditModal] = (0, react_1.useState)(false);
    const [showDeployModal, setShowDeployModal] = (0, react_1.useState)(false);
    const [showVersionsModal, setShowVersionsModal] = (0, react_1.useState)(false);
    const [selectedModel, setSelectedModel] = (0, react_1.useState)(null);
    const [searchTerm, setSearchTerm] = (0, react_1.useState)('');
    const [currentPage, setCurrentPage] = (0, react_1.useState)(1);
    // Filter and search logic
    const filteredModels = (0, react_1.useMemo)(() => {
        let filtered = models;
        // Apply search filter
        if (searchTerm) {
            filtered = filtered.filter(model => model.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
                model.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
                model.provider.toLowerCase().includes(searchTerm.toLowerCase()));
        }
        // Apply status filter
        if (filters.status && filters.status.length > 0) {
            filtered = filtered.filter(model => filters.status.includes(model.status));
        }
        // Apply provider filter
        if (filters.provider && filters.provider.length > 0) {
            filtered = filtered.filter(model => filters.provider.includes(model.provider));
        }
        // Apply environment filter
        if (filters.environment && filters.environment.length > 0) {
            filtered = filtered.filter(model => model.deployment_config &&
                filters.environment.includes(model.deployment_config.environment));
        }
        return filtered;
    }, [models, searchTerm, filters]);
    // Pagination logic
    const paginatedModels = (0, react_1.useMemo)(() => {
        const startIndex = (currentPage - 1) * pageSize;
        return filteredModels.slice(startIndex, startIndex + pageSize);
    }, [filteredModels, currentPage, pageSize]);
    const totalPages = Math.ceil(filteredModels.length / pageSize);
    // Event handlers
    const handleCreateModel = async (data) => {
        try {
            const newModel = await createModel(data);
            setShowCreateModal(false);
            onModelCreate?.(newModel);
        }
        catch (error) {
            // Error is handled by the context
            console.error('Failed to create model:', error);
        }
    };
    const handleFormSubmit = (data) => {
        if ('id' in data) {
            // It's an update request
            handleUpdateModel(data);
        }
        else {
            // It's a create request
            handleCreateModel(data);
        }
    };
    const handleUpdateModel = async (data) => {
        try {
            const updatedModel = await updateModel(data);
            setShowEditModal(false);
            setSelectedModel(null);
            onModelUpdate?.(updatedModel);
        }
        catch (error) {
            console.error('Failed to update model:', error);
        }
    };
    const handleDeleteModel = async (model) => {
        if (window.confirm(`Are you sure you want to delete ${model.name}?`)) {
            try {
                await deleteModel(model.id);
                onModelDelete?.(model.id);
            }
            catch (error) {
                console.error('Failed to delete model:', error);
            }
        }
    };
    const handleDeployModel = async (data) => {
        try {
            await deployModel(data);
            setShowDeployModal(false);
            setSelectedModel(null);
        }
        catch (error) {
            console.error('Failed to deploy model:', error);
        }
    };
    const handleModelSelect = (model) => {
        setSelectedModel(model);
        onModelSelect?.(model);
    };
    const handleEditModel = (model) => {
        setSelectedModel(model);
        setShowEditModal(true);
    };
    const handleDeployModelModal = (model) => {
        setSelectedModel(model);
        setShowDeployModal(true);
    };
    const handleViewVersions = (model) => {
        setSelectedModel(model);
        setShowVersionsModal(true);
    };
    const handleFilterChange = (newFilters) => {
        setFilters(newFilters);
        setCurrentPage(1); // Reset to first page when filters change
    };
    const handleRetry = () => {
        clearError();
        // Retry will be triggered by useEffect in provider
    };
    // Render loading state
    if (loading && models.length === 0) {
        return ((0, jsx_runtime_1.jsx)("div", { className: `model-registry ${className}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center h-64", "data-testid": "model-registry-loading", children: [(0, jsx_runtime_1.jsx)(Loader_js_1.default, { size: "large" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-4 text-gray-600", children: "Loading models..." })] }) }));
    }
    // Render error state
    if (error && models.length === 0) {
        return ((0, jsx_runtime_1.jsx)("div", { className: `model-registry ${className}`, children: (0, jsx_runtime_1.jsx)("div", { "data-testid": "model-registry-error", children: (0, jsx_runtime_1.jsx)(Alert_js_1.default, { type: "error", title: "Failed to load models", message: error, actions: [
                        {
                            label: 'Retry',
                            onClick: handleRetry,
                            variant: 'primary'
                        }
                    ] }) }) }));
    }
    // Render empty state
    if (filteredModels.length === 0 && !loading) {
        return ((0, jsx_runtime_1.jsxs)("div", { className: `model-registry ${className}`, children: [(0, jsx_runtime_1.jsx)(ModelRegistryHeader_js_1.ModelRegistryHeader, { onCreateModel: () => setShowCreateModal(true), showCreateButton: showActions }), searchable && ((0, jsx_runtime_1.jsx)(ModelRegistryFilters_js_1.ModelRegistryFilters, { searchTerm: searchTerm, onSearchChange: setSearchTerm, filters: filters, onFilterChange: handleFilterChange, showFilters: filterable })), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col items-center justify-center h-64 text-center", "data-testid": "model-registry-empty", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-gray-400 mb-4", children: (0, jsx_runtime_1.jsx)("svg", { className: "w-16 h-16 mx-auto", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) }) }), (0, jsx_runtime_1.jsx)("h3", { className: "text-lg font-medium text-gray-900 mb-2", children: searchTerm || Object.keys(filters).length > 0 ? 'No models found' : 'No models yet' }), (0, jsx_runtime_1.jsx)("p", { className: "text-gray-500 mb-4", children: searchTerm || Object.keys(filters).length > 0
                                ? 'Try adjusting your search or filters'
                                : 'Add your first model to get started' }), showActions && ((0, jsx_runtime_1.jsx)("button", { onClick: () => setShowCreateModal(true), className: "bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-md font-medium", children: "Add Model" }))] }), showCreateModal && ((0, jsx_runtime_1.jsx)(Modal_js_1.default, { isOpen: showCreateModal, onClose: () => setShowCreateModal(false), title: "Create New Model", "data-testid": "model-create-modal", children: (0, jsx_runtime_1.jsx)(ModelForm_js_1.ModelForm, { onSubmit: handleFormSubmit, onCancel: () => setShowCreateModal(false), loading: loading, error: error || undefined }) }))] }));
    }
    // Render main model list
    return ((0, jsx_runtime_1.jsxs)("div", { className: `model-registry ${className}`, children: [(0, jsx_runtime_1.jsx)(ModelRegistryHeader_js_1.ModelRegistryHeader, { onCreateModel: () => setShowCreateModal(true), showCreateButton: showActions, modelCount: filteredModels.length, totalCount: models.length }), error && ((0, jsx_runtime_1.jsx)("div", { className: "mb-4", children: (0, jsx_runtime_1.jsx)(Alert_js_1.default, { type: "error", title: "Error", message: error, onDismiss: clearError }) })), (searchable || filterable) && ((0, jsx_runtime_1.jsx)(ModelRegistryFilters_js_1.ModelRegistryFilters, { searchTerm: searchTerm, onSearchChange: setSearchTerm, filters: filters, onFilterChange: handleFilterChange, showFilters: filterable })), (0, jsx_runtime_1.jsxs)("div", { "data-testid": "model-registry-list", children: [(0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6", children: paginatedModels.map((model) => ((0, jsx_runtime_1.jsx)(ModelCard_js_1.ModelCard, { model: model, onEdit: showActions ? handleEditModel : undefined, onDeploy: showActions ? handleDeployModelModal : undefined, onDelete: showActions ? handleDeleteModel : undefined, onViewVersions: showActions ? handleViewVersions : undefined, showActions: showActions, onClick: () => handleModelSelect(model) }, model.id))) }), loading && models.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center py-4", children: [(0, jsx_runtime_1.jsx)(Loader_js_1.default, { size: "small" }), (0, jsx_runtime_1.jsx)("span", { className: "ml-2 text-gray-600", children: "Updating..." })] }))] }), totalPages > 1 && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between mt-8", children: [(0, jsx_runtime_1.jsxs)("div", { className: "text-sm text-gray-700", children: ["Showing ", ((currentPage - 1) * pageSize) + 1, " to ", Math.min(currentPage * pageSize, filteredModels.length), " of ", filteredModels.length, " models"] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex space-x-2", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setCurrentPage(prev => Math.max(prev - 1, 1)), disabled: currentPage === 1, className: "px-3 py-1 border border-gray-300 rounded-md disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50", children: "Previous" }), Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setCurrentPage(page), className: `px-3 py-1 border rounded-md ${page === currentPage
                                    ? 'bg-blue-600 text-white border-blue-600'
                                    : 'border-gray-300 hover:bg-gray-50'}`, children: page }, page))), (0, jsx_runtime_1.jsx)("button", { onClick: () => setCurrentPage(prev => Math.min(prev + 1, totalPages)), disabled: currentPage === totalPages, className: "px-3 py-1 border border-gray-300 rounded-md disabled:opacity-50 disabled:cursor-not-allowed hover:bg-gray-50", children: "Next" })] })] })), showCreateModal && ((0, jsx_runtime_1.jsx)(Modal_js_1.default, { isOpen: showCreateModal, onClose: () => setShowCreateModal(false), title: "Create New Model", "data-testid": "model-create-modal", children: (0, jsx_runtime_1.jsx)(ModelForm_js_1.ModelForm, { onSubmit: handleCreateModel, onCancel: () => setShowCreateModal(false), loading: loading, error: error }) })), showEditModal && selectedModel && ((0, jsx_runtime_1.jsx)(Modal_js_1.default, { isOpen: showEditModal, onClose: () => {
                    setShowEditModal(false);
                    setSelectedModel(null);
                }, title: "Edit Model", "data-testid": "model-edit-modal", children: (0, jsx_runtime_1.jsx)(ModelForm_js_1.ModelForm, { model: selectedModel, onSubmit: handleUpdateModel, onCancel: () => {
                        setShowEditModal(false);
                        setSelectedModel(null);
                    }, loading: loading, error: error }) })), showDeployModal && selectedModel && ((0, jsx_runtime_1.jsx)(Modal_js_1.default, { isOpen: showDeployModal, onClose: () => {
                    setShowDeployModal(false);
                    setSelectedModel(null);
                }, title: "Deploy Model", "data-testid": "model-deploy-modal", children: (0, jsx_runtime_1.jsx)(ModelDeploymentForm_js_1.ModelDeploymentForm, { model: selectedModel, onSubmit: handleDeployModel, onCancel: () => {
                        setShowDeployModal(false);
                        setSelectedModel(null);
                    }, loading: loading, error: error }) })), showVersionsModal && selectedModel && ((0, jsx_runtime_1.jsx)(Modal_js_1.default, { isOpen: showVersionsModal, onClose: () => {
                    setShowVersionsModal(false);
                    setSelectedModel(null);
                }, title: `Version History - ${selectedModel.name}`, size: "large", "data-testid": "model-versions-modal", children: (0, jsx_runtime_1.jsx)(ModelVersions_js_1.ModelVersions, { modelId: selectedModel.id, currentVersion: selectedModel.version, onRollback: (version) => {
                        // Handle rollback - this would typically show a confirmation dialog
                        console.log('Rollback to version:', version);
                    } }) }))] }));
};
exports.ModelRegistry = ModelRegistry;
//# sourceMappingURL=ModelRegistry.js.map