"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var assign = require("lodash/assign");
var find = require("lodash/find");
var findKey = require("lodash/findKey");
var includes = require("lodash/includes");
var isString = require("lodash/isString");
var mapValues = require("lodash/mapValues");
var React = require("react");
var utils = require("../../utils");
var Grid_1 = require("../Grid");
var Input_1 = require("../Input");
var getKeyLabel = function (schema) {
    var s = find(schema.properties, { description: 'key' });
    return s && s.title ? s.title : 'key';
};
var getValueLabel = function (schema) {
    var s = find(schema.properties, { description: 'value' });
    return s && s.title ? s.title : 'value';
};
exports.operators = {
    is: {
        getLabel: function (_s) { return 'is'; },
    },
    is_not: {
        getLabel: function (_s) { return 'is not'; },
    },
    key_is: {
        getLabel: function (s) { return getKeyLabel(s) + " is"; },
    },
    key_contains: {
        getLabel: function (s) { return getKeyLabel(s) + " contains"; },
    },
    key_not_contains: {
        getLabel: function (s) { return getKeyLabel(s) + " does not contain"; },
    },
    key_matches_re: {
        getLabel: function (s) { return getKeyLabel(s) + " matches RegEx"; },
    },
    key_not_matches_re: {
        getLabel: function (s) { return getKeyLabel(s) + " does not match RegEx"; },
    },
    value_is: {
        getLabel: function (s) { return getValueLabel(s) + " is"; },
    },
    value_contains: {
        getLabel: function (s) { return getValueLabel(s) + " contains"; },
    },
    value_not_contains: {
        getLabel: function (s) { return getValueLabel(s) + " does not contain"; },
    },
    value_matches_re: {
        getLabel: function (s) { return getValueLabel(s) + " matches RegEx"; },
    },
    value_not_matches_re: {
        getLabel: function (s) { return getValueLabel(s) + " does not match RegEx"; },
    },
};
var keyOperators = [
    'is',
    'is_not',
    'key_is',
    'key_contains',
    'key_not_contains',
    'key_matches_re',
    'key_not_matches_re',
];
var valueOperators = [
    'is',
    'is_not',
    'value_is',
    'value_contains',
    'value_not_contains',
    'value_matches_re',
    'value_not_matches_re',
];
exports.decodeFilter = function (filter) {
    var operator = filter.title;
    if (!filter.properties) {
        return null;
    }
    var keys = Object.keys(filter.properties);
    if (!keys.length) {
        return null;
    }
    var value;
    var field = keys[0];
    if (operator === 'is') {
        value = mapValues(filter.properties[field].contains.properties, function (v) { return v.const; });
    }
    else if (operator === 'is_not') {
        value = mapValues(filter.properties[field].not.contains.properties, function (v) { return v.const; });
    }
    else if (operator === 'key_is' || operator === 'value_is') {
        value = mapValues(filter.properties[field].contains.properties, function (v) { return v.const; });
    }
    else if (operator === 'key_contains' || operator === 'value_contains') {
        value = mapValues(filter.properties[field].contains.properties, function (v) { return v.description; });
    }
    else if (operator === 'key_not_contains' ||
        operator === 'value_not_contains') {
        value = mapValues(filter.properties[field].not.contains.properties, function (v) { return v.description; });
    }
    else if (operator === 'key_matches_re' || operator === 'value_matches_re') {
        value = mapValues(filter.properties[field].contains.properties, function (v) { return v.pattern; });
    }
    else if (operator === 'key_not_matches_re' ||
        operator === 'value_not_matches_re') {
        value = mapValues(filter.properties[field].not.contains.properties, function (v) { return v.pattern; });
    }
    else {
        return null;
    }
    return {
        field: field,
        operator: operator,
        value: value,
    };
};
var format = function (schema, object) {
    var keyField = findKey(schema.properties, { description: 'key' });
    var valueField = findKey(schema.properties, { description: 'value' });
    var key = object[keyField];
    var value = object[valueField];
    return key && value ? key + " : " + value : key || value;
};
exports.createFilter = function (field, operator, value, schema) {
    var title = schema.title;
    var base = {
        title: operator,
        description: (title || field) + " " + exports.operators[operator].getLabel(schema) + " " + format(schema, value),
        type: 'object',
    };
    if (operator === 'is') {
        return assign(base, {
            properties: (_a = {},
                _a[field] = {
                    contains: {
                        title: title,
                        properties: mapValues(value, function (v) { return ({ const: v }); }),
                    },
                },
                _a),
            required: [field],
        });
    }
    if (operator === 'is_not') {
        return assign(base, {
            properties: (_b = {},
                _b[field] = {
                    not: {
                        contains: {
                            title: title,
                            properties: mapValues(value, function (v) { return ({ const: v }); }),
                        },
                    },
                },
                _b),
        });
    }
    if (operator === 'key_is' || operator === 'value_is') {
        return assign(base, {
            properties: (_c = {},
                _c[field] = {
                    contains: {
                        title: title,
                        properties: mapValues(value, function (v) { return ({ const: v }); }),
                    },
                },
                _c),
            required: [field],
        });
    }
    if (operator === 'key_contains' || operator === 'value_contains') {
        return assign(base, {
            properties: (_d = {},
                _d[field] = {
                    contains: {
                        title: title,
                        properties: mapValues(value, function (v) { return ({
                            type: 'string',
                            description: v,
                            pattern: utils.regexEscape(v),
                        }); }),
                    },
                },
                _d),
            required: [field],
        });
    }
    if (operator === 'key_not_contains' || operator === 'value_not_contains') {
        return assign(base, {
            properties: (_e = {},
                _e[field] = {
                    not: {
                        contains: {
                            title: title,
                            properties: mapValues(value, function (v) { return ({
                                type: 'string',
                                description: v,
                                pattern: utils.regexEscape(v),
                            }); }),
                        },
                    },
                },
                _e),
        });
    }
    if (operator === 'key_matches_re' || operator === 'value_matches_re') {
        return assign(base, {
            properties: (_f = {},
                _f[field] = {
                    contains: {
                        title: title,
                        properties: mapValues(value, function (v) { return ({
                            type: 'string',
                            pattern: v,
                        }); }),
                    },
                },
                _f),
            required: [field],
        });
    }
    if (operator === 'key_not_matches_re' ||
        operator === 'value_not_matches_re') {
        return assign(base, {
            properties: (_g = {},
                _g[field] = {
                    not: {
                        contains: {
                            title: title,
                            properties: mapValues(value, function (v) { return ({
                                type: 'string',
                                pattern: v,
                            }); }),
                        },
                    },
                },
                _g),
        });
    }
    return base;
    var _a, _b, _c, _d, _e, _f, _g;
};
exports.Edit = function (props) {
    var schema = props.schema, onUpdate = props.onUpdate, operator = props.operator;
    var value = props.value;
    var schemaKey = findKey(schema.properties, { description: 'key' });
    var schemaValue = findKey(schema.properties, { description: 'value' });
    var keyLabel = schema.properties[schemaKey].title || 'Key';
    var valueLabel = schema.properties[schemaValue].title || 'Value';
    if (isString(value)) {
        var p = {};
        if (includes(valueOperators, operator)) {
            p[schemaValue] = value;
        }
        if (includes(keyOperators, operator)) {
            p[schemaKey] = value;
        }
        value = p;
    }
    return (React.createElement(Grid_1.Flex, { wrap: true },
        includes(keyOperators, operator) && (React.createElement(Input_1.default, { type: "text", value: value ? value[schemaKey] : '', mr: 2, mb: 1, placeholder: keyLabel, onChange: function (e) {
                return onUpdate(assign(value, (_a = {},
                    _a[schemaKey] = e.currentTarget.value,
                    _a)));
                var _a;
            } })),
        includes(valueOperators, operator) && (React.createElement(Input_1.default, { type: "text", value: value ? value[schemaValue] : '', placeholder: valueLabel, onChange: function (e) {
                return onUpdate(assign(value, (_a = {},
                    _a[schemaValue] = e.currentTarget.value,
                    _a)));
                var _a;
            } }))));
};
