
import React, { ReactNode, useEffect, useRef, useState } from 'react';
import HoverInfo from '../../../components/hoverInfo/hoverInfo';
import cx from 'classnames';
import { Alignment, ColumnHeader, DataTableRow } from './dataTable.types';
import * as Cells from './dataTableCells';
import AutoDataTableService, { columnWidth } from './dataTable.helper';
import * as Text from 'app/shared/components/text/text';

interface StandardContainerProps {
  children: ReactNode;
  extraClass?: string;
}

const ScrollableContainer = ({ children, extraClass }: StandardContainerProps) => {
  const [ isScrollIndicatorVisible, setScrollIndicatorVisibility ] = useState(false);
  const scrollContainerRef = useRef<HTMLDivElement>(null);
  const [ isScrollIndicatorIconVisible, setScrollIndicatorIconVisibility ] = useState(true);

  const subContainerClassName = 'c-data-table-container__responsive-size--xl';
  const containerClassName = cx('c-data-table-container',
    'c-data-table-container--scrollable',
    'c-data-table-container__scroll-indicator--padded', extraClass
  );

  useEffect(() => {
    if (scrollContainerRef.current?.scrollWidth !== scrollContainerRef.current?.clientWidth) {
      setScrollIndicatorVisibility(true);
    }
  }, [ scrollContainerRef ]);
  
  const handleScroll = (event) => {
    if (event.target.scrollLeft === 0 && !isScrollIndicatorIconVisible) {
      setScrollIndicatorIconVisibility(true);
    } else if (isScrollIndicatorIconVisible) {
      setScrollIndicatorIconVisibility(false);
    }

    if (event.target.scrollWidth - event.target.clientWidth === event.target.scrollLeft && isScrollIndicatorVisible) {
      setScrollIndicatorVisibility(false);
    } else if (!isScrollIndicatorVisible) {
      setScrollIndicatorVisibility(true);
    }
  };

  return <div className="u-position--relative">
    <div ref={scrollContainerRef} className={containerClassName} onScroll={handleScroll}>
      <div className={subContainerClassName}>
        {children}
      </div>
    </div>
    <div className="c-data-table-container__scroll-indicator">
      {isScrollIndicatorVisible && <div
        className='c-data-table-container__scroll-indicator-icon-container'
      >
        {isScrollIndicatorIconVisible && <div className='c-data-table-container__scroll-indicator-icon'>
          <i className='icon-flat-arrow-right' />
        </div>}
      </div>}
    </div>
  </div>;
};

const HeaderRow = ({ children }: StandardContainerProps) => (
  <div className="c-data-table-header-row">
    {children}
  </div>
);

interface HeaderRowColumnProps {
  text: string;
  subtext?: string;
  width?: number;
  description?: string;
  align?: Alignment;
  onClick?: () => void;
  isColumnSorted: boolean;
  defaultColumnWidth: number;
  isAscendingOrder: boolean;
}

const HeaderRowColumn = ({
  text,
  subtext,
  isColumnSorted,
  defaultColumnWidth,
  isAscendingOrder,
  width,
  description,
  align = 'left',
  onClick,
}: HeaderRowColumnProps) => {
  return (
    <div className='c-data-table-row-label' style={columnWidth(width ?? defaultColumnWidth)}>
      <span 
        className={cx(
          'c-data-table-row-label__value u-position--relative', 
          { 'u-align-self-end u-align--right': align === 'right' },
          { 'c-data-table-row-label--sortable': Boolean(onClick) })} 
        onClick={onClick}
      >
        {text}
        {Boolean(onClick) && <i className={cx('c-data-table-row-label__sort-indicator', {
          'c-data-table-row-label__sort-indicator--visible': isColumnSorted,
          'icon-flat-arrow-up' : isAscendingOrder,
          'icon-flat-arrow-down' : !isAscendingOrder,
        })} />}
      </span>
      { subtext && 
        <Text.Menu extraClass={cx('u-margin--none', { 'u-align-self-end u-align--right': align === 'right' })}>
          <span className='u-color--dark-grey'>{subtext}</span>
        </Text.Menu> 
      }
      { description &&
          <HoverInfo position="left" extraClass="u-align-self-end u-margin-top--auto o-gutter-top--small" icon="icon-info-straight">
            {description}
          </HoverInfo>
      }
    </div>
  );
};

const DataRow = <T, >({ children, onClick, item, clickable = false, extraClass }: DataTableRow<T>) => {
  return (
    <div
      className={cx('c-data-table-data-row', { 'c-data-table-data-row--clickable': clickable }, extraClass)}
      onClick={() => onClick ? onClick(item!) : null}>
      {children}
    </div>
  );
};

interface ColumnsHeaderProps {
  headers: ColumnHeader[];
}

const ColumnsHeader = ({ headers }: ColumnsHeaderProps) => (
  <div className="c-data-table-columns-header o-layout o-layout--space-between o-gutter-left o-gutter-right">
    {
      headers.map((item, index) => (
        <div key={index} className="c-data-table-columns-header__item" style={AutoDataTableService.columnWidth(item.width)}>
          {item.text}
        </div>
      ))
    }
  </div>
);


export {
  ScrollableContainer,
  HeaderRow,
  HeaderRowColumn,
  DataRow,
  Cells,
  ColumnsHeader,
};
