/** @jsxRuntime classic */
/** @jsx jsx */

import { SerializedStyles, useTheme, css, jsx } from '@emotion/react';
import React, { useState, useRef, useEffect } from 'react';

import { Popup } from '../Popup';
import { StyledSelect } from './style';
import { BnArrowDown, BnArrowUp } from '../../icons';
import { SelectOptions } from '../Options';
import { capitalize } from '../../functions';
import { Tooltip } from '../Tooltip';
import { getIcon } from '../../icons';
import { InputContainer } from '../Input/style';
import cx from 'classnames';
import { ErrorMessage } from '../ErrorMessage';
import { BnIcon } from '..';
import { Icons } from '../../types/theme';

export interface IOption {
  value: string | number;
  label: string;
  icon?: Icons;
}

export interface ISelect {
  options: IOption[];
  placeholder?: string;
  value?: string;
  onSelecte?: (val: string | string[] | number[]) => void;
  isMultiple?: boolean;
  sizer?: 'M' | 'S';
  label?: string;
  disabled?: boolean;
  info?: string;
  error?: string;
  helper?: string;
  helperContent?: string;
  clear?: () => void;
  noLabel?: boolean;
  hideError?: boolean;
  onChange?: (v: unknown) => void;
  css?: SerializedStyles;
}

export const Select = ({
  options,
  onSelecte = (val) => {},
  value = '',
  placeholder = '',
  sizer = 'S',
  label = '',
  noLabel = false,
  disabled = false,
  isMultiple = false,
  info = '',
  helper = '',
  hideError = false,
  error = '',
  helperContent = '',
  clear,
  ...rest
}: ISelect & React.SelectHTMLAttributes<HTMLSelectElement>) => {
  const [isOpen, setOpen] = useState<boolean>(false);
  const [visited, setVisited] = useState<boolean>(false);
  const [toEnter, setToEnter] = useState<boolean>(false);
  const colors = useTheme();
  const ref = useRef<HTMLDivElement>(null);

  const style = rest.style;

  const chosen = options
    .filter((option) => option.value === value)
    .map((option) => option.label);

  let multipleChosen;
  if (isMultiple) {
    try {
      multipleChosen = options
        .filter((option) => value.includes(option.value as string))
        .map((option) => option.label);
    } catch {
      (err: any) => {
        console.log(err);
      };
    }
  }

  const onChange = (val: string) => {
    if (isMultiple) {
      if (value && value.includes(val)) {
        onSelecte(((value as unknown) as string[]).filter((v) => v !== val));
      } else {
        //@ts-ignore
        onSelecte([...value, val]);
      }
    } else {
      onSelecte(val);
      setOpen(false);
      if (ref.current) {
        ref.current.focus();
      }
    }
  };

  useEffect(() => {
    if (toEnter) {
      if (!isOpen) {
        setVisited(true);
      }
    }
    setToEnter(true);
  }, [isOpen]);

  return (
    <InputContainer
      className={cx(
        {
          M: sizer === 'M',
          S: sizer === 'S',
        },
        rest.className
      )}
      style={style}
      theme={{ ...colors }}
    >
      {(label || noLabel) && (
        <div className="label">
          <div>
            {capitalize(label)}
            {rest.required && !noLabel && ' *'}
          </div>
          {info && <Tooltip content={info}>{getIcon('info', 'l')}</Tooltip>}
        </div>
      )}
      <div className="select-container">
        <Popup
          fullWidth
          disableAutoTrigger
          body={
            disabled ? undefined : (
              <SelectOptions
                value={value}
                options={options}
                onSelect={onChange}
                isMultiple={isMultiple}
              />
            )
          }
          onOpenChange={setOpen}
          padding={'0'}
          borderRadius={0}
          trigger={isOpen}
        >
          <StyledSelect
            className={cx({
              placeholder: !value,
              disabled: disabled,
            })}
            theme={{ ...colors }}
            tabIndex={0}
            ref={ref}
            onClick={() => {
              if (ref.current === document.activeElement) {
                setOpen(!isOpen);
              }

              // console.log(ref.current === document.activeElement);
            }}
            onFocus={(e) => {
              setOpen(!isOpen);
            }}
          >
            <div className={cx('value', { error: error && visited })}>
              {value
                ? isMultiple
                  ? multipleChosen?.join(', ')
                  : capitalize(chosen[0])
                : placeholder}
            </div>
            <div className="button">
              {isOpen ? <BnArrowUp /> : <BnArrowDown />}
            </div>
          </StyledSelect>
        </Popup>
        {clear && !rest.required && (
          <div className="remove" onClick={clear}>
            <BnIcon icon={Icons.remove} />
          </div>
        )}
      </div>
      {!hideError && (
        <div style={{ minHeight: '15px' }}>
          {visited && <ErrorMessage error={error} />}
        </div>
      )}
      {helper && (
        <div className="helper">
          {helperContent && (
            <Tooltip content={helperContent}>{getIcon('info', 'r')}</Tooltip>
          )}
          <div>{capitalize(helper)}</div>
        </div>
      )}
    </InputContainer>
  );
};
