import Button, { ButtonStyleType } from "../Button/Button";
import Color from "../../../Types/Color";
import Icon from "../Icon/Icon";
import IconProp from "../../../Types/Icon/IconProp";
import React, { useRef, useState, } from "react";
const parseCSV = (text) => {
    const rows = [];
    let current = "";
    let inQuotes = false;
    let row = [];
    for (let i = 0; i < text.length; i++) {
        const char = text[i];
        const nextChar = text[i + 1];
        if (inQuotes) {
            if (char === '"' && nextChar === '"') {
                current += '"';
                i++;
            }
            else if (char === '"') {
                inQuotes = false;
            }
            else {
                current += char;
            }
        }
        else if (char === '"') {
            inQuotes = true;
        }
        else if (char === ",") {
            row.push(current.trim());
            current = "";
        }
        else if (char === "\n" || (char === "\r" && nextChar === "\n")) {
            row.push(current.trim());
            current = "";
            if (row.some((cell) => {
                return cell.length > 0;
            })) {
                rows.push(row);
            }
            row = [];
            if (char === "\r") {
                i++;
            }
        }
        else {
            current += char;
        }
    }
    // Push the last row
    row.push(current.trim());
    if (row.some((cell) => {
        return cell.length > 0;
    })) {
        rows.push(row);
    }
    return rows;
};
const CSVFileUpload = (props) => {
    const [error, setError] = useState("");
    const [parsedRows, setParsedRows] = useState([]);
    const [fileName, setFileName] = useState("");
    const fileInputRef = useRef(null);
    const downloadTemplate = () => {
        const headerRow = props.columns
            .map((col) => {
            return col.title;
        })
            .join(",");
        const csvContent = headerRow + "\n";
        const blob = new Blob([csvContent], { type: "text/csv" });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = props.templateFileName || "template.csv";
        a.click();
        window.URL.revokeObjectURL(url);
    };
    const handleFileChange = (event) => {
        var _a;
        setError("");
        setParsedRows([]);
        setFileName("");
        const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
        if (!file) {
            return;
        }
        if (!file.name.toLowerCase().endsWith(".csv")) {
            setError("Please upload a CSV file.");
            return;
        }
        setFileName(file.name);
        const reader = new FileReader();
        reader.onload = (e) => {
            var _a, _b;
            const text = ((_a = e.target) === null || _a === void 0 ? void 0 : _a.result) || "";
            const rows = parseCSV(text);
            if (rows.length < 2) {
                setError("CSV file must have a header row and at least one data row.");
                return;
            }
            const headerRow = rows[0];
            // Map header titles to column keys
            const columnMap = new Map();
            for (const col of props.columns) {
                const index = headerRow.findIndex((h) => {
                    return h.toLowerCase() === col.title.toLowerCase();
                });
                if (index !== -1) {
                    columnMap.set(index, col);
                }
                else if (col.required) {
                    setError(`Required column "${col.title}" not found in CSV headers. Found: ${headerRow.join(", ")}`);
                    return;
                }
            }
            const dataRows = [];
            const errors = [];
            for (let i = 1; i < rows.length; i++) {
                const row = rows[i];
                const rowData = {};
                let hasRequiredFields = true;
                for (const [colIndex, col] of columnMap.entries()) {
                    const value = ((_b = row[colIndex]) === null || _b === void 0 ? void 0 : _b.trim()) || "";
                    rowData[col.key] = value;
                    if (col.required && !value) {
                        hasRequiredFields = false;
                        errors.push(`Row ${i}: missing required field "${col.title}"`);
                    }
                }
                if (hasRequiredFields) {
                    dataRows.push(rowData);
                }
            }
            if (dataRows.length === 0) {
                setError(errors.length > 0
                    ? `No valid rows found. ${errors.slice(0, 3).join(". ")}${errors.length > 3 ? ` and ${errors.length - 3} more errors.` : ""}`
                    : "No valid data rows found in the CSV file.");
                return;
            }
            if (errors.length > 0 && dataRows.length > 0) {
                // Some rows were skipped but we have valid data
                setError(`${errors.length} row(s) skipped due to missing required fields. ${dataRows.length} valid row(s) found.`);
            }
            setParsedRows(dataRows);
            props.onDataChanged(dataRows);
        };
        reader.onerror = () => {
            setError("Failed to read the CSV file. Please try again.");
        };
        reader.readAsText(file);
        // Reset the input so the same file can be re-uploaded
        event.target.value = "";
    };
    return (React.createElement("div", { className: "space-y-4 w-full" },
        props.description && (React.createElement("p", { className: "text-sm text-gray-500" }, props.description)),
        React.createElement("div", { className: "flex items-center space-x-3" },
            React.createElement(Button, { title: "Download CSV Template", icon: IconProp.Download, buttonStyle: ButtonStyleType.OUTLINE, onClick: downloadTemplate })),
        React.createElement("div", { className: "rounded-lg border border-gray-200 bg-gray-50 p-3" },
            React.createElement("p", { className: "text-xs font-medium text-gray-700 mb-2" }, "Expected columns:"),
            React.createElement("div", { className: "flex flex-wrap gap-2" }, props.columns.map((col) => {
                return (React.createElement("span", { key: col.key, className: `inline-flex items-center rounded px-2 py-1 text-xs font-medium ${col.required
                        ? "bg-indigo-100 text-indigo-700"
                        : "bg-gray-200 text-gray-600"}`, title: col.description },
                    col.title,
                    col.required && React.createElement("span", { className: "ml-1 text-red-500" }, "*")));
            }))),
        React.createElement("div", { className: "flex w-full justify-center rounded-md border-2 border-dashed border-gray-300 bg-white px-6 py-8 cursor-pointer hover:border-indigo-400 transition", onClick: () => {
                var _a;
                return (_a = fileInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
            } },
            React.createElement("div", { className: "flex flex-col items-center space-y-2 text-center" },
                React.createElement(Icon, { icon: IconProp.File, className: "h-10 w-10 text-gray-400" }),
                React.createElement("div", { className: "text-sm text-gray-600" },
                    React.createElement("span", { className: "font-medium text-indigo-600" }, "Click to upload CSV"),
                    " ",
                    "or drag and drop"),
                React.createElement("p", { className: "text-xs text-gray-500" }, "CSV files only"),
                React.createElement("input", { ref: fileInputRef, type: "file", accept: ".csv", className: "sr-only", onChange: handleFileChange }))),
        fileName && !error && (React.createElement("div", { className: "flex items-center rounded-lg bg-green-50 p-3" },
            React.createElement(Icon, { className: "h-5 w-5 flex-shrink-0", icon: IconProp.CheckCircle, color: new Color("#16a34a") }),
            React.createElement("div", { className: "ml-2 text-sm font-medium text-green-800" },
                fileName,
                " - ",
                parsedRows.length,
                " row(s) ready to import"))),
        error && (React.createElement("div", { className: "rounded-lg bg-red-50 p-3" },
            React.createElement("p", { className: "text-sm text-red-700" }, error))),
        parsedRows.length > 0 && (React.createElement("div", { className: "rounded-lg border border-gray-200 overflow-hidden" },
            React.createElement("div", { className: "bg-gray-50 px-4 py-2 text-xs font-medium text-gray-700" },
                "Preview (first ",
                Math.min(parsedRows.length, 5),
                " of",
                " ",
                parsedRows.length,
                " rows)"),
            React.createElement("div", { className: "overflow-x-auto" },
                React.createElement("table", { className: "min-w-full divide-y divide-gray-200" },
                    React.createElement("thead", { className: "bg-gray-50" },
                        React.createElement("tr", null, props.columns.map((col) => {
                            return (React.createElement("th", { key: col.key, className: "px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase" }, col.title));
                        }))),
                    React.createElement("tbody", { className: "divide-y divide-gray-200 bg-white" }, parsedRows.slice(0, 5).map((row, i) => {
                        return (React.createElement("tr", { key: i }, props.columns.map((col) => {
                            return (React.createElement("td", { key: col.key, className: "px-4 py-2 text-sm text-gray-900 truncate max-w-xs" }, row[col.key] || ""));
                        })));
                    }))))))));
};
export default CSVFileUpload;
//# sourceMappingURL=CSVFileUpload.js.map