import * as React from 'react';
import { copyTransforms, RefinerProps } from './utils';
import { debounce } from 'lodash';

interface CategoricalState {
    inputValue?: any;
}

/**
 * Column Component to add filter/refinement functionality to a categorical table column.
 */
export class ColumnCategoricalRefinerComponent extends React.Component<
    RefinerProps,
    CategoricalState
> {
    transformUpdateDebounced;
    constructor(props) {
        super(props);
        this.state = { inputValue: '' };

        // debounce updating the transforms with input value
        const delay =
            this.props.transformsDelay === undefined
                ? 1000
                : this.props.transformsDelay;
        const transformUpdateHandler = () => {
            this.updateTransforms(this.state.inputValue);
        };
        this.transformUpdateDebounced = debounce(transformUpdateHandler, delay);
    }

    updateTransforms(value) {
        let config = this.props.config,
            newTransforms,
            refinementTransform;

        // make a complete copy of the transforms
        newTransforms = copyTransforms(this.props.transforms);

        if (
            Object.prototype.hasOwnProperty.call(
                newTransforms.filters,
                config.columnName
            )
        ) {
            refinementTransform = newTransforms.filters[config.columnName];
        } else {
            refinementTransform = {
                type: 'categorical',
                column: config.columnName,
            };
        }

        refinementTransform.value = value;
        newTransforms.filters[config.columnName] = refinementTransform;

        this.props.setTransforms(newTransforms);
    }

    /**
     * Handles changes to the input field.
     *  If there is a value in the input field, set a categorical transform with that value on config.columnName.
     * @param evt
     */
    handleInputChange(evt) {
        let value = evt.target.value;

        if (value === undefined || value === null) {
            value = '';
        }

        // debounce updating the transforms with input value
        this.transformUpdateDebounced();

        this.setState(
            {
                inputValue: value,
            },
            () => {
                if (this.state.inputValue) {
                    this.props.setIsFiltered(true);
                } else {
                    this.props.setIsFiltered(false);
                }
            }
        );
    }

    clearInputs = () => {
        // debounce updating the transforms with input value
        this.transformUpdateDebounced();

        this.setState(
            {
                inputValue: '',
            },
            () => {
                this.props.setIsFiltered(false);
            }
        );
    };

    /**
     * Render Column Component
     */
    render() {
        return (
            <React.Fragment>
                <input
                    className="form-control mmui-form-control"
                    type="text"
                    value={this.state.inputValue}
                    placeholder="Search"
                    onChange={this.handleInputChange.bind(this)}
                />
                <div>
                    <button
                        type="button"
                        className="mmui-reset-link btn btn-link pl-0"
                        onClick={this.clearInputs}
                    >
                        Clear
                    </button>
                </div>
            </React.Fragment>
        );
    }
}
