import clsx from 'clsx';
import React, { PropsWithChildren } from 'react';
import { noop } from '../../../../helpers/utils';
import { IconName, Icons } from '../../../Icons';
import classes from './ScrollColumn.scss';

export interface ScrollColumnProps<T> {
  /** Array of options to  select from */
  items: T[];

  /** Currently selected item */
  selectedItem: T;

  /** Custom render function for label */
  render?: (item: T) => string;

  /** Callback triggered when an item is selected */
  onSelected?: (item: T) => void;

  /** Height of individual item */
  itemHeight?: number;

  /** Number of items to display when expanded */
  displayItemCount?: number;

  /** Show or hide options */
  isActive?: boolean;

  /** Optional subtitle to display when options are hidden */
  inActiveTitle?: string;
}

export const ScrollColumn = <T,>({
  items,
  selectedItem,
  onSelected = noop,
  itemHeight = 35,
  displayItemCount = 5,
  render,
  isActive = false,
  inActiveTitle,
}: PropsWithChildren<ScrollColumnProps<T>>): JSX.Element => {
  const columnHeight = itemHeight * displayItemCount + displayItemCount - 1;
  const selectedIndex = items.indexOf(selectedItem);
  const scrollerTranslate =
    columnHeight / 2 - itemHeight / 2 - selectedIndex * (itemHeight + 1);

  const containerStyles: React.CSSProperties = {
    height: `${columnHeight}px`,
  };

  const scrollerStyles: React.CSSProperties = {
    transform: `translate(0, ${scrollerTranslate}px)`,
  };

  const selectPrevious = () => {
    onSelected(items[selectedIndex - 1]);
  };
  const selectNext = () => {
    onSelected(items[selectedIndex + 1]);
  };

  return (
    <div className={classes.container}>
      <button
        className={clsx(classes.button, !isActive && classes.hidden)}
        onClick={(e) => {
          e.preventDefault();
          selectPrevious();
        }}
      >
        <Icons icon={IconName.ChevronUp} className={classes.icon} />
      </button>
      <div className={classes['scroll-container']} style={containerStyles}>
        {isActive ? (
          <div
            className={classes.scroller}
            style={scrollerStyles}
            onWheel={(e) => {
              if (e.deltaY > 0) {
                selectNext();
              } else {
                selectPrevious();
              }
            }}
          >
            {items.map((item, key) => {
              return (
                <button
                  key={key}
                  className={clsx(
                    classes.item,
                    selectedItem === item && classes.selected,
                    isActive && classes.active,
                  )}
                  style={{ height: `${itemHeight}px` }}
                  onClick={(e) => {
                    e.preventDefault();
                    onSelected(item);
                  }}
                >
                  {render ? render(item) : item}
                </button>
              );
            })}
          </div>
        ) : (
          <div
            style={{
              display: 'grid',
              gridGap: '1px',
            }}
          >
            <div
              style={{
                gridRowStart: 1,
                gridRowEnd: Math.floor(displayItemCount / 2) - 1,
                height: `${itemHeight}px`,
              }}
            ></div>
            <div
              className={classes['inactive-title']}
              style={{ height: `${itemHeight}px` }}
            >
              {inActiveTitle}
            </div>
            <div
              className={clsx(classes.item, classes.selected)}
              style={{ height: `${itemHeight}px` }}
              onClick={() => onSelected(selectedItem)}
            >
              {render ? render(selectedItem) : selectedItem}
            </div>
          </div>
        )}
      </div>
      <button
        className={clsx(classes.button, !isActive && classes.hidden)}
        onClick={(e) => {
          e.preventDefault();
          selectNext();
        }}
      >
        <Icons icon={IconName.ChevronDown} className={classes.icon} />
      </button>
    </div>
  );
};
