import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState } from "react";
import { ConnectConfirmationModal } from "../modal/confirmation-modal.js";
import { SchemaTreeSidebar, } from "./components/schema-tree-sidebar.js";
import { TableView, } from "./components/table-view.js";
const DEFAULT_PAGE_SIZE = 50;
export function DBExplorer({ schema, getTables, getTableRows, getDefaultSort, pageSize = DEFAULT_PAGE_SIZE, onImportDb, onExportDb, }) {
    const fileInputRef = useRef(null);
    const [tables, setTables] = useState([]);
    const [tablesLoading, setTablesLoading] = useState(true);
    const [selectedTable, setSelectedTable] = useState();
    const [tableData, setTableData] = useState(null);
    const [pagination, setPagination] = useState({
        offset: 0,
        limit: pageSize,
        total: null,
    });
    const [sort, setSort] = useState();
    const [filters, setFilters] = useState();
    const [loading, setLoading] = useState(false);
    const [pendingImport, setPendingImport] = useState(null);
    const columns = tables.find((t) => t.name === selectedTable)?.columns ?? [];
    const loadTableData = useCallback(async () => {
        if (!selectedTable)
            return;
        setLoading(true);
        const data = await getTableRows(selectedTable, {
            schema,
            limit: pagination.limit,
            offset: pagination.offset,
            sort,
            filters,
        });
        setTableData(data);
        setPagination((prev) => ({ ...prev, total: data.total }));
        setLoading(false);
    }, [
        selectedTable,
        schema,
        pagination.limit,
        pagination.offset,
        sort,
        filters,
        getTableRows,
    ]);
    const loadTables = useCallback(async () => {
        setTablesLoading(true);
        const data = await getTables();
        setTables(data);
        setTablesLoading(false);
        return data;
    }, [getTables]);
    const handleRefresh = useCallback(async () => {
        const newTables = await loadTables();
        // Clear selection if selected table no longer exists
        if (selectedTable && !newTables.some((t) => t.name === selectedTable)) {
            setSelectedTable(undefined);
            setTableData(null);
            return;
        }
        // Reload current table data if a table is selected
        if (selectedTable) {
            await loadTableData();
        }
    }, [loadTables, selectedTable, loadTableData]);
    // Load tables on mount
    useEffect(() => {
        void loadTables();
    }, [loadTables]);
    useEffect(() => {
        if (selectedTable) {
            void loadTableData();
        }
    }, [selectedTable, pagination.offset, sort, filters, loadTableData]);
    const handleSelectTable = (table) => {
        if (table === selectedTable)
            return;
        setSelectedTable(table);
        setPagination((prev) => ({ ...prev, offset: 0, total: null }));
        setSort(getDefaultSort?.(table));
        setFilters(undefined);
        setTableData(null);
    };
    const handlePageChange = (offset) => {
        setPagination((prev) => ({ ...prev, offset }));
    };
    const handleSort = (newSort) => {
        setSort(newSort);
        setPagination((prev) => ({ ...prev, offset: 0 }));
    };
    const handleImportClick = () => {
        fileInputRef.current?.click();
    };
    const handleFileChange = (e) => {
        const file = e.target.files?.[0];
        if (!file)
            return;
        void file.text().then((content) => {
            setPendingImport(content);
        });
        e.target.value = "";
    };
    const handleImportConfirm = async () => {
        if (pendingImport) {
            // Clear selection before import to prevent stale queries
            setSelectedTable(undefined);
            setTableData(null);
            await onImportDb?.(pendingImport);
            setPendingImport(null);
            await loadTables();
        }
    };
    const handleImportCancel = () => {
        setPendingImport(null);
    };
    const handleExportClick = () => {
        void onExportDb?.();
    };
    return (_jsxs("div", { className: "flex h-full", children: [_jsx("input", { ref: fileInputRef, type: "file", accept: ".sql,.txt,text/plain", className: "hidden", onChange: handleFileChange }), _jsx(ConnectConfirmationModal, { open: !!pendingImport, onOpenChange: (open) => !open && setPendingImport(null), header: "Replace Database?", body: "This will delete all existing data and replace it with the imported file. This action cannot be undone.", cancelLabel: "Cancel", continueLabel: "Replace Data", onCancel: handleImportCancel, onContinue: () => void handleImportConfirm(), continueButtonProps: {
                    className: "bg-red-900 text-white hover:bg-red-800",
                } }), _jsxs("div", { className: "flex w-64 shrink-0 flex-col border-r border-gray-200", children: [_jsx("div", { className: "flex-1 overflow-auto", children: _jsx(SchemaTreeSidebar, { schema: schema, tables: tables, selectedTable: selectedTable, onSelectTable: handleSelectTable, onRefresh: handleRefresh, loading: tablesLoading || loading }) }), (onImportDb || onExportDb) && (_jsxs("div", { className: "flex shrink-0 flex-col gap-2 border-t border-gray-200 p-2", children: [onImportDb && (_jsx("button", { className: "rounded border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", onClick: handleImportClick, type: "button", children: "Import DB" })), onExportDb && (_jsx("button", { className: "rounded border border-gray-300 bg-white px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", onClick: handleExportClick, type: "button", children: "Export DB" }))] }))] }), _jsx("div", { className: "flex-1 overflow-auto p-4", children: !selectedTable ? (_jsx("div", { className: "text-sm text-gray-500", children: "Select a table to view data" })) : !tableData && loading ? (_jsx("div", { className: "text-sm text-gray-500", children: "Loading..." })) : tableData ? (_jsx(TableView, { columns: columns, rows: tableData.rows, pagination: pagination, onPageChange: handlePageChange, onSort: handleSort, currentSort: sort, loading: loading, filters: filters, onFiltersChange: (newFilters) => {
                        setFilters(newFilters);
                        setPagination((prev) => ({ ...prev, offset: 0 }));
                    } })) : null })] }));
}
//# sourceMappingURL=db-explorer.js.map