"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImportDialog = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
/**
 * ImportDialog Component
 *
 * A dialog for importing data into a data table
 */
const react_1 = require("react");
const prop_types_1 = __importDefault(require("prop-types"));
/**
 * Parses CSV data into an array of objects
 * @param {string} csvText - CSV data to parse
 * @param {Object} options - Parsing options
 * @returns {Array} Parsed data
 */
const parseCSV = (csvText, options = {}) => {
    const { delimiter = ',', hasHeader = true } = options;
    const lines = csvText.split(/\r\n|\n|\r/).filter(line => line.trim());
    if (!lines.length)
        return [];
    // Parse header row
    const headerRow = hasHeader ? lines[0].split(delimiter) : [];
    const headers = hasHeader
        ? headerRow.map((header, index) => {
            // Remove quotes if present
            return header.replace(/^["'](.*)["']$/, '$1') || `column${index}`;
        })
        : [];
    // Parse data rows
    const startIndex = hasHeader ? 1 : 0;
    const data = [];
    for (let i = startIndex; i < lines.length; i++) {
        const values = lines[i].split(delimiter);
        // Skip empty lines
        if (!values.length || (values.length === 1 && !values[0].trim()))
            continue;
        const row = {};
        // Map values to headers
        if (hasHeader) {
            headers.forEach((header, index) => {
                // Remove quotes if present
                let value = index < values.length ? values[index] : '';
                value = value.replace(/^["'](.*)["']$/, '$1');
                // Convert to appropriate type
                if (/^\d+$/.test(value)) {
                    value = parseInt(value, 10);
                }
                else if (/^\d+\.\d+$/.test(value)) {
                    value = parseFloat(value);
                }
                else if (/^(true|false)$/i.test(value)) {
                    value = value.toLowerCase() === 'true';
                }
                row[header] = value;
            });
        }
        else {
            // No header, use numeric indices
            values.forEach((value, index) => {
                // Remove quotes if present
                value = value.replace(/^["'](.*)["']$/, '$1');
                // Convert to appropriate type
                if (/^\d+$/.test(value)) {
                    value = parseInt(value, 10);
                }
                else if (/^\d+\.\d+$/.test(value)) {
                    value = parseFloat(value);
                }
                else if (/^(true|false)$/i.test(value)) {
                    value = value.toLowerCase() === 'true';
                }
                row[`column${index}`] = value;
            });
        }
        data.push(row);
    }
    return data;
};
/**
 * Parses JSON data into an array of objects
 * @param {string} jsonText - JSON data to parse
 * @returns {Array} Parsed data
 */
const parseJSON = (jsonText) => {
    try {
        const parsed = JSON.parse(jsonText);
        return Array.isArray(parsed) ? parsed : [parsed];
    }
    catch (error) {
        console.error('Error parsing JSON:', error);
        return [];
    }
};
/**
 * ImportDialog component
 * @param {Object} props - Component props
 * @param {boolean} props.isOpen - Whether the dialog is open
 * @param {Function} props.onClose - Close handler
 * @param {Function} props.onImport - Import handler
 * @param {Array} props.formats - Available import formats (default: ['csv', 'json'])
 * @param {string} props.defaultFormat - Default import format (default: 'csv')
 * @param {Object} props.parsingOptions - Options for parsing (default: {})
 * @param {string} props.className - Additional CSS classes
 * @param {Object} props.style - Additional inline styles
 * @returns {React.ReactElement|null} ImportDialog component or null if closed
 */
const ImportDialog = ({ isOpen, onClose, onImport, formats = ['csv', 'json'], defaultFormat = 'csv', parsingOptions = {}, className = '', style = {}, ...rest }) => {
    // State
    const [selectedFormat, setSelectedFormat] = (0, react_1.useState)(defaultFormat);
    const [fileContent, setFileContent] = (0, react_1.useState)('');
    const [fileName, setFileName] = (0, react_1.useState)('');
    const [parseError, setParseError] = (0, react_1.useState)('');
    const [hasHeader, setHasHeader] = (0, react_1.useState)(true);
    const [delimiter, setDelimiter] = (0, react_1.useState)(',');
    const [previewData, setPreviewData] = (0, react_1.useState)([]);
    const fileInputRef = (0, react_1.useRef)(null);
    // Handle format change
    const handleFormatChange = (e) => {
        setSelectedFormat(e.target.value);
        setFileContent('');
        setFileName('');
        setParseError('');
        setPreviewData([]);
    };
    // Handle file selection
    const handleFileChange = (e) => {
        const file = e.target.files[0];
        if (!file)
            return;
        setFileName(file.name);
        const reader = new FileReader();
        reader.onload = (event) => {
            const content = event.target.result;
            setFileContent(content);
            try {
                let data = [];
                if (selectedFormat === 'csv') {
                    data = parseCSV(content, { delimiter, hasHeader });
                }
                else if (selectedFormat === 'json') {
                    data = parseJSON(content);
                }
                setPreviewData(data.slice(0, 5)); // Preview first 5 rows
                setParseError('');
            }
            catch (error) {
                setParseError(`Error parsing file: ${error.message}`);
                setPreviewData([]);
            }
        };
        reader.onerror = () => {
            setParseError('Error reading file');
            setPreviewData([]);
        };
        reader.readAsText(file);
    };
    // Handle manual input
    const handleManualInput = (e) => {
        const content = e.target.value;
        setFileContent(content);
        try {
            let data = [];
            if (selectedFormat === 'csv') {
                data = parseCSV(content, { delimiter, hasHeader });
            }
            else if (selectedFormat === 'json') {
                data = parseJSON(content);
            }
            setPreviewData(data.slice(0, 5)); // Preview first 5 rows
            setParseError('');
        }
        catch (error) {
            setParseError(`Error parsing data: ${error.message}`);
            setPreviewData([]);
        }
    };
    // Handle delimiter change
    const handleDelimiterChange = (e) => {
        setDelimiter(e.target.value);
        if (fileContent && selectedFormat === 'csv') {
            try {
                const data = parseCSV(fileContent, {
                    delimiter: e.target.value,
                    hasHeader
                });
                setPreviewData(data.slice(0, 5));
                setParseError('');
            }
            catch (error) {
                setParseError(`Error parsing with new delimiter: ${error.message}`);
            }
        }
    };
    // Handle header change
    const handleHeaderChange = (e) => {
        setHasHeader(e.target.checked);
        if (fileContent && selectedFormat === 'csv') {
            try {
                const data = parseCSV(fileContent, {
                    delimiter,
                    hasHeader: e.target.checked
                });
                setPreviewData(data.slice(0, 5));
                setParseError('');
            }
            catch (error) {
                setParseError(`Error parsing with header option: ${error.message}`);
            }
        }
    };
    // Handle import
    const handleImport = (0, react_1.useCallback)(() => {
        if (!fileContent) {
            setParseError('No data to import');
            return;
        }
        try {
            let data = [];
            if (selectedFormat === 'csv') {
                data = parseCSV(fileContent, { delimiter, hasHeader });
            }
            else if (selectedFormat === 'json') {
                data = parseJSON(fileContent);
            }
            if (data.length === 0) {
                setParseError('No data found to import');
                return;
            }
            // Call the onImport callback with the parsed data
            onImport(data);
            // Close the dialog
            onClose();
        }
        catch (error) {
            setParseError(`Error importing data: ${error.message}`);
        }
    }, [fileContent, selectedFormat, delimiter, hasHeader, onImport, onClose]);
    // Don't render if not open
    if (!isOpen)
        return null;
    return ((0, jsx_runtime_1.jsx)("div", { className: `bf-import-dialog ${className}`, style: style, ...rest, children: (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__content", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__header", children: [(0, jsx_runtime_1.jsx)("h2", { className: "bf-import-dialog__title", children: "Import Data" }), (0, jsx_runtime_1.jsx)("button", { className: "bf-import-dialog__close-button", onClick: onClose, "aria-label": "Close", children: "\u00D7" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__body", children: [(0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__section", children: [(0, jsx_runtime_1.jsx)("h3", { className: "bf-import-dialog__section-title", children: "Import Format" }), (0, jsx_runtime_1.jsx)("div", { className: "bf-import-dialog__format-options", children: formats.map(format => ((0, jsx_runtime_1.jsxs)("label", { className: "bf-import-dialog__format-option", children: [(0, jsx_runtime_1.jsx)("input", { type: "radio", name: "import-format", value: format, checked: selectedFormat === format, onChange: handleFormatChange }), (0, jsx_runtime_1.jsx)("span", { className: "bf-import-dialog__format-label", children: format.toUpperCase() })] }, format))) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__section", children: [(0, jsx_runtime_1.jsx)("h3", { className: "bf-import-dialog__section-title", children: "Upload File" }), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__file-upload", children: [(0, jsx_runtime_1.jsx)("input", { type: "file", ref: fileInputRef, className: "bf-import-dialog__file-input", accept: selectedFormat === 'csv' ? '.csv' : '.json', onChange: handleFileChange }), (0, jsx_runtime_1.jsx)("div", { className: "bf-import-dialog__file-info", children: fileName ? ((0, jsx_runtime_1.jsx)("span", { className: "bf-import-dialog__filename", children: fileName })) : ((0, jsx_runtime_1.jsx)("span", { className: "bf-import-dialog__no-file", children: "No file selected" })) })] })] }), selectedFormat === 'csv' && ((0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__section", children: [(0, jsx_runtime_1.jsx)("h3", { className: "bf-import-dialog__section-title", children: "CSV Options" }), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__csv-options", children: [(0, jsx_runtime_1.jsxs)("label", { className: "bf-import-dialog__option", children: [(0, jsx_runtime_1.jsx)("span", { children: "Delimiter:" }), (0, jsx_runtime_1.jsxs)("select", { className: "bf-import-dialog__delimiter-select", value: delimiter, onChange: handleDelimiterChange, children: [(0, jsx_runtime_1.jsx)("option", { value: ",", children: "Comma (,)" }), (0, jsx_runtime_1.jsx)("option", { value: ";", children: "Semicolon (;)" }), (0, jsx_runtime_1.jsx)("option", { value: "\\t", children: "Tab (\\t)" }), (0, jsx_runtime_1.jsx)("option", { value: "|", children: "Pipe (|)" })] })] }), (0, jsx_runtime_1.jsxs)("label", { className: "bf-import-dialog__option", children: [(0, jsx_runtime_1.jsx)("input", { type: "checkbox", checked: hasHeader, onChange: handleHeaderChange }), (0, jsx_runtime_1.jsx)("span", { children: "First row contains headers" })] })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__section", children: [(0, jsx_runtime_1.jsxs)("h3", { className: "bf-import-dialog__section-title", children: ["Manual Input", (0, jsx_runtime_1.jsx)("span", { className: "bf-import-dialog__section-hint", children: "(or edit uploaded file)" })] }), (0, jsx_runtime_1.jsx)("textarea", { className: "bf-import-dialog__manual-input", value: fileContent, onChange: handleManualInput, placeholder: `Paste ${selectedFormat.toUpperCase()} data here`, rows: 8 })] }), parseError && ((0, jsx_runtime_1.jsx)("div", { className: "bf-import-dialog__error", children: parseError })), previewData.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__section", children: [(0, jsx_runtime_1.jsx)("h3", { className: "bf-import-dialog__section-title", children: "Preview" }), (0, jsx_runtime_1.jsx)("div", { className: "bf-import-dialog__preview", children: (0, jsx_runtime_1.jsxs)("table", { className: "bf-import-dialog__preview-table", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsx)("tr", { children: Object.keys(previewData[0]).map(key => ((0, jsx_runtime_1.jsx)("th", { children: key }, key))) }) }), (0, jsx_runtime_1.jsx)("tbody", { children: previewData.map((row, rowIndex) => ((0, jsx_runtime_1.jsx)("tr", { children: Object.values(row).map((value, colIndex) => ((0, jsx_runtime_1.jsx)("td", { children: typeof value === 'object' ? JSON.stringify(value) : value }, colIndex))) }, rowIndex))) })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__preview-note", children: ["Showing ", previewData.length, " of ", previewData.length, " rows"] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "bf-import-dialog__actions", children: [(0, jsx_runtime_1.jsx)("button", { className: "bf-import-dialog__cancel-button", onClick: onClose, children: "Cancel" }), (0, jsx_runtime_1.jsx)("button", { className: "bf-import-dialog__import-button", onClick: handleImport, disabled: !fileContent || parseError, children: "Import" })] })] })] }) }));
};
exports.ImportDialog = ImportDialog;
exports.ImportDialog.propTypes = {
    isOpen: prop_types_1.default.bool.isRequired,
    onClose: prop_types_1.default.func.isRequired,
    onImport: prop_types_1.default.func.isRequired,
    formats: prop_types_1.default.arrayOf(prop_types_1.default.string),
    defaultFormat: prop_types_1.default.string,
    parsingOptions: prop_types_1.default.object,
    className: prop_types_1.default.string,
    style: prop_types_1.default.object
};
exports.default = exports.ImportDialog;
//# sourceMappingURL=ImportDialog.js.map