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 } = props;
  const [dataState, setDataState] = useState([...data]);

  useEffect(() => {
    const orderedData = sortListBy(data, headers, orderBy, orderType);
    setDataState(orderedData);
  }, [data, headers, orderBy, orderType]);

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

            if (parentIndex !== indexes.parentIndex) {
              Object.assign(item.parentItem.items, { [`${property}`]: false });
            }
          }

          if (item.childItems) {
            item.childItems.forEach((childItem) => {
              return Object.assign(childItem.items, { [`${property}`]: false });
            });
          }
        });
      } else if (type === 'child') {
        dataToUpdate.forEach((item, index) => {
          Object.assign(item.parentItem.items, { [`${property}`]: false });

          if (item.childItems) {
            item.childItems.forEach((childItem, childIndex) => {
              if (indexes) {
                if (indexes.parentIndex !== index) {
                  Object.assign(childItem.items, { [`${property}`]: false });
                }

                if (indexes.parentIndex === index) {
                  if (selected && selected !== property) {
                    Object.assign(childItem.items, { [`${property}`]: false });
                  }

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

          if (item.childItems) {
            item.childItems.forEach((childItem) => {
              return Object.assign(childItem.items, { [`${property}`]: false });
            });
          }
        });
      }
    });
  };

  const openRow = (index) => {
    const updatedDataState = [...dataState];

    if (updatedDataState[index].parentItem.items.isExpandable) {
      Object.assign(updatedDataState[index].parentItem.items, {
        opened: !updatedDataState[index].parentItem.items.opened,
      });
    }

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

    setDataState(updatedDataState);
  };

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

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

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

    setDataState(updatedDataState);
  };

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

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

    closeAllOtherModals(
      ['graphOpened', 'modalOpened'],
      updatedDataState,
      selected,
      { parentIndex: index, childIndex },
      'child'
    );

    setDataState(updatedDataState);
  };

  useEffect(() => {
    if (dataState.length) {
      return;
    }
    if (data.length) {
      setDataState([...data]);
    }
  }, [dataState, data]);

  return {
    dataState,
    openRow,
    openParentModal,
    openChildModal,
  };
};

useInteractDataRowAndGraph.propTypes = {
  data: PropTypes.arrayOf(
    PropTypes.shape({
      parentItem: PropTypes.shape({
        items: PropTypes.arrayOf(
          PropTypes.shape({
            propertyKey: PropTypes.string.isRequired,
            value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
            setting: PropTypes.bool,
          })
        ),
        chart: PropTypes.arrayOf(
          PropTypes.shape({
            x: PropTypes.string,
            y: PropTypes.number,
          })
        ),
      }),
      childItems: PropTypes.arrayOf(
        PropTypes.shape({
          items: PropTypes.arrayOf(
            PropTypes.shape({
              propertyKey: PropTypes.string.isRequired,
              value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
              setting: PropTypes.bool,
            })
          ),
          chart: PropTypes.arrayOf(
            PropTypes.shape({
              x: PropTypes.string.isRequired,
              y: PropTypes.number.isRequired,
            })
          ),
        })
      ),
    })
  ).isRequired,
};

export default useInteractDataRowAndGraph;
