import React, { useEffect, useId, useMemo, useState } from 'react';
import { AsyncPaginate } from 'react-select-async-paginate';
import axios from 'axios'

const buildQueryString = (itemRef, queryParams) => {
  const params = new URLSearchParams();

  if (itemRef === 'roles') {
    params.set('businessOnly', 'true');
  }

  if (typeof queryParams === 'string') {
    const extraParams = new URLSearchParams(queryParams);
    extraParams.forEach((value, key) => params.set(key, value));
    return params.toString();
  }

  if (queryParams && typeof queryParams === 'object') {
    Object.entries(queryParams).forEach(([key, value]) => {
      if (value === undefined || value === null || value === '') {
        return;
      }

      params.set(key, String(value));
    });
  }

  return params.toString();
};

export const SelectField = ({ options, field, form, itemRef, showField, disabled, queryParams }) => {
  const [value, setValue] = useState(null)
  const PAGE_SIZE = 100;
  const extraQueryString = useMemo(() => buildQueryString(itemRef, queryParams), [itemRef, queryParams]);

  useEffect(() => {
    if (field?.value?.id) {
      setValue({ value: field.value.id, label: field.value[showField || 'name'] || field.value.label });
      form.setFieldValue(field.name, field.value.id);
    } else if (options?.id) {
      const label = options[showField || 'name'] || options.label || options.firstName || options.email || options.request_code || options.reservation_code || options.summary;
      setValue({ value: options.id, label });
      if (field?.value !== options.id) {
        form.setFieldValue(field.name, options.id);
      }
    } else if (!field?.value) {
      setValue(null);
    }
  }, [options, field?.value, form, field?.name, showField])

  const mapResponseToValuesAndLabels = (data) => ({
    value: data.id,
    label: data.label,
  })

  const handleChange = (option) => {
    form.setFieldValue(field.name, option?.value || null)
    setValue(option)
  }

  async function callApi(inputValue: string, loadedOptions: any[]) {
    const params = new URLSearchParams(extraQueryString);
    params.set('limit', String(PAGE_SIZE));
    params.set('offset', String(loadedOptions.length));
    if (inputValue) {
      params.set('query', inputValue);
    }

    const path = `/${itemRef}/autocomplete?${params.toString()}`;
    const { data } = await axios(path);
    return {
      options: data.map(mapResponseToValuesAndLabels),
      hasMore: data.length === PAGE_SIZE,
    }
  }

  return (
      <AsyncPaginate
          classNames={{
            control: () => 'px-1 py-2',
          }}
          classNamePrefix='react-select'
          instanceId={useId()}
          value={value}
          debounceTimeout={1000}
          loadOptions={callApi}
          onChange={handleChange}
          defaultOptions
          isDisabled={disabled}
          isClearable
      />
  )
}
