import React, { forwardRef, useCallback, useEffect, useMemo } from 'react';
import { isNumber } from 'lodash';
import { bem } from 'utils/bem';
import { BgStyle } from 'common/styles/utils';
import { SRadioButton, SRadioGroup } from './s-radio-group';
import { Icon } from '../../icon';
import { IconName } from '../../icon/types';
import { Tooltip } from '../../tooltip';

interface CommonRadioButtonProps {
  id: number;
  selectedValue?: number;
  dataSelector?: string;
  className?: string;
}

interface TextRadioButtonProps extends CommonRadioButtonProps {
  name: string;
}

const buttonClasses = bem('radio-button');

export const RadioButton = ({ id, name, selectedValue = 0, dataSelector, className }: TextRadioButtonProps) => {
  const isSelected = selectedValue === id;
  return (
    <SRadioButton isSelected={isSelected} className={className}>
      <span className={buttonClasses('radio')}>
        <input
          type="radio"
          name="radioGroup"
          data-selector={`${dataSelector}-${name.toLowerCase().split(' ')[0]}`}
          value={id}
          checked={isSelected}
          readOnly
        />
      </span>
      <span className={buttonClasses('name')}>{name}</span>
    </SRadioButton>
  );
};

interface IconRadioButtonProps extends CommonRadioButtonProps {
  icon: IconName;
}

export const IconRadioButton = forwardRef<HTMLLabelElement, IconRadioButtonProps>(
  ({ id, icon, selectedValue = 0, dataSelector, className }, ref) => {
    const isSelected = selectedValue === id;
    return (
      <SRadioButton ref={ref} className={className} isSelected={isSelected}>
        <span className={buttonClasses('radio')}>
          <input type="radio" name="radioGroup" data-selector={`${dataSelector}-${icon.toLowerCase()}`} value={id} />
        </span>
        <div className={buttonClasses('icon')}>
          <Icon name={icon} size="general" color={isSelected ? 'black' : undefined} />
        </div>
      </SRadioButton>
    );
  }
);

export interface RadioGroupOption {
  id: number;
  name?: string;
  icon?: string;
  tooltip?: string;
  className?: string;
}

interface RadioGroupProps {
  options?: RadioGroupOption[];
  onChange?(value: number): void;
  customHandler?(event: React.FormEvent<HTMLDivElement>): void;
  value?: number | { id: unknown } | null;
  defaultValue?: string | number;
  bgStyle?: BgStyle;
  dataSelector?: string;
  disabled?: boolean;
  className?: string;
}

export const RadioGroup = ({
  options = [],
  onChange = () => {},
  customHandler,
  defaultValue,
  value,
  bgStyle = 'white',
  dataSelector,
  disabled,
  className,
}: RadioGroupProps) => {
  const validatedValue = useMemo(() => {
    if (isNumber(value)) return value;
    if (value?.id && isNumber(value.id)) return value.id;
    return -1;
  }, [value]);

  const onChangeHandler = useCallback(
    (event: React.FormEvent<HTMLDivElement>) => {
      if (customHandler) {
        customHandler(event);
      } else {
        onChange(+(event.target as any).value);
      }
    },
    [customHandler, onChange]
  );

  useEffect(() => {
    const isSelectedInOptions = options.some(option => option.id === validatedValue);
    if (defaultValue && !isSelectedInOptions) {
      onChange(+defaultValue);
    }
  }, [options, validatedValue, onChange, defaultValue]);

  const renderRadioButton = useCallback(
    option => {
      return option.icon ? (
        <IconRadioButton key={option.id} {...option} selectedValue={validatedValue} dataSelector={dataSelector} />
      ) : option.name ? (
        <RadioButton key={option.id} {...option} selectedValue={validatedValue} dataSelector={dataSelector} />
      ) : null;
    },
    [validatedValue, dataSelector]
  );

  return (
    <SRadioGroup
      disabled={disabled}
      data-selector={dataSelector}
      onChange={onChangeHandler}
      bgStyle={bgStyle}
      className={className}
    >
      {options.map(option => {
        return option.tooltip ? (
          <Tooltip content={option.tooltip}>{renderRadioButton(option)}</Tooltip>
        ) : (
          renderRadioButton(option)
        );
      })}
    </SRadioGroup>
  );
};
