import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Icon } from "@powerhousedao/design-system";
import { useCallback, useMemo, useState } from "react";
import { twMerge } from "tailwind-merge";
import { ConnectSelect } from "../../select/select.js";
function getAvailableOperators(column) {
    const baseOperators = [
        "=",
        "!=",
        ">",
        "<",
        ">=",
        "<=",
        "IS NULL",
        "IS NOT NULL",
    ];
    const dataType = column.dataType.toLowerCase();
    // Text types get LIKE and ILIKE
    if (dataType.includes("varchar") ||
        dataType.includes("text") ||
        dataType.includes("char")) {
        return [...baseOperators, "LIKE", "ILIKE"];
    }
    // Numeric types don't get LIKE/ILIKE
    if (dataType.includes("int") ||
        dataType.includes("decimal") ||
        dataType.includes("numeric") ||
        dataType.includes("real") ||
        dataType.includes("double") ||
        dataType.includes("float") ||
        dataType.includes("bigint") ||
        dataType.includes("smallint")) {
        return baseOperators;
    }
    // Default: all operators except LIKE/ILIKE
    return baseOperators;
}
function getInputType(column, operator) {
    if (operator === "IS NULL" || operator === "IS NOT NULL") {
        return "text"; // Will be hidden anyway
    }
    const dataType = column.dataType.toLowerCase();
    if (dataType.includes("int") ||
        dataType.includes("decimal") ||
        dataType.includes("numeric") ||
        dataType.includes("real") ||
        dataType.includes("double") ||
        dataType.includes("float") ||
        dataType.includes("bigint") ||
        dataType.includes("smallint")) {
        return "number";
    }
    if (dataType.includes("timestamp") ||
        dataType.includes("date") ||
        dataType.includes("time")) {
        return "datetime-local";
    }
    return "text";
}
function FilterClauseComponent({ clause, columns, onUpdate, onRemove, showConnector, connector, onConnectorChange, }) {
    const column = columns.find((c) => c.name === clause.column);
    const availableOperators = column
        ? getAvailableOperators(column)
        : ["=", "!="];
    const inputType = column ? getInputType(column, clause.operator) : "text";
    const showValueInput = clause.operator !== "IS NULL" && clause.operator !== "IS NOT NULL";
    const columnItems = useMemo(() => columns.map((col) => ({
        value: col.name,
        displayValue: col.name,
    })), [columns]);
    const operatorItems = useMemo(() => availableOperators.map((op) => ({
        value: op,
        displayValue: op,
    })), [availableOperators]);
    const connectorItems = useMemo(() => [
        { value: "AND", displayValue: "AND" },
        { value: "OR", displayValue: "OR" },
    ], []);
    const handleColumnChange = useCallback((columnName) => {
        const newColumn = columns.find((c) => c.name === columnName);
        if (!newColumn)
            return;
        const newAvailableOperators = getAvailableOperators(newColumn);
        const newOperator = newAvailableOperators.includes(clause.operator)
            ? clause.operator
            : newAvailableOperators[0];
        onUpdate({
            ...clause,
            column: columnName,
            operator: newOperator,
            value: "",
        });
    }, [clause, columns, onUpdate]);
    const handleOperatorChange = useCallback((operator) => {
        onUpdate({
            ...clause,
            operator,
            value: operator === "IS NULL" || operator === "IS NOT NULL"
                ? ""
                : clause.value,
        });
    }, [clause, onUpdate]);
    const handleValueChange = useCallback((value) => {
        onUpdate({
            ...clause,
            value,
        });
    }, [clause, onUpdate]);
    return (_jsxs("div", { className: "flex items-center gap-2", children: [showConnector && (_jsx(ConnectSelect, { absolutePositionMenu: true, borderRadius: "4px", containerClassName: "min-w-[80px]", id: `connector-${clause.id}`, items: connectorItems, itemClassName: "px-2 py-1 text-xs", menuClassName: "px-2 py-1 text-xs min-w-[80px]", value: connector, onChange: onConnectorChange })), _jsx(ConnectSelect, { absolutePositionMenu: true, borderRadius: "4px", containerClassName: "min-w-[150px]", id: `column-${clause.id}`, items: columnItems, itemClassName: "px-2 py-1 text-xs", menuClassName: "px-2 py-1 text-xs min-w-[150px]", value: clause.column, onChange: handleColumnChange }), _jsx(ConnectSelect, { absolutePositionMenu: true, borderRadius: "4px", containerClassName: "min-w-[100px]", id: `operator-${clause.id}`, items: operatorItems, itemClassName: "px-2 py-1 text-xs", menuClassName: "px-2 py-1 text-xs min-w-[100px]", value: clause.operator, onChange: handleOperatorChange }), showValueInput && (_jsx("input", { className: "min-w-[150px] rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-900", type: inputType, value: clause.value, onChange: (e) => handleValueChange(e.target.value) })), _jsx("button", { className: "flex items-center justify-center rounded p-1 text-gray-500 hover:bg-gray-200 hover:text-gray-700", onClick: onRemove, title: "Remove filter", type: "button", children: _jsx(Icon, { name: "Xmark", size: 14 }) })] }));
}
export function FilterBar({ columns, filters, onFiltersChange, }) {
    const [isExpanded, setIsExpanded] = useState(false);
    const handleAddFilter = useCallback(() => {
        const newClause = {
            id: `filter-${Date.now()}-${Math.random()}`,
            column: columns[0]?.name ?? "",
            operator: "=",
            value: "",
        };
        if (!filters) {
            onFiltersChange({
                clauses: [newClause],
                connectors: [],
            });
        }
        else {
            onFiltersChange({
                clauses: [...filters.clauses, newClause],
                connectors: [
                    ...filters.connectors,
                    filters.clauses.length > 0 ? "AND" : "AND",
                ],
            });
        }
        setIsExpanded(true);
    }, [columns, filters, onFiltersChange]);
    const handleUpdateClause = useCallback((index, clause) => {
        if (!filters)
            return;
        const newClauses = [...filters.clauses];
        newClauses[index] = clause;
        onFiltersChange({
            ...filters,
            clauses: newClauses,
        });
    }, [filters, onFiltersChange]);
    const handleRemoveClause = useCallback((index) => {
        if (!filters)
            return;
        const newClauses = filters.clauses.filter((_, i) => i !== index);
        const newConnectors = filters.connectors.filter((_, i) => i !== index - 1);
        if (newClauses.length === 0) {
            onFiltersChange(undefined);
        }
        else {
            onFiltersChange({
                clauses: newClauses,
                connectors: newConnectors,
            });
        }
    }, [filters, onFiltersChange]);
    const handleConnectorChange = useCallback((index, connector) => {
        if (!filters)
            return;
        const newConnectors = [...filters.connectors];
        newConnectors[index] = connector;
        onFiltersChange({
            ...filters,
            connectors: newConnectors,
        });
    }, [filters, onFiltersChange]);
    const hasFilters = filters && filters.clauses.length > 0;
    return (_jsxs("div", { className: "flex shrink-0 flex-col gap-2 rounded-lg border border-gray-300 bg-white p-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("button", { className: "flex items-center gap-1 text-xs text-gray-700 hover:text-gray-900", onClick: () => setIsExpanded(!isExpanded), type: "button", children: [_jsx(Icon, { className: twMerge("transition-transform", isExpanded && "rotate-90"), name: "ChevronDown", size: 12 }), _jsx("span", { children: "Filters" }), hasFilters && (_jsx("span", { className: "rounded bg-blue-100 px-1.5 py-0.5 text-xs text-blue-700", children: filters.clauses.length }))] }), _jsxs("button", { className: "flex items-center gap-1 rounded border border-gray-300 bg-white px-2 py-1 text-xs text-gray-700 hover:bg-gray-100", onClick: handleAddFilter, type: "button", children: [_jsx(Icon, { name: "Plus", size: 12 }), "Add Filter"] })] }), isExpanded && hasFilters && (_jsx("div", { className: "flex flex-col gap-2", children: filters.clauses.map((clause, index) => (_jsx(FilterClauseComponent, { clause: clause, columns: columns, connector: index > 0 ? (filters.connectors[index - 1] ?? "AND") : "AND", onConnectorChange: (connector) => handleConnectorChange(index - 1, connector), onRemove: () => handleRemoveClause(index), onUpdate: (updatedClause) => handleUpdateClause(index, updatedClause), showConnector: index > 0 }, clause.id))) }))] }));
}
//# sourceMappingURL=filter-bar.js.map