import React from 'react';
import Popover from 'material-ui/Popover/Popover';
import SelectBox from './SelectBox';
import SelectWithSearch from './SelectWithSearch';
import RadioGroup from './RadioGroup';
import Checkbox from 'material-ui/Checkbox';
import TextField from 'material-ui/TextField';
import CustomSelectFilter from './CustomSelectFilter';
import { Creatable } from 'react-select';
import Select from 'react-select';
import PropTypes from 'prop-types';

/**
 * Component:
 * <div style={this.props.style} className={this.props.className}>
 *      <div style={this.props.titleStyle} className={this.props.titleClass}>
 *          {this.props.title}
 *      </div>
 *
 *      type: 'TextField'
 *          style={this.props.fieldStyle}
 *          className={this.props.inputClass}
 *          placeholder={this.props.placeholder}
 *          defaultValue={this.props.value}
 *
 *
 *      type: 'Select'
 *
 *      type: 'RadioGroup'
 *          dataSource: [],
 *          value: ''
 *
 *      type:  'CheckboxGroup'
 *      {
 *           dataSource: this.state.dataSource,
 *              > Format: [
 *                   {label: 'Fruits', value: 'FRUITS', selected: true, disabled:true},
 *                   {label: 'Vegetable', value: 'VEGETABLE', selected: false, disabled:false},
 *                   {label: 'Milk', value: 'MILK', selected: true},
 *                   {label: 'Trip Closure', value: 'TRIP_CLOSURE', selected: false}
 *               ]
 *           onChange: this.checkBoxCallback function
 *               > Signature: function(dataSource)
 *
 *       };
 *
 * </div>
 * */


export default class FormField extends React.Component {

    constructor() {
        super();

        this.getValueFunctionMap = {
            TextField: 'getTextInputValue',
            Select: 'getInputValue',
            RadioGroup: 'getInputValue',
            CustomSelectFilter : 'getCustomSelectFilterValue',
            SelectWithSearch: 'getSelectWithSearchValue'
        };

        this.getRenderFunctionMap = {
            TextField: 'createTextField',
            Select: 'createSelectBoxField',
            SelectWithSearch: 'createSelectWithSearchField',
            RadioGroup: 'createRadioGroup',
            CheckboxGroup: 'createCheckboxGroup',
            CustomSelectFilter : 'createCustomSelectFilter',
            ReactSelect : 'createReactSelectDropdown',
            customRadio : 'createCustomRadioTabButton'
        };

        this.state = {};
    }

    checkBoxCallback = (event, isInputChecked) => {
        const dataSource = this.props.dataSource;
        dataSource.map((data) => {
            if (data.value === event.target.value) {
                data.selected = isInputChecked;
            }
        });
        this.props.onChange(dataSource);
    };

    createCheckboxGroup() {
        const style = {
            marginBottom: 10,
        };
        var CheckedComponent = this.props.checkedComponent;
        return this.props.dataSource.map((data,i) => {
                if(CheckedComponent && data.selected){
                    return <div className="customCheckboxWrap"><div className="checkbox"><Checkbox
                        key={i}
                        label={data.label}
                        value={data.value}
                        checked={data.selected}
                        onCheck={this.checkBoxCallback}
                        style={style}
                        disabled={data.disabled} /></div><div className="timeInput"><CheckedComponent /></div></div>
                }else{
                    return <Checkbox
                        key={i}
                        label={data.label}
                        value={data.value}
                        checked={data.selected}
                        onCheck={this.checkBoxCallback}
                        style={style}
                        disabled={data.disabled}
                    />
                }
        });
    }

    getInputValue(ref) {
        let value = ref.getValue();
        return value;
    }

    getTextInputValue(ref) {
        return ref.value.trim();
    }

    getCustomSelectFilterValue(ref) {
        let value = ref.value();
        return value;
    }

    getSelectWithSearchValue(ref) {
      return this.state.selectedObj;
    }

    createTitleField() {
        if (this.props.title) {
            return (
                <div style={this.props.titleStyle}
                     className={`field-label ${this.props.titleClass ? this.props.titleClass : ''}`}>{this.props.title + (this.props.isRequired ? '*' : '')}</div>
            );
        }
        return (null);
    }

    createRadioGroup(fieldMap) {
        return (
            <RadioGroup ref='input'
                        defaultSelected={fieldMap.value}
                        style={fieldMap.fieldStyle}
                        name={fieldMap.name}
                        selectedValue={fieldMap.selectedValue}
                        onChange={fieldMap.onChange}
                        dataSource={fieldMap.dataSource}
                        disabled={fieldMap.disabled}/>
        );
    }

