'use strict';

/** @jsx createElement */
import { Component, createElement, PropTypes } from 'rax';
import Icon from 'nuke-icon';
import Dom from 'nuke-dom';
import Input from 'nuke-normal-input';
import View from 'nuke-view';
import Text from 'nuke-text';
import Touchable from 'nuke-touchable';
import { isWeb, isWeex } from 'nuke-env';
import { connectStyle } from 'nuke-theme-provider';
import stylesProvider from '../styles';

class SearchBar extends Component {
  constructor(props) {
    super(props);
    let value = '';
    if ('defaultValue' in props) {
      value = props.defaultValue;
    } else if ('defaultValue' in props) {
      value = props.value;
    }
    this.state = {
      focus: false,
      value,
    };
    this.userInputValue = value || '';
    const events = [
      'focusHandler',
      'blurHandler',
      'changeHandler',
      'inputHandler',
      'searchHandler',
      'returnHandler',
      'textSearchHandler',
    ];
    events.forEach((m) => {
      this[m] = this[m].bind(this);
    });
  }

  //   calcRem
  componentDidMount() {
    const { centered } = this.props;
    if (!centered) return;

    Dom.getRect('parentDOM').then(
      (wrap) => {
        this.setState({
          strentchStyle: {
            width: isWeb ? `${wrap.width}px` : wrap.width, // web 端 offset 的单位是 px
          },
        });
      },
      () => {}
    );
  }
  componentWillReceiveProps(nextProps) {
    if ('value' in nextProps) {
      this.setState({
        value: nextProps.value,
      });
      this.userInputValue = nextProps.value;
    }
  }
  render() {
    const {
      value,
      disabled,
      defaultValue,
      placeholder,
      onInput,
      onChange,
      onSearch,

      inputStyle,
      style = {},
      themeStyle: styles,
      ...others
    } = this.props;
    const searchbarWrapStyle = Object.assign({}, styles.wrap, style);

    return (
      <View clsName="search-bar-wrap" style={searchbarWrapStyle} {...others}>
        <View clsName="body" ref="parentDOM" style={[styles.body, inputStyle]}>
          {this.renderPlaceholder(styles)}
          {this.renderInput()}
        </View>
        {this.renderSearchButton(styles)}
      </View>
    );
  }
  // 输入框以及placeholder
  renderInput() {
    const { maxLength, disabled, themeStyle: styles } = this.props;
    return (
      <Input
        ref={(ref) => {
          this._input = ref;
        }}
        style={styles['input-wrap']}
        type="search"
        returnKeyType="search"
        materialDesign={false}
        maxLength={maxLength}
        value={this.state.value}
        onFocus={this.focusHandler}
        onBlur={this.blurHandler}
        onReturn={this.returnHandler}
        disabled={disabled}
        inputStyle={styles['input-ele']}
        onInput={this.inputHandler}
        onChange={this.changeHandler}
      />
    );
  }
  // 模拟的 placeholder
  renderPlaceholder(styles) {
    const { placeholder, centered, placeholderColor } = this.props;
    const { focus } = this.state;
    let element;


    const textStyle = {};
    const TextAttrArr = ['color', 'fontSize', 'fontStyle', 'fontWeight'];
    TextAttrArr.forEach((item) => {
      if (styles.placeholder[item]) {
        textStyle[item] = styles.placeholder[item];
      }
    });

    if (isWeb) {
      element =
        placeholder && !this.userInputValue && !focus ? (
          <Text style={[textStyle, { color: placeholderColor }]}>
            {placeholder}
          </Text>
        ) : null;
    } else {
      element =
        placeholder && !this.userInputValue && !focus ? (
          <Text style={[textStyle, { color: placeholderColor }]}>
            {placeholder}
          </Text>
        ) : null;
    }
    const iconDOM = (
      <Icon style={[styles.icon, { color: placeholderColor }]} name="search" />
    );
    const placeholderStyle =
      centered && !focus && !this.userInputValue
        ? { ...styles['body-centered'], ...this.state.strentchStyle }
        : {};
    return (
      <View
        role="placeholder-wrap"
        ref="placeholderDOM"
        style={[styles.placeholder, placeholderStyle]}
      >
        {iconDOM}
        {element}
      </View>
    );
  }

  // 搜索按钮
  renderSearchButton(styles) {
    if (!this.props.showSearchButton) return null;

    return (
      <Touchable onPress={this.searchHandler} style={styles.button}>
        <Text onPress={this.textSearchHandler} style={styles['button-text']}>
          {this.props.locale.search}
        </Text>
      </Touchable>
    );
  }

  focusHandler(e) {
    this.setState({
      focus: true,
    });
    this.trigger('onFocus', e);
  }
  trigger(fn, ...attrs) {
    if (typeof fn === 'string') fn = this.props[fn];
    if (!(typeof fn === 'function')) return;

    return fn.apply(this, attrs);
  }
  blurHandler(e) {
    this.setState({
      focus: false,
    });
    this.trigger('onBlur', e);
  }

  inputHandler(e) {
    this.userInputValue = e.value;
    this.trigger('onInput', e);
  }

  changeHandler(value, e) {
    this.setState({
      value,
    });
    this.userInputValue = value;
    this.trigger('onChange', value, e);
  }
  returnHandler(e) {
    const value = e.value;

    this.setState({ value });
    this.searchHandler();
  }

  searchHandler(e) {
    // alert(this.userInputValue);
    this._input.wrappedInstance.blur();
    this.props.onSearch && this.props.onSearch({ value: this.userInputValue });
  }
  textSearchHandler(e) {
    if (isWeb) {
      e.stopPropagation();
    }
    this.searchHandler();
  }
}
SearchBar.propTypes = {
  onCancel: PropTypes.func,
  onChange: PropTypes.func,
  onSearch: PropTypes.func,
  value: PropTypes.string,
  defaultValue: PropTypes.string,
  locale: PropTypes.object,
  disabled: PropTypes.bool,
  showSearchButton: PropTypes.bool,
  centered: PropTypes.bool,
  placeholderColor: PropTypes.string,
  inputStyle: PropTypes.any,
  style: PropTypes.any,
  placeholder: PropTypes.string,
  onInput: PropTypes.func,
};

SearchBar.defaultProps = {
  locale: {
    search: '搜索',
  },
  onSearch: () => {},
  showSearchButton: true,
  disabled: false,
  centered: false,
  defaultValue: null,
  onCancel: () => {},
  inputStyle: {},
  onChange: () => {},
  onInput: () => {},
  placeholderColor: '#cccccc',
  placeholder: '',
  style: {},
};
SearchBar.displayName = 'SearchBar';

const StyledSearchBar = connectStyle(stylesProvider, { withRef: true })(
  SearchBar
);

export default StyledSearchBar;
