import * as React from 'react';
import {Radio} from '../form/Radio';
import {TextInput} from '../form/TextInput';
import {Form} from '../form/Form';
import {Highlighter} from '../Highlighter';
import {PropertyFilterTitle} from './PropertyFilterTitle';
import {propertyFieldContext} from './context';
import {PropertyFilterOptionDescriptor, PropertyFilterContext} from './types';

type PropertyFilterSelectProps = {
    id: string;
    title: string;
    options: Array<PropertyFilterOptionDescriptor>;
    hasSearch?: boolean;
    searchLabel: string;
    noResultsLabel: string;
    testAutomationId: string;
};

type PropertyFilterSelectState = {
    searchQuery: string;
};

export class PropertyFilterSelect extends React.PureComponent<
    PropertyFilterSelectProps,
    PropertyFilterSelectState
> {
    static contextType = propertyFieldContext;

    static defaultProps = {
        searchLabel: 'Search',
        noResultsLabel: 'No results',
        testAutomationId: 'propertyFilterSelect'
    };

    state = {
        searchQuery: ''
    };

    fieldID = (Math.random() * 1000000).toFixed(0);

    handleSearchChange = event => {
        this.setState({
            searchQuery: event.target.value
        });
    };

    renderOption = (option: PropertyFilterOptionDescriptor, index: number) => {
        const {searchQuery} = this.state;
        const searchRegExp = new RegExp(searchQuery, 'i');

        return (
            <Radio
                noOffset
                className="rc-property-filter__section-item"
                data-test-automation-id={`item-${index}`}
                key={option.id}
                name={this.fieldID}
                value={option.id}
                disabled={option.disabled}>
                <Highlighter highlightRegexp={searchRegExp}>{option.title}</Highlighter>
            </Radio>
        );
    };

    renderRoot = (context: PropertyFilterContext) => {
        const {id, title, testAutomationId} = this.props;

        const value = context.values[id] || '';
        const onChange = context.onChange;

        const formValue = {[this.fieldID]: value};
        const changeHandler = formData => {
            onChange(id, formData[this.fieldID]);
        };

        return (
            <section
                className="rc-property-filter__section"
                data-test-automation-id={testAutomationId}>
                <Form noContainer value={formValue} onChange={changeHandler}>
                    <PropertyFilterTitle key="title">{title}</PropertyFilterTitle>
                    {this.renderSearch()}
                    <div className="rc-property-filter__section-container">
                        {this.renderOptions()}
                    </div>
                </Form>
            </section>
        );
    };

    renderOptions = () => {
        const {options, noResultsLabel} = this.props;
        const {searchQuery} = this.state;
        const optionNodes: Array<React.ReactElement<Radio>> = [];

        for (let index = 0; index < options.length; index++) {
            if (
                !searchQuery ||
                options[index].title
                    .toString()
                    .toLowerCase()
                    .includes(searchQuery.toLowerCase())
            ) {
                optionNodes.push(this.renderOption(options[index], index));
            }
        }

        if (optionNodes.length === 0) {
            return <div className="rc-property-filter__no-results">{noResultsLabel}</div>;
        }

        return optionNodes;
    };

    renderSearch() {
        const {id, hasSearch, searchLabel} = this.props;
        const {searchQuery} = this.state;

        if (!hasSearch) {
            return null;
        }

        return (
            <TextInput
                className="rc-property-filter__search"
                name={`filterSearch-${id}`}
                placeholder={searchLabel}
                value={searchQuery}
                onChange={this.handleSearchChange}
            />
        );
    }

    render() {
        return <propertyFieldContext.Consumer>{this.renderRoot}</propertyFieldContext.Consumer>;
    }
}
