import React, {PureComponent} from 'react';
// import style from "styled-components";
import {Select} from 'antd';
import * as api from "../../services/api";

import {moreSelcetData} from '../../common/dataCache';

const {
  setDataMoreSelcet,
  getDataMoreSelcet,
  subscribe,
  setWritingState,
  ifWrited
} = moreSelcetData();

const Option = Select.Option;

/**
 *
 * @desc    antd Select 组件自带的 api 都可以直接使用
 *          demo   LaborBasic.js
 * @param   {String} type  设置数据字典需要类型
 * @param   {Boolean|Object} addOption   设置为 true 的时候，默认增加"全部选项，设置为Array<obj>，
 *          下拉列表默认追加指定 option
 * @param   {func} onChange(data,type)  , {String} data 下拉选择参数；{type} 数据字典类型
 * @return
 */
class DictSelect extends PureComponent {
  constructor(props, context) {
    super(props, context);
    this.state = {
      dataSource: [],
      type: this.props.type,
      addOption: false,
      optionConfig: {
        keyName: "codeValue",
        keyValue: "label",
      }
    }

  }

  /******************************生命周期******************************/

  componentDidMount = () => {
    const type = this.props.type;
    if (type && type.trim() !== "") {
      this.setState({type});
      this.publicCommonDictGetDictByCodeTypes(type);
    } else {
      console.log("请设置数据字典 codeTypes");
    }

    const optionConfig = this.props.optionConfig || null;
    if (optionConfig && Object.keys(optionConfig).length != 0) {
      this.setState({optionConfig});
    }

  }

  /******************************ajax请求******************************/

  publicCommonDictGetDictByCodeTypes = (type) => {

    const dataSource = getDataMoreSelcet(type);

    if (dataSource) {
      this.initDataSouce(dataSource, type);
      return;
    }

    if (ifWrited(type)) {
      subscribe({type, func: this.initDataSouce});
      return;
    }

    setWritingState(type);

    api.publicCommonDictGetDictByCodeTypes({codeTypes: type}).then(({data}) => {
      setDataMoreSelcet(data);
      this.initDataSouce(data, type);
    }, (err) => {
      console.error(err);
    });

  }

  initDataSouce = (data, type) => {
    if (!data) {
      return;
    }
    let dataSource = data[type];

    //判断是否需要新增字典之外的 选项
    let props = this.props || {};
    const {optionConfig} = this.state;

    if ("addOption" in props) {
      // addOption   设置为 true 的时候，默认增加"全部选项
      if (Object.prototype.toString.call(props.addOption) == "[object Boolean]") {
        if (props.addOption) {
          dataSource.push({
            [optionConfig.keyName]: "",
            [optionConfig.keyValue]: "全部"
          });
        }
      }
      //如果 addOption 为 object 配置对象，则默认添加
      if (Object.prototype.toString.call(props.addOption) == "[object Object]") {
        dataSource = [
          ...dataSource, ...props.addOption
        ]
      }
    }
    this.setState({dataSource});
  }


  /******************************相关事件******************************/
  onChange = (value) => {
    let props = this.props || {};
    if ("onChange" in props) {
      this.props.onChange(value, this.state.type);
    }
  }

  /******************************render******************************/

  render() {
    const {optionConfig, dataSource} = this.state;
    let props = {...this.props, ...{onChange: this.onChange}};

    return (
      <Select {...props} >
        {dataSource.length != 0 && dataSource.map((val) => (
          <Option
            value={val[optionConfig.keyName] + ""}
            key={val[optionConfig.keyName]}>{val[optionConfig.keyValue]}</Option>
        ))}
      </Select>
    );
  }
}


const HOC = (Component) => {
  return class WrapComponent extends React.Component {
    render() {
      const style = {
        style: {
          width: "214px"
        }
      };
      return (
        <Component {...style} {...this.props}/>
      )
    }
  }
}
const PMSelect = HOC(DictSelect);

PMSelect.allSelcet = (codeTypes) => {
  if (!codeTypes.includes(",")) {
    throw new Error('Expected the arguments includes ,');
  }
  codeTypes.split(',').map(val=> setWritingState(val));

  api.publicCommonDictGetDictByCodeTypes({codeTypes}).then(({data}) => {
    setDataMoreSelcet(data);
  }, (err) => {
    console.error(err);
  });
}


export default PMSelect;


