import * as Ariakit from '@ariakit/react';
import { IOption } from '@websolutespa/bom-core';
import { FocusEvent, useEffect, useState } from 'react';
import { useVariants } from '../../variants';
import { innerToOuterSelectValue, outerToInnerSelectValue } from '../utils/utils';
import { SelectContext, SelectContextProps } from './select.context';
import { selectVariants } from './select.variants';

type SelectValueProps = {
  value?: string | IOption | string[] | IOption[] | null;
  defaultValue?: string | IOption | string[] | IOption[] | null;
};

export type SelectProps = Omit<Ariakit.SelectProviderProps, keyof (SelectContextProps | SelectValueProps)> &
  Omit<SelectContextProps, 'onFocus' | 'onBlur'> & {
    onFocus?: (event: FocusEvent<HTMLButtonElement>) => void;
    onBlur?: (event: FocusEvent<HTMLButtonElement>) => void;
    onChange?: (value: string | IOption | string[] | IOption[] | null) => void;
  } & SelectValueProps;

export function Select({
  name,
  label,
  value: outerValue,
  defaultValue: outerDefaultValue,
  options,
  multiple,
  placeholder,
  variant = 'default',
  variants,
  onBlur,
  onFocus,
  onChange,
  children,
  ...props }: SelectProps) {

  const value = outerToInnerSelectValue(outerValue);
  const defaultValue = outerToInnerSelectValue(outerDefaultValue) || (multiple ? [] : '');
  const [innerValue, setInnerValue] = useState<string | string[] | undefined>(value || defaultValue);
  const [previousOuterValue, setPreviousOuterValue] = useState<string | string[] | undefined>(outerValue);
  // console.log('outerValue', outerValue, 'innerValue', innerValue);

  useEffect(() => {
    if (previousOuterValue !== outerValue) {
      setPreviousOuterValue(outerValue);
      setInnerValue(value);
      // console.log('useEffect.setInnerValue', value);
    }
  }, [previousOuterValue, outerValue, value]);

  const onChange_ = (value: string | string[] | undefined) => {
    if (innerValue !== value) {
      setInnerValue(value);
      // console.log('onChange_.setInnerValue', value);
      const outerValue = innerToOuterSelectValue(value, options);
      onChange && onChange(outerValue);
      // console.log('onChange_.setOuterValue', outerValue);
    }
  };

  /*
  const store = Ariakit.useSelectStore({
    // value: value,
    defaultValue: defaultValue,
    setValue: (value) => onChange_(value),
  });

  console.log('Select', value, defaultValue);
  */

  const onBlur_ = (event: FocusEvent<HTMLButtonElement>) => {
    onBlur && onBlur(event);
  };

  const onFocus_ = (event: FocusEvent<HTMLButtonElement>) => {
    onFocus && onFocus(event);
  };

  const globalVariants = useVariants('select', selectVariants);
  variants = variants || globalVariants;
  return (
    <Ariakit.SelectProvider
      value={innerValue}
      setValue={onChange_}
      {...props}
      // store={store}
    >
      <SelectContext.Provider value={{
        name,
        label,
        options,
        multiple,
        placeholder,
        variant,
        variants,
        onFocus: onFocus_,
        onBlur: onBlur_,
      }}>
        {children}
      </SelectContext.Provider>
    </Ariakit.SelectProvider>
  );
}
