import * as React from 'react'
import * as cx from 'classnames'

import { Row } from './row'
import { Column } from './column'
import { List, ListItem } from './list'
import { Spinner } from './spinner'
import { TextInput } from './text-input'
import { BaseFormField } from './base-form-field'
import { TextSearchProps, TextSearchComponentProps, AbstractFormField } from '../interfaces'
import { shortID } from '../utils'

const styles = require('../../src/styles/components/forms.scss')

export class TextSearch extends React.Component<TextSearchComponentProps, {}> {
    public render(): JSX.Element {
        const { field, placeholder } = this.props
        return (
            <Column className={styles.searchContainer}>
                <Row className={this.classNames(field)}>
                    <input
                        className={styles.input}
                        type="text"
                        value={field.value}
                        placeholder={placeholder}
                        onChange={this.handleInputChange}
                        onFocus={this.handleInputFocus}
                        onBlur={this.handleInputBlur} />
                    {this.renderSpinner()}
                </Row>
                {this.renderSearchResults()}
            </Column>
        )
    }

    private renderSpinner(): JSX.Element {
        return <Spinner visible={this.props.loading} />
    }

    private renderSearchResults(): JSX.Element | null {
        if (!this.props.dropdownOpen) return null
        return (
            <List
                className={styles.resultsContainer}>
                {this.props.searchResults.map(o =>
                    <ListItem
                        key={shortID()}
                        onClick={this.mkHandleSetSelected(o)}>
                        {o.suggestion}
                    </ListItem>,
                )}
            </List>
        )
    }

    private mkHandleSetSelected = (o: any) => () => {
        this.props.setSelected(o)
    }

    private handleInputFocus = () => this.props.setFocus(true)
    private handleInputBlur = () => this.props.setFocus(false)

    private handleInputChange = (e: React.SyntheticEvent<any>) => {
        this.props.setSearch(e.currentTarget.value)
    }

    private classNames(field: AbstractFormField<string>) {
        return cx(
            this.props.className,
            styles.inputContainer,
            {
                [styles.focus]: this.props.isFocused,
                [styles.success]: field.valid,
                [styles.error]: field.errors.length > 0 || (field.dirty && !field.valid),
            },
        )
    }
}
