import { Collapse, TableBody, TableCell, TableRow } from "@mui/material";
import _ from "lodash";
import React, { Fragment, useState } from "react";
import { Waypoint } from "react-waypoint";
import { Checkbox, IconButton } from "../..";

export const Body = ({
    data,
    loading,
    messageNoData,
    columns,
    disableItemSelection,
    filterDataPaginate,
    grouping,
    groupingValueToCompare,
    groupingArea,
    selectedItems,
    keyColumn,
    setSelectedItems,
    onSelectedItems,
    onCollapse,
    infiniteScroll,
    nextToken,
    onChangePage,
    setPage,
    page,
    total,
    rowsPerPage,
    onChangeDisplayData,
    filterData,
    moreRowsAvailable,
    noMoreItemsMessage,
    onRowClick
}: any) => {

  const [expanded, setExpanded] = useState<any>([]);
  let currentGroup: any;



  return (
    <TableBody>
      {data?.length === 0 && !loading && messageNoData && (
        <TableRow>
          <TableCell
            colSpan={
              columns.length && !disableItemSelection
                ? columns.length + 1
                : columns.length
            }
          >
            {messageNoData}
          </TableCell>
        </TableRow>
      )}
      {filterDataPaginate.map((row: any, index: any) => {
        if (row.type === 'group') {
          return (
            <TableRow 
              key={`group-${index}`}
              sx={{
                backgroundColor: '#f5f5f5',
                '& td': {
                  padding: '8px 16px',
                }
              }}
            >
              <TableCell
                colSpan={columns.filter((x: any) => x.disabled || x.show).length + (!disableItemSelection ? 1 : 0) + (onCollapse ? 1 : 0)}
              >
                {row.content}
              </TableCell>
            </TableRow>
          );
        }

        let printGroup = false;
        if (grouping) {
          let newGroup = row[groupingValueToCompare];
          printGroup = !_.isEqual(newGroup, currentGroup);
          currentGroup = printGroup ? newGroup : currentGroup;
        }
        return (
          <Fragment key={index}>
            {printGroup && (
              <>
                <TableRow>
                  <TableCell
                    colSpan={columns.filter((x: any) => x.disabled || x.show).length + 1}
                    style={{ padding: 0 }}
                  >
                    {groupingArea
                      ? groupingArea(currentGroup, row)
                      : currentGroup.toString()}
                  </TableCell>
                </TableRow>
              </>
            )}

            <TableRow
              onClick={(e: React.MouseEvent<HTMLTableRowElement>) => {
                if (e.isPropagationStopped()) {
                  return;
                }
                
                const target = e.target as HTMLElement;
                const clickedElement = target;
                
                if (
                  clickedElement.tagName === 'INPUT' && clickedElement.getAttribute('type') === 'checkbox' ||
                  clickedElement.closest('input[type="checkbox"]') ||
                  (clickedElement.tagName === 'BUTTON' && clickedElement.closest('button')) ||
                  clickedElement.closest('[role="menu"]') ||
                  clickedElement.closest('.MuiMenu-root') ||
                  clickedElement.closest('[aria-expanded="true"]')
                ) {
                  return;
                }
                
                if (onRowClick && row.type !== 'group') {
                  onRowClick(row);
                }
              }}
              sx={{ 
                cursor: onRowClick ? 'pointer' : 'default',
                '&:hover': onRowClick ? { backgroundColor: 'rgba(0, 0, 0, 0.04)' } : {}
              }}
            >
              {!disableItemSelection && (
                <TableCell padding="checkbox" onClick={(e) => e.stopPropagation()}>
                  <Checkbox
                    checked={
                      selectedItems.findIndex(
                        (x: any) =>
                          (keyColumn && x[keyColumn] == row[keyColumn]) ||
                          x == row
                      ) > -1
                    }
                    onChange={() => {
                      let newSelectedItems: any = [...selectedItems];
                      let index = newSelectedItems.findIndex(
                        (x: any) =>
                          (keyColumn && x[keyColumn] == row[keyColumn]) ||
                          x == row
                      );
                      if (index > -1) newSelectedItems.splice(index, 1);
                      else newSelectedItems.push(row);

                      setSelectedItems(newSelectedItems);
                      onSelectedItems && onSelectedItems(newSelectedItems);
                    }}
                  />
                </TableCell>
              )}

              {onCollapse && (
                <TableCell onClick={(e) => e.stopPropagation()}>
                  {row?.children > 0 && (
                    <IconButton
                      icon={
                        expanded.includes(row[keyColumn])
                          ? "arrow_drop_down"
                          : "arrow_right"
                      }
                      onClick={() => {
                        if (expanded.includes(row[keyColumn])) {
                          setExpanded([
                            ...expanded.filter(
                              (e: any) => e !== row[keyColumn]
                            ),
                          ]);
                        } else {
                          setExpanded([...expanded, ...[row[keyColumn]]]);
                        }
                      }}
                    />
                  )}
                </TableCell>
              )}

              {columns
                .filter((x: any) => x.disabled || x.show)
                .map((col: any, index: any) => {
                  return (
                    <TableCell 
                      key={index}
                      onClick={(e: React.MouseEvent<HTMLTableCellElement>) => {
                        const clickedElement = e.target as HTMLElement;

                        const isButton = clickedElement.tagName === 'BUTTON' || clickedElement.closest('button');
                        const isMenuOpen = clickedElement.closest('[role="menu"]') || clickedElement.closest('.MuiMenu-root');
                        const isMenuItem = clickedElement.closest('[role="menuitem"]');

                        if ((isButton && clickedElement.tagName === 'BUTTON') || isMenuOpen || isMenuItem) {
                          e.stopPropagation();
                        }
                      }}
                    >
                      {col.render ? col.render(row) : row[col.key]?.toString()}
                    </TableCell>
                  );
                })}
            </TableRow>

            {onCollapse && (
              <TableRow>
                <TableCell colSpan={columns.length + 1} style={{ padding: 0 }}>
                  <Collapse
                    in={expanded.includes(row[keyColumn])}
                    timeout="auto"
                    unmountOnExit
                  >
                    {onCollapse(row)}
                  </Collapse>
                </TableCell>
              </TableRow>
            )}
          </Fragment>
        );
      })}

      {infiniteScroll && (
        <TableRow>
          <TableCell
            style={{ textAlign: "center" }}
            colSpan={columns.filter((x: any) => x.disabled || x.show).length + 1}
          >
            <Waypoint
              onEnter={() => {
                if (nextToken) {
                  if (onChangePage) onChangePage();
                } else if (nextToken === undefined && total) {
                  let newPage = page + 1;
                  if (filterDataPaginate.length < total) {
                    setPage(newPage);
                    if (onChangePage) onChangePage(newPage, rowsPerPage);
                    if (onChangeDisplayData) onChangeDisplayData(filterData);
                  }
                }
              }}
            />

            {!moreRowsAvailable && !loading && (
              <div className="gtc-rc-no-more-items">
                {noMoreItemsMessage || "There are no more items"}
              </div>
            )}
          </TableCell>
        </TableRow>
      )}
    </TableBody>
  );
};