    createReactSelectDropdown(fieldMap){
        let error = false;
        let msg = '';
        if(fieldMap.errorType == 'array'){
            if(fieldMap.error && fieldMap.error.length){
                fieldMap.error.filter((el)=>{
                    if(el.field == fieldMap.error_key){
                        error = true;
                        msg = el.error;
                    }
                })
            }
        }
        return (
            <div>
                {(fieldMap.Creatable=="Yes" || fieldMap.Creatable==true || fieldMap.Creatable=='true') && <Creatable {...fieldMap} className={(error && msg)?'error':''} />}
                {(!fieldMap.Creatable||fieldMap.Creatable=='No') && <Select {...fieldMap} className={(error && msg)?'error':''} />}
                {(error && msg) && <div className="error inputLength">{msg}</div>}
            </div>
        )
    }

    createCustomRadioTabButton(fieldMap){
        return(
            <div className={`CustomRadioTabButtonContainer`}>
                <div className="label">{fieldMap.label}</div>
                <div className="tabs">
                    <div className={`tab ${(fieldMap.option1==fieldMap.value)?'selected':''}`} onClick={()=>fieldMap.onChange('isManager',fieldMap.option1,this.props.context.props)}>{fieldMap.option1}</div>
                    <div className={`tab ${(fieldMap.option2==fieldMap.value)?'selected':''}`} onClick={()=>fieldMap.onChange('isManager',fieldMap.option2,this.props.context.props)}>{fieldMap.option2}</div>
                </div>
            </div>
        )
    }

    createTextField(fieldMap) {
        let inputType = (fieldMap.inputType) ? fieldMap.inputType : 'text';
        let error = false;
        let msg = '';
        if(fieldMap.errorType == 'array'){
            if(fieldMap.error && fieldMap.error.length){
                if(fieldMap.error_key=='webpageUrl'){
                    fieldMap.error.filter((el)=>{
                        if(el.field == 'metadata'){
                            error = true;
                            msg = el.error;
                        }
                    })
                }
                else{
                    fieldMap.error.filter((el)=>{
                        if(el.field == fieldMap.error_key){
                            error = true;
                            msg = el.error;
                        }
                    })
                }
            }
        }
        var validationsArray = fieldMap.validationArray && (fieldMap.validationArray.filter((el)=>{return (Object.keys(el)[0]==fieldMap.error_key)}));
        var validationObj = (validationsArray)?validationsArray[0][fieldMap.error_key]:{};
        var charCounter;
        if(fieldMap.multiLine){
            if((validationObj['minLength']||validationObj['maxLength']||validationObj['length']) && validationObj['showLength']){
                return (
                    <div>
                        <div className={`characterWidget ${(error)?'error inputLength':'inputLength'}`}>{`${fieldMap.value.length} characters`}</div>
                        <textarea type={inputType}
                           ref='input'
                           style={fieldMap.fieldStyle}
                           className={`text-box regular-text ${(error)?'error':''} ${fieldMap.inputClass ? fieldMap.inputClass : ''}`}
                           placeholder={fieldMap.placeholder}
                           onChange={fieldMap.onChange}
                           onClick={fieldMap.onClick}
                           value={fieldMap.value}
                           readOnly={fieldMap.readOnly}>
                        </textarea>
                        { msg && msg.length && <div className={`${(error)?'error inputLength':'inputLength'}`}>{`${msg}`}</div> }
                    </div>
                );
            }
            else{
                return (
                    <div>
                        <textarea type={inputType}
                               ref='input'
                               style={fieldMap.fieldStyle}
                               className={`text-box regular-text ${(error)?'error':''} ${fieldMap.inputClass ? fieldMap.inputClass : ''}`}
                               placeholder={fieldMap.placeholder}
                               onChange={fieldMap.onChange}
                               onClick={fieldMap.onClick}
                               value={fieldMap.value}
                               readOnly={fieldMap.readOnly}></textarea>
                        { msg && msg.length && <div className={`${(error)?'error inputLength':'inputLength'}`}>{`${msg}`}</div> }
                    </div>
                )
            }
        }
        else{
            if((validationObj['minLength']||validationObj['maxLength']||validationObj['length']) && validationObj['showLength']){
                return (
                    <div>
                        <div className={`characterWidget ${(error)?'error inputLength':'inputLength'}`}>{`${(fieldMap.value)?fieldMap.value.length:0} characters`}</div>
                        <input type={inputType}
                            ref='input'
                            style={fieldMap.fieldStyle}
                            className={`text-box regular-text ${(error)?'error':''} ${fieldMap.inputClass ? fieldMap.inputClass : ''}`}
                            placeholder={fieldMap.placeholder}
                            onChange={fieldMap.onChange}
                            onClick={fieldMap.onClick}
                            value={fieldMap.value}
                            readOnly={fieldMap.readOnly}/>
                        { msg && msg.length && <div className={`${(error)?'error inputLength':'inputLength'}`}>{`${msg}`}</div> }
                    </div>
                );
            }
            else{
                return (
                    <div>
                        <input type={inputType}
                               ref='input'
                               style={fieldMap.fieldStyle}
                               className={`text-box regular-text ${(error)?'error':''} ${fieldMap.inputClass ? fieldMap.inputClass : ''}`}
                               placeholder={fieldMap.placeholder}
                               onChange={fieldMap.onChange}
                               onClick={fieldMap.onClick}
                               value={fieldMap.value}
                               readOnly={fieldMap.readOnly}/>
                        { msg && msg.length && <div className={`${(error)?'error inputLength':'inputLength'}`}>{`${msg}`}</div> }
                    </div>
                );
            }
        }
    }

