import * as React from 'react';
import { useEffect, useRef, useState, useContext, Fragment, CSSProperties } from 'react';
import { Thumbnail } from '../../Thumbnail';
import { Helpers } from '../../../services/helpers';
import { StoreContext } from '../../../services/store';
import { IMedia } from '../../../types';

interface Props {
  forceColumns?: number;
}

const Wall = ({ forceColumns }: Props) => {
  const context = useContext(StoreContext);
  const containerRef = useRef<HTMLDivElement>(null);
  const defaultColumnsNumber = context.isMobile ? 2 : 3;

  // Function to calculate dynamically the number of media per row, depending on screen size
  const columnsNumber = (): number => {
    const settings = context?.data?.settings;
    const contentSize = Number(settings?.content_size) ?? undefined;
    const contentsPerRow = forceColumns || contentSize || defaultColumnsNumber;
    const minWidth = 125;

    if (forceColumns) {
      return forceColumns;
    }
    if (!context?.isMobile) {
      return contentsPerRow;
    }
    if (!containerRef.current) {
      return defaultColumnsNumber;
    }

    const calculatedColumns = Math.floor(containerRef.current.clientWidth / minWidth) || 1;
    const isWideEnough = containerRef.current.clientWidth / contentsPerRow > minWidth;
    return isWideEnough ? contentsPerRow : calculatedColumns;
  };

  const [numberOfColumns, setNumberOfColumns] = useState<number>(columnsNumber());
  // Call columnsNumber and change numberOfColumns
  // accordingly at each re-render, included screen resize
  useEffect(() => {
    setNumberOfColumns(columnsNumber());
  });
  const [medias, setMedias] = useState<IMedia[]>(context?.data?.content?.medias ?? []);
  // Update media to show if medias array actually changes
  useEffect(() => {
    setMedias(context?.data?.content?.medias);
  }, [context?.data?.content?.medias]);

  const renderRows = () => {
    const thumbStyle = { ...thumbnailStyle };
    const rStyle = { ...rowStyle };
    thumbStyle.width = `${100 / numberOfColumns}%`;
    const numberOfRow: number = Math.ceil((medias?.length ?? 0) / numberOfColumns) ?? 1;
    const rows: JSX.Element[][] = Helpers.createArray(numberOfRow).map(() => []);
    medias.forEach((media, i: number) => {
      rows[Math.floor(i / numberOfColumns)].push(
        <div className={`${context?.config.classPrefix}-item`} style={thumbStyle} key={i}>
          <Thumbnail media={media} position={i} />
        </div>,
      );
    });
    const lastRowContents = (medias?.length ?? 0) % numberOfColumns;
    let rest = -lastRowContents + numberOfColumns;
    if (!lastRowContents) {
      rest = 0;
    }
    while (rest > 0) {
      rows[rows && rows.length - 1].push(
        <div
          className={`${context?.config.classPrefix}-item`}
          style={{ ...thumbStyle }}
          key={`empty-${rest}`}
        >
          <div style={emptyThumnailStyle} />
        </div>,
      );
      rest -= 1;
    }
    return rows.map((content, i) => (
      <Fragment key={i}>
        <div className={`${context?.config.classPrefix}-row`} style={rStyle}>
          {content}
        </div>
        <br />
      </Fragment>
    ));
  };

  return (
    <div
      className={`${context?.config.classPrefix}-layout-wall`}
      style={rowContainerStyle}
      ref={containerRef}
    >
      {renderRows()}
    </div>
  );
};

const rowStyle: CSSProperties = {
  display: 'inline-block',
  marginTop: -4,
  width: '100%',
};

const rowContainerStyle: CSSProperties = {
  textAlign: 'center',
};

const emptyThumnailStyle: CSSProperties = {
  paddingBottom: '100%',
};

const thumbnailStyle: CSSProperties = {
  display: 'inline-block',
};

export default Wall;
