import React, {
  forwardRef,
  useEffect,
  useMemo,
  useRef,
  useState,
  useCallback,
} from "react";
import { cloneDeep } from "lodash";
import { LicenseManager } from "ag-grid-enterprise";
import { AgGridReact } from "ag-grid-react"; // React Data Grid Component
import "ag-grid-community/styles/ag-grid.css"; // Mandatory CSS required by the Data Grid
import "ag-grid-community/styles/ag-theme-alpine.css"; // Optional Theme applied to the Data Grid
import "./Table.styles.scss";

import TableHeader from "./tableHeader";
import AgGridHeader from "./AgGridHeader";
import TablePagination from "./tablePagination";
import {
  getMainMenuItems,
  Columns,
  updateFontSizeOnToolPanel,
} from "./tableFunctions";
import TableAdvanceSearchModal from "../Table/advanceSearchModal";
import BulkActionBar from "./actionBar";
import { ReactComponent as EmptyStateImage} from "../../assets/emptyStateImage.svg"

export const OldTable = forwardRef(
  (
    {
      defaultColDef: defColDef,
      columnDefs: colDefs,
      tableHeader = "",
      rowHeight: rowHei,
      height,
      topRightOptions,
      topLeftOptions,
      onGlobalSearchClick,
      paginationPageSizeSelector = [10, 20, 50, 100],
      defaultPageSize,
      onNumberFormatChange = () => {},
      onColumnSearchClick,
      tableActionOptions,
      bottomLeftOptions,
      cardContainer = true,
      hideRowHeightOptionMenu = false,
      onPaginationChanged = () => {},
      showDownloadButton = false,
      onDownloadButtonClick = () => {},
      nestedTable = false,
      nestedTableComponent = null,
      closeButton = false,
      handleCloseButtonClick,
      additionalButtons,
      applySort,
      onFilterChanged,
      sortModel,
      onSearchApplyClick,
      gridId,
      showHideEditableCells = false,
      handleShowHideEditableCells = () => {},
      topCenterOptions,
      bottomCenterOptions,
      onAdvanceSearchClick,
      handleInlineSearch,
      tableActions,
      customGetMainMenuItems,
      hidePaginationPageSizeSelector = false,
      onTableActionsTabClick,
      hideTableFormat = false,
      hideTableActions = false,
      handleClearSearchInline,
      aboveTableComponent: belowHeaderComponent,
      hideTableSetting = false,
      explicitlyCloseTableSetting = false,
      handleCloseInputField,
      customHeaderComponent,
      debounceTime = 1500,
      hideMarginBottom = false,
      customSystemButton,
      onContentDensityChange,
      savedViewsOptions,
      handleSaveAndApply = () => {},
      maxSavedViews = 50,
      handleSavedViewClick = () => {},
      handleEditSaveView = () => {},
      isSaveViewEnabled = false,
      isSaveViewLoading = false,
      handleDeleteViewClick = () => {},
      isDeleteViewLoading = false,
      handleSetDefaultView = () => {},
      closeTableSettingOnOutsideClick = false,
      onTableSettingClick = () => {},
      deleteViewPromptText,
      enableHeaderTextWrap = true,
      numericFormatDefault = "full_no",
      defaultFontSize = "medium",
      emptyStateText = "No data to display",
      showBulkActionBar = false,
      bulkActionBarProps = {
        actionBarLabel: "",
        enableSelectAll: true,
        totalRowCount: 0,
      },
      onSelectAllRows = () => {},
      onClearSelection = () => {},
      ...args
    },
    ref
  ) => {
    LicenseManager.setLicenseKey(
      "Using_this_{AG_Grid}_Enterprise_key_{AG-072820}_in_excess_of_the_licence_granted_is_not_permitted___Please_report_misuse_to_legal@ag-grid.com___For_help_with_changing_this_key_please_contact_info@ag-grid.com___{Impact_Analytics}_is_granted_a_{Multiple_Applications}_Developer_License_for_{1}_Front-End_JavaScript_developer___All_Front-End_JavaScript_developers_need_to_be_licensed_in_addition_to_the_ones_working_with_{AG_Grid}_Enterprise___This_key_has_not_been_granted_a_Deployment_License_Add-on___This_key_works_with_{AG_Grid}_Enterprise_versions_released_before_{31_December_2025}____[v3]_[01]_MTc2NzEzOTIwMDAwMA==acb63fc998feb69e3a3ca9ad323b2577"
    );

    const tempRef = useRef();
    const actualRef = ref || tempRef;
    const [localPageSize, setLocalPageSize] = useState(
      defaultPageSize || paginationPageSizeSelector[0]
    );
    const [girdColumns, setGridColumns] = useState([]);
    const [tableSettingOpen, setTableSettingOpen] = useState(false);

    const [rowHeight, setRowHeight] = useState(
      rowHei === "comfort" ? 52 : rowHei === "compact" ? 30 : 46
    );

    const [tableFontSize, setTableFontSize] = useState(
      defaultFontSize || "medium"
    );

    const buttonRef = useRef(null);

    useEffect(() => {
      if (defaultFontSize) setTableFontSize(defaultFontSize);
    }, [defaultFontSize]);

    const nestedTableRef = useRef(null);
    const [isAdvanceSearch, setAdvanceSearch] = useState(false);
    const [currentColumnId, setCurrentColumnId] = useState(null);
    const toggleAdvanceSearch = (colId) => {
      setAdvanceSearch((prev) => !prev);
      setCurrentColumnId(colId || null);
    };

    const defaultColDef = useMemo(() => {
      return {
        ...defColDef,
        filter: true,
        resizable: true,
      };
    }, []);

    const selectColumn = (cols) => {
      actualRef?.current.api.clearRangeSelection();
      actualRef?.current.api.addCellRange({ columns: cols });
    };

    // passing props using headerComponentParams for ag grid to manage the rendering of header component
    const AgGridHeaderWrapper = (props) => {
      const {
        selectColumn,
        onColumnSearchClick,
        applySort,
        onFilterChanged,
        sortModel,
        toggleAdvanceSearch,
        onAdvanceSearchClick,
        handleInlineSearch,
        handleClearSearchInline,
        handleCloseInputField,
        debounceTime,
        headerComponent,
        ...rest
      } = props;

      return (
        <AgGridHeader
          {...rest}
          sortModel={sortModel}
          onClick={() => selectColumn?.([rest?.column?.colId])}
          onColumnSearchClick={onColumnSearchClick}
          applySort={applySort}
          onFilterChanged={onFilterChanged}
          toggleAdvanceSearch={toggleAdvanceSearch}
          onAdvanceSearchClick={onAdvanceSearchClick}
          handleInlineSearch={handleInlineSearch}
          handleClearSearchInline={handleClearSearchInline}
          handleCloseInputField={handleCloseInputField}
          debounceTime={debounceTime}
          enableHeaderTextWrap={enableHeaderTextWrap}
        >
          {headerComponent ? headerComponent(props) : rest?.displayName}
        </AgGridHeader>
      );
    };

    // Add special attributes to columns
    const addSpecialAttributes = useCallback(
      (cols) => {
        return cols.map((child) => {
          const obj = {
            ...child,
            cellClass:
              (child.cellClass || "") +
              (child.editable ? " editable-ag-cell" : "") +
              ([
                "number",
                "int",
                "percentage",
                "dollar",
                "trend",
                "float",
              ].includes(child.type)
                ? " number-cell"
                : "") +
              (rowHeight === 46
                ? " default-cell"
                : rowHeight === 30
                ? " compact-cell"
                : " comfort-cell"),
            headerClass:
              (child.headerClass || "") +
              ([
                "number",
                "int",
                "percentage",
                "dollar",
                "trend",
                "float",
              ].includes(child.type)
                ? " number-cell"
                : ""),
            width:
              child.checkboxSelection || child.headerCheckboxSelection
                ? "40px"
                : child.width || undefined,
            headerComponentParams: {
              ...child?.headerComponentParams,
              selectColumn,
              onColumnSearchClick,
              applySort,
              onFilterChanged,
              sortModel,
              toggleAdvanceSearch,
              onAdvanceSearchClick,
              handleInlineSearch,
              handleClearSearchInline,
              handleCloseInputField,
              debounceTime,
              headerComponent: child?.headerComponent,
            },
          };

          // assigning custom header component if not already set to not cause renrender issues
          obj.headerComponent = customHeaderComponent
            ? customHeaderComponent
            : AgGridHeaderWrapper;
          if (child.children) {
            obj.children = addSpecialAttributes(child.children);
          }
          return obj;
        });
      },
      [customHeaderComponent, rowHeight]
    );

    const columnDefs = useMemo(() => addSpecialAttributes(colDefs), [colDefs]);

    useEffect(() => {
      const copyColumns =
        actualRef?.current?.api?.getColumnDefs() || columnDefs;
      function applyStyleRecursively(columns) {
        return columns?.map((column) => {
          if (column?.children && Array.isArray(column.children)) {
            // Recursive call for children
            column.children = applyStyleRecursively(column.children);
          } else {
            // Apply style to columns without children
            if (column?.field !== "Selection") {
              column.cellStyle = {
                ...column.cellStyle,
                fontSize: updateFontSizeOnToolPanel(tableFontSize),
              };
            }
          }
          return column;
        });
      }

      let cols = copyColumns;
      if (tableFontSize) {
        cols = applyStyleRecursively(copyColumns);
      }
      setGridColumns(cols);
      if (actualRef?.current?.api)
        actualRef.current.api.getModel().appliedFontSize = tableFontSize;
    }, [tableFontSize]);

    useEffect(() => {
      setGridColumns(columnDefs);
    }, [columnDefs]);

    const paginationChanged = (params) => {
      setDynmaicStyleToButtonComponent();
      onPaginationChanged(params);
    };

    const onFirstDataRendered = (params) => {
      if (params?.api) params.api.getModel().appliedFontSize = tableFontSize;
      args?.onFirstDataRendered?.(params);
      args?.gridOptions?.onFirstDataRendered?.(params); 
    };

    const setDynmaicStyleToButtonComponent = () => {
      const span1 = document.querySelector(".ag-paging-row-summary-panel");
      const span2 = document.querySelector(".ag-paging-page-summary-panel");
      if (span1 || span2) {
        let actualWidth =
          (span1?.offsetWidth || 0) + (span2?.offsetWidth || 0) + 20;
        if (buttonRef?.current) {
          buttonRef.current.style.right = `${actualWidth}px`;
          if (tableSettingOpen) {
            buttonRef.current.style.right = `${actualWidth + 375}px`;
          } else {
            buttonRef.current.style.right = `${actualWidth}px`;
          }
        }
      }
    };

    useEffect(() => {
      setDynmaicStyleToButtonComponent();
      const div = document.querySelector(".ag-root-wrapper-body");
      if (div) {
        let actualHeight = div.offsetHeight;
        let tableContainer = document.querySelector(`#${gridId || "myGrid"}`);
        if (tableSettingOpen) {
          if (actualHeight < 480) {
            if (tableContainer) {
              tableContainer.style.height = `551px`;
              if (buttonRef && buttonRef.current)
                buttonRef.current.style.bottom = `${480 - actualHeight - 37}px`;
            }
          } else {
            document.querySelector(
              ".display-table-setting"
            ).style.height = `${actualHeight}px`;
          }
        } else {
          if (tableContainer) tableContainer.style.height = `unset`;
          if (buttonRef && buttonRef.current)
            buttonRef.current.style.bottom = `13px`;
        }
      }
    }, [tableSettingOpen, cardContainer]);

    useEffect(() => {
      if (nestedTable && nestedTableRef.current) {
        setTimeout(() => {
          try {
            const rect = nestedTableRef.current.getBoundingClientRect();
            requestAnimationFrame(() => {
              window.scrollTo({
                top: rect.top,
                behavior: "smooth",
              });
            });
          } catch (error) {
            console.warn("Error during nested table scroll:", error);
          }
        }, 0);
      }
    }, [nestedTable]);

    const onSearchApplyClicks = (formValues) => {
      const rest = actualRef?.current;
      formValues.forEach((value) => {
        // Recursively find the column definition
        const findColumnDef = (cols, field) => {
          for (const col of cols) {
            if (col.children) {
              const found = findColumnDef(col.children, field);
              if (found) return found;
            }
            if (col.field === field) return col;
          }
          return null;
        };

        const columnDef = findColumnDef(colDefs, value?.column?.value);
        const type = columnDef?.type;

        const parsedValue =
          type === "number" ? parseFloat(value?.value) : value?.value;
        const currentFilterModel = rest?.sortModel
          ? rest?.sortModel
          : rest.api.getFilterModel();
        currentFilterModel[value?.column?.value] =
          parsedValue != null || parsedValue !== ""
            ? {
                type: value?.operation?.value || "contains",
                filter: parsedValue,
                filterType: type,
              }
            : undefined;

        rest.api.setFilterModel(currentFilterModel);
      });
      rest.api.onFilterChanged();
      toggleAdvanceSearch();
    };

    const updateExpandState = (params) => {
      let allExpanded = true;
      let hasGroups = false;

      params.api.forEachNode((node) => {
        if (node.group) {
          hasGroups = true;
          if (!node.expanded) {
            allExpanded = false;
          }
        }
      });

      if (hasGroups) {
        actualRef.current.api.getModel().isExpand = allExpanded;
      }
    };

    useEffect(() => {
      let newRowHeight;
      if (typeof rowHei === "number") {
        newRowHeight = rowHei;
      } else if (rowHei === "comfort") {
        newRowHeight = 52;
      } else if (rowHei === "compact") {
        newRowHeight = 30;
      } else {
        newRowHeight = 46;
      }
      setRowHeight(newRowHeight);
      if (actualRef?.current?.api) {
        setTimeout(() => {
          actualRef.current.api.resetRowHeights();
        }, 0);
      }
    }, [rowHei, actualRef]);
    
     const EmptyStateOverlay = (params) => {
          if(args.noRowsOverlayComponent){
            return args.noRowsOverlayComponent(params);
          }
          return (
            <div className="table-empty-state">
              <EmptyStateImage />
              <span>{emptyStateText}</span>
            </div>
          );
        };



    return (
      <div
        className={`ag-theme-alpine ia-basic-table-layout table-v32 ${
          enableHeaderTextWrap ? "header-wrap-enabled" : ""
        }`}
        style={{
          width: "100%",
          "--ag-grid-height": height || "500px",
        }}
      >
        <div
          className={`impact-table-main-container  ${
            cardContainer ? "card-container" : ""
          } ${tableSettingOpen ? "table-setting-open" : ""} ${
            bottomLeftOptions || bottomCenterOptions
              ? "footer-button-with-bottom-options"
              : ""
          } ${hideMarginBottom ? "hide-margin-bottom" : ""}`}
          id={gridId || "myGrid"}
        >
          <TableHeader
            actualRef={actualRef}
            colDefs={colDefs}
            Columns={Columns}
            rowHeight={rowHeight}
            setRowHeight={setRowHeight}
            tableFontSize={tableFontSize}
            setTableFontSize={setTableFontSize}
            tableHeader={tableHeader}
            topRightOptions={topRightOptions}
            topLeftOptions={topLeftOptions}
            onGlobalSearchClick={onGlobalSearchClick}
            cardContainer={cardContainer}
            onNumberFormatChange={onNumberFormatChange}
            hideRowHeightOptionMenu={hideRowHeightOptionMenu}
            showDownloadButton={showDownloadButton}
            onDownloadButtonClick={onDownloadButtonClick}
            closeButton={closeButton}
            handleCloseButtonClick={handleCloseButtonClick}
            additionalButtons={additionalButtons}
            setTableSettingOpen={setTableSettingOpen}
            showHideEditableCells={showHideEditableCells}
            handleShowHideEditableCells={handleShowHideEditableCells}
            topCenterOptions={topCenterOptions}
            tableActions={tableActions}
            onTableActionsTabClick={onTableActionsTabClick}
            hideTableFormat={hideTableFormat}
            hideTableActions={hideTableActions}
            hideTableSetting={hideTableSetting}
            explicitlyCloseTableSetting={explicitlyCloseTableSetting}
            customSystemButton={customSystemButton}
            onContentDensityChange={onContentDensityChange}
            savedViewsOptions={savedViewsOptions}
            handleSaveAndApply={handleSaveAndApply}
            maxSavedViews={maxSavedViews}
            handleSavedViewClick={handleSavedViewClick}
            handleEditSaveView={handleEditSaveView}
            isSaveViewEnabled={isSaveViewEnabled}
            isSavingViewLoading={isSaveViewLoading}
            handleDeleteViewClick={handleDeleteViewClick}
            isDeleteViewLoading={isDeleteViewLoading}
            handleSetDefaultView={handleSetDefaultView}
            closeTableSettingOnOutsideClick={closeTableSettingOnOutsideClick}
            onTableSettingClick={onTableSettingClick}
            deleteViewPromptText={deleteViewPromptText}
            numericFormatDefault={numericFormatDefault}
          />
          <BulkActionBar
            showBulkActionBar={showBulkActionBar}
            onSelectAllRows={onSelectAllRows}
            onClearSelection={onClearSelection}
            bulkActionBarProps={bulkActionBarProps}
          />
          {belowHeaderComponent && belowHeaderComponent}
          <AgGridReact
            {...args}
            ref={actualRef}
            domLayout="autoHeight"
            rowHeight={rowHeight}
            columnDefs={girdColumns}
            headerHeight={40}
            defaultColDef={defaultColDef}
            enableRangeSelection
            suppressMenuHide
            getMainMenuItems={customGetMainMenuItems || getMainMenuItems}
            paginationPageSize={localPageSize}
            onPaginationChanged={paginationChanged}
            onRowGroupOpened={updateExpandState}
            noRowsOverlayComponent={EmptyStateOverlay}
            onFirstDataRendered={onFirstDataRendered}
          />
          {(bottomLeftOptions || bottomCenterOptions || args.pagination) && (
            <div
              className={`table-footer-section ${
                !bottomLeftOptions && !bottomCenterOptions
                  ? "table-footer-section-with-only-pagination"
                  : ""
              } ${
                !args.pagination
                  ? "table-footer-section-without-pagination"
                  : ""
              }`}
              style={{
                width: hidePaginationPageSizeSelector && "60%",
              }}
              ref={buttonRef}
            >
              {bottomLeftOptions && (
                <div className="table-footer-left-section">
                  {bottomLeftOptions}
                </div>
              )}
              {bottomCenterOptions && (
                <div className="table-footer-center-section">
                  {bottomCenterOptions}
                </div>
              )}
              {!hidePaginationPageSizeSelector && args.pagination ? (
                <TablePagination
                  actualRef={actualRef}
                  localPageSize={localPageSize}
                  setLocalPageSize={setLocalPageSize}
                  paginationPageSizeSelector={
                    paginationPageSizeSelector.length > 0
                      ? paginationPageSizeSelector
                      : [10]
                  }
                  defaultPageSize={defaultPageSize}
                />
              ) : null}
            </div>
          )}
          {nestedTable && (
            <div className="nested-table-container" ref={nestedTableRef}>
              {nestedTableComponent}
            </div>
          )}
          {isAdvanceSearch && (
            <TableAdvanceSearchModal
              isAdvanceSearch={isAdvanceSearch}
              toggleAdvanceSearch={toggleAdvanceSearch}
              colDefs={colDefs}
              actualRef={actualRef}
              onSearchApplyClick={onSearchApplyClicks}
              currentColumnId={currentColumnId}
              {...args}
            />
          )}
        </div>
      </div>
    );
  }
);
