import React from 'react';
import ReactDOM from 'react-dom';
import Address from '../../components/address/address.js';
import '../text-input/text-input.less';

/**\

    title: AutoComplete
    category: atom
    description:
        sets up a google maps autocomplete text input
        when the user selects an address, it tries to
        pass an address model through the match
        property. Requires google maps to be loaded on the page
        with the places library. Should create a service
        wrapper for this dependency.
    props:
        setFocus[Boolean]:
            sets focus on the input on the first mounting
        match[Function]:
            a callback for when the input matches a location
        update[Function]:
            a callback for handling when the input has changed
        placeholder[String]:
            the default null text to display
        altPlaceholder[String]:
            Some text to display when the textarea has no value and has focus.
            If not defined, the placeholder is used
        error[String]: Field specific error text
        label[String]:
            a string to be displayed above the input
        value[String]:
            the default value of the input

\**/

class AutoComplete extends React.Component {
    constructor(props) {
        super(props);
    }

    state = {
        focus: false
    }

    componentDidMount() {
        const node = ReactDOM.findDOMNode(this),
            elem = node.getElementsByTagName('input')[0];

        this.node = node;

        /* istanbul ignore if: document.activeElement isn't available */
        if (this.props.setFocus) {
            elem.focus();
        }

        if (typeof google === 'undefined') {
            return;
        }

        const auto = new google.maps.places.Autocomplete(
            this.node.getElementsByTagName('input')[0],
            { types: [ 'geocode' ] }
        );

        google.maps.event.addListener(
            auto,
            'place_changed',
            this.processChange.bind(this, auto)
        );
    }

    componentWillUnmount() {
        /* istanbul ignore next: untestable for now */
        this.node = null;
    }

    componentWillReceiveProps(props) {
        /* istanbul ignore else: no one cares */
        if (props.hasOwnProperty('value')) {
            this.node.getElementsByTagName('input')[0].value = props.value;
        }
    }

    processChange(auto) {
        const addr = Address.fromGooglePlace(auto.getPlace());

        /* istanbul ignore else: no one cares */
        if (typeof this.props.update === 'function') {
            this.props.update(addr.street);
        }

        /* istanbul ignore else: no one cares */
        if (typeof this.props.match === 'function') {
            this.props.match(addr);
        }
    }

    onBlur() {
        this.setState({ focus: false });
    }

    onFocus() {
        this.setState({ focus: true });
    }

    update(evt) {
        /* istanbul ignore if: no one cares */
        if (typeof this.props.update !== 'function') {
            return;
        }

        this.props.update(evt.target.value);
    }

    render() {
        let placeholder = this.props.placeholder || '',
            label,
            errorTooltip,
            classer = 'text-input auto-complete';

        if (this.state.focus && this.props.altPlaceholder) {
            placeholder = this.props.altPlaceholder;
        }

        if (this.props.label) {
            label = <label>{ this.props.label }</label>;
        }

        if (this.props.error) {
            classer += ' has-error';

            errorTooltip = (
                <div className="error-tooltip">
                    { this.props.error }
                </div>
            );
        }

        return (
            <div className={ classer }>
                { label }
                <div>
                    <input type="text"
                        defaultValue={ this.props.value }
                        onChange={ this.update.bind(this) }
                        onFocus={ this.onFocus.bind(this) }
                        onBlur={ this.onBlur.bind(this) }
                        placeholder={ placeholder } />
                    { errorTooltip }
                </div>
            </div>
        );
    }
}

export default AutoComplete;
