/**
 * Copyright 2024 Phenix Real Time Solutions, Inc. Confidential and Proprietary. All Rights Reserved.
 */
import React, {useEffect, useLayoutEffect, useState} from 'react';

import {DirectionType} from 'interfaces/tableProps';
import {compare} from 'utility/sort';
import {Error} from 'components/error-renderer/style';
import {Table as TableContainer} from './style';
import TableHeader from './table-header';
import TableBody from './table-body';
import {ITable, DataRowType, ColumnsType} from './props';

const defaultHideColumnWidth = 100;
const TableComponent = ({columns, data, sortColumn, sortDirection, sort, errorMessage}: ITable): React.JSX.Element => {
  const getHeadersBasedOnWidth = (columns: ColumnsType) => {
    const newHeaders: ColumnsType = {};

    Object.keys(columns).forEach(key => {
      const hideColumnAt = columns[key]?.hideColumnAt || defaultHideColumnWidth;
      const isHidden: boolean = columns[key]?.isHidden || window.innerWidth <= hideColumnAt;

      newHeaders[key] = {
        ...columns[key],
        isHidden
      };
    });

    return newHeaders;
  };

  const [sortHeaderColumn, setSortHeaderColumn] = useState<string | null>(sortColumn || null);
  const [headers, setHeaders] = useState<ColumnsType>(getHeadersBasedOnWidth(columns));
  const [modifiedData, setModifiedData] = useState<DataRowType[]>(data);

  useEffect(() => {
    if (sortColumn && sortDirection) {
      const newHeaders: ColumnsType = {...headers};

      if (headers[sortColumn]?.textCell) {
        newHeaders[sortColumn] = {
          ...newHeaders[sortColumn],
          textCell: {
            ...newHeaders[sortColumn].textCell,
            direction: sortDirection,
            propName: newHeaders[sortColumn].textCell?.propName || sortColumn
          }
        };
      }

      setHeaders(newHeaders);
    }
  }, [sortColumn, sortDirection]);

  useEffect(() => {
    setModifiedData(data);
  }, [data]);

  useEffect(() => {
    setHeaders(columns);
  }, [columns]);

  useLayoutEffect(() => {
    const updateComponentBasedOnWidth = () => {
      setHeaders(getHeadersBasedOnWidth(columns));
    };

    window.addEventListener('resize', updateComponentBasedOnWidth);

    return () => window.removeEventListener('resize', updateComponentBasedOnWidth);
  });

  const sortAction = (propName: string) => {
    if (headers[propName]) {
      const newHeaders = {...headers};
      const currentDirection = newHeaders[propName].textCell.direction;
      const newDirection = currentDirection === DirectionType.Asc ? DirectionType.Desc : DirectionType.Asc;

      newHeaders[propName].textCell.direction = newDirection;

      if (sort) {
        sort({
          sortColumn: propName,
          sortDirection: newDirection
        });
      } else {
        const newData = modifiedData.sort((a, b) => compare(a, b, newDirection, propName));

        setModifiedData(newData);
      }

      setHeaders(newHeaders);
      setSortHeaderColumn(propName);
    }
  };

  return !errorMessage ? (
    <TableContainer className="testId-table">
      <TableHeader columns={headers} sortHeaderColumn={sortHeaderColumn} sortAction={sortAction} />
      <TableBody columns={headers} data={modifiedData} />
    </TableContainer>
  ) : (
    <Error>{errorMessage || 'Error'}</Error>
  );
};

export default TableComponent;
