import React from 'react';
import { Select } from 'antd';
import querystring from 'querystring';
// import * as oMapper from 'object-mapper';
import { fetchJSON } from './../../utils/request';
import { observer } from 'mobx-react';
import { merge, objectMapper } from './../../utils/commons';

const { Option } = Select;

let timeout;
let currentValue;

function curl(opts, callback) {
  if (timeout) {
    clearTimeout(timeout);
    timeout = null;
  }
  currentValue = opts.value;

  function fake() {
    // console.log(currentValue, opts.value);
    if (currentValue === opts.value && opts.value === '空') {
      const _p = [{ 'key': '0', 'label': '空' }];
      return callback(_p);
    }
    const param = merge({ code: 'utf-8', q: opts.value }, opts.param);
    // const str = new URLSearchParams({
    //   code: 'utf-8',
    //   q: opts.value,
    // }).toString();

    fetchJSON(`${opts.url}`, param)
      .then(d => {
        if (currentValue === opts.value) {
          const result = objectMapper(d.result, opts.map) || [];
          callback(result);
        }
      });
  }

  timeout = setTimeout(fake, 300);
}

/**
 * 异步请求的下拉菜单, 可搜索
 * @property {array} defaultOptions 默认选项 [{key: '', label: '' }]
 * @property {string} url
 * @property {object} map 异步结果的字段转换定义
 * @property {boolean} autoGet 首次默认请求
 * @property {string} resultkey 结果的根字段
 */
class SearchInput extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      data: this.props.defaultOptions || [],
      value: undefined,
      autoData: this.props.defaultOptions || [],
    };
  }

  componentDidMount() {
    if (this.props.autoGet === true) {
      const { map, resultkey, param } = this.props;
      const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {});
      curl({ value: '', url: this.props.url || '', map: mapKey, resultkey, param }, (data) =>
        this.setState({ data, autoData: data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
      );
    }
  }

  componentDidUpdate(prevProps) {
    if (this.props.value !== prevProps.value) {
      this.setState({ value: undefined });
    }
  }

  handleClear = () => {
    this.setState({ data: this.state.autoData });
  };

  handleSearch = value => {
    if ( ! this.props.url && this.props.defaultOptions?.length) {
      const f = this.props.defaultOptions.filter(r => String(r.label).indexOf(value) !== -1);
      this.setState({ data: f || [] });
      return false;
    }
    const { map, resultkey, param } = this.props;
    const mapKey = Object.keys(map).reduce((r, v) => ({ ...r, [v]: { key: map[v] } }), {});
    if (value) {
      curl({ value, url: this.props.url || '', map: mapKey, resultkey, param }, (data) =>
        this.setState({ data }, () => (typeof this.props.onSearchAfter === 'function' ? this.props.onSearchAfter(data, this.state.value) : ''))
      );
    } else {
      this.setState({ data: this.state.autoData || [] });
    }
  };

  handleChange = (value, option) => {
    console.log('invoke denpendencies change', value);
    this.setState({ value }, () => this.props.onChange(value, option));
  };

  render() {
    const options = this.state.data.map(d => <Option key={d.key} extradata={d.options}>{d.label}</Option>);
    const { onSearchAfter, defaultOptions, autoGet, ...props } = this.props;
    return (
      <Select
        {...props}
        style={this.props.style || { width: '100%' }}
        showSearch
        labelInValue
        value={this.state.value || this.props.value}
        placeholder={this.props.placeholder}
        defaultActiveFirstOption={false}
        showArrow={false}
        filterOption={false}
        onSearch={this.handleSearch}
        onChange={this.handleChange}
        notFoundContent={null}
        allowClear={true}
        onClear={this.handleClear}
      >
        {options}
      </Select>
    );
  }
}
export default observer(SearchInput);
