/* eslint-disable */
import React from "react";
import { PureInput } from "./PureInput";
import { SingleValueSelect } from "./SingleValueSelect";
import { MultipleValueSelect } from "./MultipleValueSelect";
import { Loading } from "./Loading";
import { Empty } from "./Empty";
import { DropdownBox } from "../../dropdown";
import {
  AttributeTypeOptions,
  AttributeValue,
  Value,
} from "../AttributeSelect";

export interface ValueSelectProps {
  /**
   * 值选择组件类型，用于选择不同组件
   */
  type: AttributeValue["type"];

  /**
   * 值选择组件可选值的集合
   */
  values?: AttributeValue["values"];

  /**
   * 当前输入值
   */
  inputValue?: string;

  /**
   * 自定义渲染
   */
  render?: AttributeValue["render"];

  onChange?: (value: Value[]) => void;
  onSelect?: (value: Value[]) => void;
  onCancel?: () => void;
  offset: number;
  maxHeight: number;
}

export class ValueSelect extends React.Component<ValueSelectProps, any> {
  mount = false;
  operationalKeyDownListener = (_: string) => {};

  state = {
    values: this.props.values,
  };

  componentDidMount() {
    this.mount = true;
    const propsValues = this.props.values;
    if (typeof propsValues === "function") {
      const res = propsValues();
      // Promise
      if (res && "then" in res) {
        res.then(values => {
          this.mount && this.setState({ values });
        });
      } else {
        this.mount && this.setState({ values: res });
      }
    }
  }

  componentWillUnmount() {
    this.mount = false;
  }

  handleKeyDown = (keyCode: number): boolean => {
    if (this["select"] && this["select"].handleKeyDown) {
      return this["select"].handleKeyDown(keyCode);
    }
    return true;
  };

  handleKeyDownForRenderMode = (operationalKey: string) => {
    if (this.props.render) {
      this.operationalKeyDownListener(operationalKey);
    }
    return true;
  };

  // handleKeyUp = (keyCode: number): boolean => {
  //   if (this['select'] && this['select'].handleKeyUp) {
  //     return this['select'].handleKeyUp(keyCode);
  //   }
  //   return true;
  // }

  render() {
    const { values } = this.state;
    const {
      type,
      inputValue,
      onChange,
      onSelect,
      onCancel,
      offset,
      maxHeight,
      render,
    } = this.props;

    const props = {
      values,
      inputValue,
      onChange,
      onSelect,
      onCancel,
      offset,
      maxHeight,
    };

    if (render) {
      return (
        <DropdownBox
          style={{ marginLeft: offset }}
          onClick={e => e.stopPropagation()}
        >
          {render({
            onOperationalKeyDown: listener => {
              this.operationalKeyDownListener = listener;
            },
            inputValue,
            onSelect,
            onCancel,
          })}
        </DropdownBox>
      );
    }

    let typeOptions: AttributeTypeOptions;

    if (Array.isArray(type)) {
      typeOptions = type;
    } else {
      typeOptions = [type, {}] as AttributeTypeOptions;
    }

    if (typeOptions[0] === "input") {
      return <PureInput ref={select => (this["select"] = select)} {...props} />;
    }

    if (typeOptions[0] === "single") {
      const componentOptions = typeOptions[1];
      if (!Array.isArray(values)) {
        return <Loading offset={offset} />;
      }
      if (!values.length) {
        return (
          <Empty {...componentOptions} offset={offset} onCancel={onCancel} />
        );
      }
      return (
        <SingleValueSelect
          {...props}
          {...componentOptions}
          ref={select => (this["select"] = select)}
          values={values}
        />
      );
    }

    if (typeOptions[0] === "multiple") {
      const componentOptions = typeOptions[1];
      if (!Array.isArray(values)) {
        return <Loading offset={offset} />;
      }
      if (!values.length) {
        return (
          <Empty {...componentOptions} offset={offset} onCancel={onCancel} />
        );
      }
      return (
        <MultipleValueSelect
          {...props}
          {...componentOptions}
          ref={select => (this["select"] = select)}
          values={values}
        />
      );
    }
    return null;
  }
}
