import React, { useCallback, useState } from 'react';
import { AnimatePresence, motion } from 'framer-motion';
import { bem } from 'utils/bem';
import { SExpandedRow } from '../../s-components/table/s-expanded-row';
import { BodyContent, TableContent } from './constants';
import { TableTheme } from 'app/theme/table';
import { Sort } from 'utils/sort';

interface Props<BodyType extends BodyContent, SortField extends string> {
  renderExpandedRow?: (content: BodyType) => React.ReactNode;
  headerContent: TableContent<BodyType, SortField>[];
  isExpanded: boolean;
  rowData: BodyType;
  isEven?: boolean;
  theme: TableTheme;
  sort: Sort<SortField>;
  hasStickyColumns?: boolean;
  isCheckable?: boolean;
}

const classes = bem('expanded-row');

const expandAnimationProps = {
  initial: { height: 0 },
  exit: { height: 0, overflow: 'hidden' },
  animate: { height: 'unset' },
  transition: { type: 'spring', damping: 15, mass: 0.5 },
};

export const ExpandedRow = <BodyType extends BodyContent, SortField extends string>({
  renderExpandedRow,
  headerContent,
  isExpanded,
  rowData,
  isEven,
  theme,
  sort,
  hasStickyColumns,
  isCheckable,
}: Props<BodyType, SortField>) => {
  const [isOverflowed, setIsOverflowed] = useState(true);

  const onAnimationStart = useCallback(() => {
    setIsOverflowed(true);
  }, []);

  const onAnimationComplete = useCallback(() => {
    setIsOverflowed(false);
  }, []);

  return (
    <SExpandedRow tableTheme={theme} isEven={isEven}>
      {isCheckable && !hasStickyColumns && <td className={classes('empty-checkbox')} />}
      <td colSpan={headerContent.length} className={classes('empty-cell')}>
        <AnimatePresence exitBeforeEnter>
          {isExpanded && (
            <motion.div
              {...expandAnimationProps}
              onAnimationStart={onAnimationStart}
              onAnimationComplete={onAnimationComplete}
              className={classes('expanded-container', { 'is-overflowed': isOverflowed })}
            >
              {renderExpandedRow && renderExpandedRow(rowData)}
              {!renderExpandedRow && (
                <div className={classes('row-container')}>
                  {headerContent.map(item => (
                    <div
                      key={item.dataIndex}
                      className={classes(
                        'expanded-column',
                        { sorted: sort.field === item.sortField },
                        item.additionalExpandedClassName
                      )}
                    >
                      {item.renderExpanded && item.renderExpanded(rowData)}
                    </div>
                  ))}
                </div>
              )}
            </motion.div>
          )}
        </AnimatePresence>
      </td>
    </SExpandedRow>
  );
};
