import { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import {
  Indexes,
  ItemGlobal,
  ReturnFromInteractDataRowAndGraph,
  UseInteractDataRowAndGraphProps,
} from '../interface';
import { sortListBy } from '../utils';

const useInteractDataRowAndGraph = (
  props: UseInteractDataRowAndGraphProps
): ReturnFromInteractDataRowAndGraph => {
  const {
    data,
    headers,
    orderBy,
    orderType,
    maxPerPage,
    currentPage,
    hasPagination,
    customSortProperty,
    customSortFunc,
    multipleOrderBy,
    multipleOrderType,
    customMultipleOrder,
  } = props;
  const [dataOrderedBy, setDataOrderedBy] = useState<ItemGlobal[]>([]);
  const [dataState, setDataState] = useState([...data]);

  useEffect(() => {
    if (
      !!customSortProperty &&
      !!customSortFunc &&
      orderBy === customSortProperty
    ) {
      const orderedData = customSortFunc(data, orderType, customSortProperty);

      setDataOrderedBy(orderedData);
      return;
    }

    if (
      !!multipleOrderBy &&
      !!multipleOrderType &&
      multipleOrderBy.length &&
      multipleOrderBy.length === multipleOrderType.length &&
      !!customMultipleOrder
    ) {
      const orderedData = customMultipleOrder.customOrderByFunc(
        data,
        multipleOrderBy,
        multipleOrderType
      );

      setDataOrderedBy(orderedData);
      return;
    }

    const orderedData = sortListBy(data, orderBy, orderType);
    setDataOrderedBy(orderedData);
  }, [
    data,
    headers,
    orderBy,
    orderType,
    customSortProperty,
    customSortFunc,
    multipleOrderBy,
    multipleOrderType,
    customMultipleOrder,
  ]);

  useEffect(() => {
    if (!dataOrderedBy) {
      return;
    }

    if (!hasPagination) {
      setDataState(dataOrderedBy);
      return;
    }

    const dataToSkip = maxPerPage * (currentPage - 1);

    setDataState(dataOrderedBy.slice(dataToSkip, dataToSkip + maxPerPage));
  }, [maxPerPage, currentPage, dataOrderedBy, hasPagination]);

  const closeAllOtherModals = (
    properties: Array<string>,
    dataToUpdate: Array<ItemGlobal>,
    selected?: string,
    indexes?: Indexes,
    type?: string
  ): void => {
    properties.forEach((property) => {
      if (type === 'parent') {
        dataToUpdate.forEach((item, index) => {
          if (indexes) {
            if (selected && selected !== property) {
              Object.assign(item, { [`${property}`]: false });
            }

            if (index !== indexes.index) {
              Object.assign(item, { [`${property}`]: false });
            }
          }
        });
      } else {
        dataToUpdate.forEach((item) => {
          Object.assign(item, { [`${property}`]: false });
        });
      }
    });
  };

  const openRow = (index, keepOthersOpen = false) => {
    if (keepOthersOpen) {
      const updatedDataState = dataState.map((item, indexItem) => ({
        ...item,
        opened: indexItem === index ? !item.opened : item.opened,
      }));

      setDataState(updatedDataState);

      return;
    }

    const updatedDataState = dataState.map((item, indexItem) => ({
      ...item,
      opened: indexItem === index ? !item.opened : false,
    }));

    closeAllOtherModals(['graphOpened', 'modalOpened'], updatedDataState);

    setDataState(updatedDataState);
  };

  const openModal = (index: number, selected: string) => {
    const updatedDataState = [...dataState];

    Object.assign(updatedDataState[index], {
      [`${selected}`]: !updatedDataState[index][selected],
    });

    closeAllOtherModals(
      ['graphOpened', 'modalOpened'],
      updatedDataState,
      selected,
      { index },
      'parent'
    );

    setDataState(updatedDataState);
  };

  return {
    dataState,
    openRow,
    openModal,
  };
};

useInteractDataRowAndGraph.propTypes = {
  data: PropTypes.arrayOf(
    PropTypes.shape({
      entityId: PropTypes.string,
      name: PropTypes.string,
      unit: PropTypes.string,
      stock: PropTypes.shape({
        value: PropTypes.number,
        isReal: PropTypes.bool,
      }),
      meanForecastedConsumption: PropTypes.number,
      daysBeforeBreakage: PropTypes.number,
      modalContent: PropTypes.func,
    })
  ).isRequired,
};

export default useInteractDataRowAndGraph;
