import React from 'react';
import { Dropdown as BDropdown } from 'react-bootstrap';
import FormCheck from 'react-bootstrap/esm/FormCheck';
import FormCheckInput from 'react-bootstrap/esm/FormCheckInput';
import FormCheckLabel from 'react-bootstrap/esm/FormCheckLabel';

// Helper function to convert array to object with values as keys
const _keyBy = (arr: string[]) => {
  return arr.reduce((acc, val) => {
    acc[val] = val;
    return acc;
  }, {} as { [key: string]: string });
};

interface DropdownsCheckProps {
  data: Array<{
    id: string,
    name: string,
    href?: string,
    disabled?: boolean
  }>,
  groups?: {[key: string]: string[]},
  value?: string[],
  defaultText?: string,
  onChange?: (value: string[], e: any) => void,
  maxHeight?: number | string,
  disabled?: boolean,
  variant?: string,
  toggleValue?: string,
  multiple?: boolean,
}

const DropdownChecks = ({ data=[], groups, defaultText="Select...", multiple=true, value=[], toggleValue='', onChange=()=>{}, maxHeight=300, disabled=false, variant, ...props } : DropdownsCheckProps) => {
  // Memoize the lookup object to prevent unnecessary recalculations
  const objectValue = React.useMemo(() => _keyBy(value), [value]);

  const handleOnClick = (id: string) => (e: any) => {
    const newValue = { ...objectValue };
    
    if (!multiple) {
      // For single select, clear all and set only the clicked item
      Object.keys(newValue).forEach(key => delete newValue[key]);
      newValue[id] = id;
    } else {
      // For multiple select, toggle the clicked item
      if (newValue[id]) {
        delete newValue[id];
      } else {
        newValue[id] = id;
      }
    }
    
    onChange(Object.values(newValue), e);
  }

  const selectedItem = data.find((item: any) => item.id === value);
  const title = selectedItem ? selectedItem.name : '';

  return (
    <BDropdown {...props} >
      <BDropdown.Toggle disabled={disabled} variant={variant} value={toggleValue}>
        {title || defaultText}
      </BDropdown.Toggle>
      <BDropdown.Menu style={{ overflowY: 'auto', maxHeight }}>
        {groups ?
          Object.keys(groups).map((key: string) => (
            <ul key={key} className="list-group list-group-flush">
              <li key={`group-${key}`} className="list-group-item">
                {key}
              </li>
              {
                data.filter((value: any) => groups[key].includes(value.id)).map((item: any) => (
                  <li key={item.id} className="list-group-item">
                    <FormCheck
                      id={item.id}
                      inline={false}
                      {...props}>
                      <FormCheckInput
                        type="checkbox"
                        id={item.id}
                        className="me-2"
                        checked={!!objectValue[item.id]}
                        onChange={handleOnClick(item.id)}
                        disabled={item.disabled}
                      />
                      <FormCheckLabel
                        htmlFor={item.id}
                        className="stretched-link"
                      >{item.name}
                      </FormCheckLabel>
                    </FormCheck>
                  </li>
                ))
              }
            </ul>
          ))
        :
          <ul className="list-group list-group-flush">
            {data.map(item => (
              <li key={item.id} className="list-group-item">
                <FormCheck
                  id={item.id}
                  inline={false}
                  {...props}>
                  <FormCheckInput
                    type="checkbox"
                    id={item.id}
                    className="me-2"
                    checked={!!objectValue[item.id]}
                    onChange={handleOnClick(item.id)}
                    disabled={item.disabled}
                  />
                  <FormCheckLabel
                    htmlFor={item.id}
                    className="stretched-link"
                  >{item.name}
                  </FormCheckLabel>
                </FormCheck>
              </li>
            ))
          }
          </ul>
        }
      </BDropdown.Menu>
    </BDropdown>
  );
};

export default DropdownChecks;
export {DropdownChecks, DropdownsCheckProps}