import FieldType from "../Types/FieldType";
import FilterOperator from "./Types/FilterOperator";
import OperatorSelector from "./OperatorSelector";
import EqualTo from "../../../Types/BaseDatabase/EqualTo";
import NotEqual from "../../../Types/BaseDatabase/NotEqual";
import GreaterThan from "../../../Types/BaseDatabase/GreaterThan";
import LessThan from "../../../Types/BaseDatabase/LessThan";
import GreaterThanOrEqual from "../../../Types/BaseDatabase/GreaterThanOrEqual";
import LessThanOrEqual from "../../../Types/BaseDatabase/LessThanOrEqual";
import InBetween from "../../../Types/BaseDatabase/InBetween";
import IsNull from "../../../Types/BaseDatabase/IsNull";
import NotNull from "../../../Types/BaseDatabase/NotNull";
import React, { useEffect, useState } from "react";
const NUMBER_OPERATORS = [
    FilterOperator.EqualTo,
    FilterOperator.NotEqualTo,
    FilterOperator.GreaterThan,
    FilterOperator.LessThan,
    FilterOperator.GreaterThanOrEqualTo,
    FilterOperator.LessThanOrEqualTo,
    FilterOperator.Between,
    FilterOperator.IsEmpty,
    FilterOperator.IsNotEmpty,
];
const detectState = (rawValue) => {
    var _a, _b;
    if (rawValue instanceof InBetween) {
        return {
            operator: FilterOperator.Between,
            value: ((_a = rawValue.startValue) !== null && _a !== void 0 ? _a : "").toString(),
            endValue: ((_b = rawValue.endValue) !== null && _b !== void 0 ? _b : "").toString(),
        };
    }
    if (rawValue instanceof EqualTo) {
        return {
            operator: FilterOperator.EqualTo,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof NotEqual) {
        return {
            operator: FilterOperator.NotEqualTo,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof GreaterThan) {
        return {
            operator: FilterOperator.GreaterThan,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof LessThan) {
        return {
            operator: FilterOperator.LessThan,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof GreaterThanOrEqual) {
        return {
            operator: FilterOperator.GreaterThanOrEqualTo,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof LessThanOrEqual) {
        return {
            operator: FilterOperator.LessThanOrEqualTo,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    if (rawValue instanceof IsNull) {
        return { operator: FilterOperator.IsEmpty, value: "", endValue: "" };
    }
    if (rawValue instanceof NotNull) {
        return { operator: FilterOperator.IsNotEmpty, value: "", endValue: "" };
    }
    if (typeof rawValue === "number") {
        return {
            operator: FilterOperator.EqualTo,
            value: rawValue.toString(),
            endValue: "",
        };
    }
    return { operator: FilterOperator.EqualTo, value: "", endValue: "" };
};
const buildValue = (state) => {
    const startNum = parseFloat(state.value);
    const endNum = parseFloat(state.endValue);
    const hasStart = !Number.isNaN(startNum) && state.value !== "";
    const hasEnd = !Number.isNaN(endNum) && state.endValue !== "";
    switch (state.operator) {
        case FilterOperator.EqualTo:
            return hasStart ? new EqualTo(startNum) : undefined;
        case FilterOperator.NotEqualTo:
            return hasStart ? new NotEqual(startNum) : undefined;
        case FilterOperator.GreaterThan:
            return hasStart ? new GreaterThan(startNum) : undefined;
        case FilterOperator.LessThan:
            return hasStart ? new LessThan(startNum) : undefined;
        case FilterOperator.GreaterThanOrEqualTo:
            return hasStart ? new GreaterThanOrEqual(startNum) : undefined;
        case FilterOperator.LessThanOrEqualTo:
            return hasStart ? new LessThanOrEqual(startNum) : undefined;
        case FilterOperator.Between:
            return hasStart && hasEnd ? new InBetween(startNum, endNum) : undefined;
        case FilterOperator.IsEmpty:
            return new IsNull();
        case FilterOperator.IsNotEmpty:
            return new NotNull();
        default:
            return undefined;
    }
};
const NumberFilter = (props) => {
    const filter = props.filter;
    if (filter.filterDropdownOptions) {
        return React.createElement(React.Fragment, null);
    }
    if (filter.type !== FieldType.Number) {
        return React.createElement(React.Fragment, null);
    }
    const detected = detectState(props.filterData[filter.key]);
    const [localOperator, setLocalOperator] = useState(detected.operator);
    useEffect(() => {
        const raw = props.filterData[filter.key];
        if (raw !== undefined && raw !== null) {
            setLocalOperator(detected.operator);
        }
    }, [props.filterData[filter.key]]);
    const state = Object.assign(Object.assign({}, detected), { operator: localOperator });
    const valuelessOperator = state.operator === FilterOperator.IsEmpty ||
        state.operator === FilterOperator.IsNotEmpty;
    const isBetween = state.operator === FilterOperator.Between;
    const apply = (nextState) => {
        var _a;
        if (!filter.key) {
            return;
        }
        setLocalOperator(nextState.operator);
        const next = Object.assign({}, props.filterData);
        const built = buildValue(nextState);
        if (built === undefined) {
            delete next[filter.key];
        }
        else {
            next[filter.key] = built;
        }
        (_a = props.onFilterChanged) === null || _a === void 0 ? void 0 : _a.call(props, next);
    };
    return (React.createElement("div", { className: "flex gap-2 items-start" },
        React.createElement(OperatorSelector, { value: state.operator, options: NUMBER_OPERATORS, onChange: (nextOperator) => {
                apply(Object.assign(Object.assign({}, state), { operator: nextOperator }));
            } }),
        !valuelessOperator && (React.createElement("div", { className: isBetween ? "flex-1 flex gap-2 min-w-0" : "flex-1 min-w-0" },
            React.createElement("div", { className: "flex-1 min-w-0" },
                React.createElement("input", { type: "number", value: state.value, onChange: (e) => {
                        apply(Object.assign(Object.assign({}, state), { value: e.target.value }));
                    }, placeholder: isBetween ? "From" : `Filter by ${filter.title}`, className: "block w-full rounded-md border border-gray-300 bg-white py-2 pl-3 pr-3 text-sm placeholder-gray-500 focus:border-indigo-500 focus:text-gray-900 focus:placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm" })),
            isBetween && (React.createElement("div", { className: "flex-1 min-w-0" },
                React.createElement("input", { type: "number", value: state.endValue, onChange: (e) => {
                        apply(Object.assign(Object.assign({}, state), { endValue: e.target.value }));
                    }, placeholder: "To", className: "block w-full rounded-md border border-gray-300 bg-white py-2 pl-3 pr-3 text-sm placeholder-gray-500 focus:border-indigo-500 focus:text-gray-900 focus:placeholder-gray-400 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm" })))))));
};
export default NumberFilter;
//# sourceMappingURL=NumberFilter.js.map