    createSelectBoxField(fieldMap) {
        return (
            <SelectBox ref='input'
                       onSelect={fieldMap.onSelect}
                       selectedValue={fieldMap.selectedValue}
                       dataSource={fieldMap.dataSource}
                       value={fieldMap.value}
                       style={fieldMap.selectBoxStyle}
            />
        );
    }

    onItemSelect = (fieldMap, obj) => {
      this.setState({
        selectedObj: obj,
        openSelect: false
      });
      if(fieldMap.onItemSelect) {
        fieldMap.onItemSelect(obj);
      }
    }

    handleTouchTap = (event) => {
      // This prevents ghost click.
      event.preventDefault();
      this.setState({
        openSelect: true,
        anchorEl: event.currentTarget
      });
    };

    handleRequestClose = () => {
      this.setState({
        openSelect: false
      });
    };

    createSelectWithSearchField(fieldMap) {
      return (
        <div className='select-with-search'>
          <div className='field flex justify-space-between' onClick={this.handleTouchTap}>
            <span>{this.state.selectedObj?this.state.selectedObj.label : (this.props.placeholder || 'Select')}</span>
            <span className="material-icons">&#xE313;</span>
          </div>
          <Popover
            className={this.props.popoverClass}
            style={this.props.popoverStyle}
            open={this.state.openSelect}
            anchorEl={this.state.anchorEl}
            onRequestClose={this.handleRequestClose}>
            <SelectWithSearch
                ref='input'
                dataSource={fieldMap.dataSource}
                menuStyle={this.props.popoverMenuStyle}
                onItemSelect={this.onItemSelect.bind({}, fieldMap)}
              />
          </Popover>
        </div>
      );
    }

    createCustomSelectFilter(fieldMap){
        return (
            <CustomSelectFilter ref='input' label={fieldMap.label} multiple={fieldMap.multiple} items={fieldMap.dataSource}  />
        )
    }



    getValue() {
        var ref = this.refs['input'],
            fieldMap = this.props,
            valueFn = this.getValueFunctionMap[fieldMap.type],
            value = '';
        return this[valueFn].call(this, ref);
    }

    createField() {
        var fieldMap = this.props,
            reactElement,
            callbackFn;

        if (fieldMap.type) {
            callbackFn = this.getRenderFunctionMap[fieldMap.type];
            reactElement = this[callbackFn].call(this, fieldMap);
            return reactElement;
        }
        return (null);
    }

    render() {
        return (
            <div style={this.props.style} className={`form-field ${this.props.className ? this.props.className : ''}`}>
                {this.createTitleField()}
                <div className={`input-group ${this.props.element?'flex multiple':''} ${this.props.inputClassName ? this.props.inputClassName : ''}`}>
                    {this.createField()}
                    {this.props.element ? this.props.element : (null)}
                </div>
            </div>
        );
    }
};


 FormField.propTypes={
    type: React.PropTypes.string.isRequired,
    title: React.PropTypes.string,
    style: React.PropTypes.object,
    onSelect: React.PropTypes.func,
    dataSource: React.PropTypes.array,
    className: React.PropTypes.string,
    inputClassName: React.PropTypes.string,
    element: React.PropTypes.element,
    isRequired: React.PropTypes.bool
}