import React, { FunctionComponent, ReactNode } from "react";
import Select, { components } from "react-select";
import CreatableSelect from "react-select/creatable";

import "./styles.scss";

export interface IOption {
  label: string;
  value: any;
}

interface IDropdownProps {
  options?: IOption[];
  label?: string;
  defaultValue?: IOption;
  disabled?: boolean;
  isClearable?: boolean;
  isCreatable?: boolean;
  isRequired?: boolean;
  placeholder?: string;
  error?: string;
  value?: IOption;
  onChange?: (option: IOption) => void;
  optionRender?: (value: string) => ReactNode;
  selectedOptionRender?: (value: string) => ReactNode;
  isValidNewOption?: (inputValue: string, value: any, options: any) => boolean;
}

export const Dropdown: FunctionComponent<IDropdownProps> = (props) => {
  const {
    label,
    placeholder = "Please select",
    defaultValue,
    isClearable = true,
    onChange,
    value,
    error,
    disabled = false,
    options = [],
    optionRender,
    selectedOptionRender,
    isCreatable = false,
    isRequired = false,
    isValidNewOption,
  } = props;

  const dropdownComponents: any = {};

  if (optionRender) {
    dropdownComponents.Option = (innerProps: any) => (
      <components.Option {...innerProps}>{optionRender(innerProps.data.value)}</components.Option>
    );
  }

  if (selectedOptionRender) {
    dropdownComponents.SingleValue = (innerProps: any) => selectedOptionRender(innerProps.data.value);
  }

  return (
    <div className="c-dropdown">
      {label && (
        <label className={`c-dropdown__label ${isRequired && "c-dropdown__label--required"}`}>{label}</label>
      )}
      {React.createElement(isCreatable ? CreatableSelect : Select, {
        components: dropdownComponents,
        options,
        isClearable,
        defaultValue,
        classNamePrefix: "c-dropdown",
        className: "c-dropdown-container",
        isDisabled: disabled,
        value: value || (defaultValue ? value : ""),
        placeholder,
        onChange: (value: any) => onChange?.(value || undefined),
        isValidNewOption,
      })}
      {error && <span className="c-text-input__validation">{error}</span>}
    </div>
  );
};
