import React, {
  useRef,
  useState,
  useEffect,
  useCallback,
  Fragment,
} from "react";
import SearchIcon from "@mui/icons-material/Search";
import { Input } from "../Input";
import CloseIcon from "@mui/icons-material/Close";
import TuneIcon from "@mui/icons-material/Tune";
import { debounce } from "../../utils/debounce";
import { Badge } from "@mui/material";
import { Tooltip } from "../Tooltip";
import TableSortIcon from "../../assets/tableSortIcon.svg";
import TableSortAscIcon from "../../assets/Up.svg";
import TableSortDescIcon from "../../assets/Down.svg";
import { DatePicker } from "../DatePicker";
import moment from "moment";
function AgGridHeader({
  children,
  sortModel,
  handleInlineSearch,
  handleClearSearchInline,
  handleCloseInputField,
  debounceTime,
  enableHeaderTextWrap = true,
  ...rest
}) {
  const menuRef = useRef();
  const textRef = useRef();
  const [showInputField, setShowInputField] = useState(false);
  const [searchText, setSearchText] = useState("");
  const [menuVisible, setMenuvisible] = useState(false);
  const [columnWidth, setColumnWidth] = useState({});
  const [currentSort, setCurrentSort] = useState(rest?.columnApi?.getColumnState?.().find(model => model.colId === rest.column.colId)?.sort ?? null);
  const [hasActiveSearch, setHasActiveSearch] = useState(false);
  const [showDatePicker, setShowDatePicker] = useState(false);
  const [selectedDate, setSelectedDate] = useState(null);
  const [isInputFocused, setIsInputFocused] = useState(false);
  const originalSuppressHeaderKeyboardEventRef = useRef(
    rest?.column?.colDef?.suppressHeaderKeyboardEvent
  );
  const [isOverflowText, setIsOverflowText] = useState(false);
  const headerTextRef = useRef(null);
  const [containerHeight, setContainerHeight] = useState(0);
  const containerRef = useRef(null);
  const onFilterChanged = useCallback(() => {
    const newFilterModel = rest?.api?.getFilterModel();
    if (newFilterModel) {
      const columnFilter = newFilterModel[rest?.column?.colId];
      let filterValue;
      // Handle different filter types
      if (rest?.column?.colDef?.filter === "agDateColumnFilter") {
        // For date columns, use dateFrom
        const dateFrom = columnFilter?.dateFrom;
        if (dateFrom) {
          // Extract only the date part (YYYY-MM-DD) from the datetime string
          filterValue = moment(dateFrom);
          setSelectedDate(filterValue);
        }
      } else {
        // For other columns, use filter
        filterValue = columnFilter?.filter;
        setSearchText(filterValue);
      }
      setHasActiveSearch(!!filterValue);
    }
  }, [rest?.api, rest?.column?.colId]);

  useEffect(() => {
    // Load initial filter state when grid loads
    const filterModel = rest.api.getFilterModel();
    if (filterModel[rest.column?.colId]) {
      const columnFilter = filterModel[rest?.column?.colId];
      let filterValue;
      // Handle different filter types
      if (rest?.column?.colDef?.filter === "agDateColumnFilter") {
        // For date columns, use dateFrom
        const dateFrom = columnFilter?.dateFrom;
        if (dateFrom) {
          // Extract only the date part (YYYY-MM-DD) from the datetime string
          filterValue = moment(dateFrom);
          setSelectedDate(filterValue);
        }
      } else {
        // For other columns, use filter
        filterValue = columnFilter?.filter;
        setSearchText(filterValue);
      }
      setHasActiveSearch(!!filterValue);
    } else {
      setSearchText("");
      setHasActiveSearch(false);
    }
    rest.api.addEventListener("filterChanged", onFilterChanged);
    return () => {
      rest.api.removeEventListener("filterChanged", onFilterChanged);
    };
  }, [rest.api, rest.column?.colId, onFilterChanged]);

  const handleSearchChange = (value) => {
    if (handleInlineSearch) {
      handleInlineSearch?.(value);
      return;
    }
    let inputValue =
      rest?.column?.colDef?.filter === "agNumberColumnFilter"
        ? parseFloat(value)
        : value;

    // Wrap all grid operations in setTimeout to prevent concurrent operations
    setTimeout(() => {
      try {
        let inputValue;
        let filterType = "contains";

        if (rest?.column?.colDef?.filter === "agDateColumnFilter") {
          filterType = "equals"; // Use equals for date filtering
          inputValue = value ? value.format("YYYY-MM-DD") : null;
        } else if (rest?.column?.colDef?.filter === "agNumberColumnFilter") {
          inputValue = isNaN(parseFloat(value)) ? null : parseFloat(value);
          filterType = "equals";
        } else {
          inputValue = value;
        }

        const currentFilterModel = rest?.sortModel
          ? rest?.sortModel
          : rest.api.getFilterModel();

        currentFilterModel[rest.column.colId] =
          inputValue != null && inputValue.toString().trim() !== ""
            ? {
                type: filterType,
                filter: inputValue,
                ...(rest?.column?.colDef?.filter === "agDateColumnFilter" && {
                  filterType: "date",
                  dateFrom: inputValue,
                }),
              }
            : undefined; // Remove the filter if the input is empty

        // Set filter model and trigger filter changed event in the same timeout
        rest.api.setFilterModel(currentFilterModel);

        // First handle grid's internal filter change
        Promise.resolve()
          .then(() => {
            rest.api.onFilterChanged();
          })
          .catch((error) => {
            console.warn("Error during grid filter operation:", error);
          })
          .finally(() => {
            // After grid has processed its internal changes, call external callback
            if (rest.onFilterChanged) {
              try {
                rest.onFilterChanged(rest);
              } catch (error) {
                console.warn("Error during external filter callback:", error);
              }
            }
          });
      } catch (error) {
        console.warn("Error during grid filter operation:", error);
      }
    }, 0);
  };

  const debouncedHandleSearchChange = useCallback(
    debounce((value) => {
      handleSearchChange(value);
    }, debounceTime),
    [
      debounceTime,
      rest?.api,
      rest?.column?.colId,
      rest?.column?.colDef?.filter,
      rest?.onFilterChanged,
    ]
  );

  const handleSearch = (e) => {
    e.stopPropagation();
    if (rest?.column?.colDef?.filter === "agDateColumnFilter") {
      setShowDatePicker((prev) => !prev);
    } else {
      setShowInputField((prev) => !prev);
    }
    setColumnWidth((prev) => ({
      ...prev,
      [rest?.column?.colId]: rest?.column?.actualWidth,
    }));
  };

  const onCloseIconClick = (colId) => {
    setSearchText("");
    setHasActiveSearch(false);
    // Wrap destroyFilter in setTimeout to prevent concurrent operations
    setTimeout(() => {
      try {
        rest.api.destroyFilter(colId);
      } catch (error) {
        console.warn("Error during filter destruction:", error);
      }
    }, 0);
  };

  const handleClickOutside = (event) => {
    setMenuvisible(false);
  };

  useEffect(() => {
    document.addEventListener("click", handleClickOutside);

    return () => {
      document.removeEventListener("click", handleClickOutside);
    };
  }, [menuVisible]);

  const onHeaderClick = () => {
    if (rest.applySort) {
      rest.applySort(rest.column.colId);
      return;
    }
    if (rest?.column?.colDef?.sortable) {
      // Wrap column state operations in setTimeout
      setTimeout(() => {
        try {
          const currentSortModel = rest?.columnApi?.getColumnState();
          const currentSort = currentSortModel.find(
            (model) => model.colId === rest.column.colId
          );
          const newSort = currentSort?.sort === "asc" ? "desc" : "asc";
          setCurrentSort(newSort);
          rest?.columnApi?.applyColumnState({
            state: [{ colId: rest.column.colId, sort: newSort }],
            defaultState: { sort: null },
          });
        } catch (error) {
          console.warn("Error during column sort operation:", error);
        }
      }, 0);
    }
  };

  const onColumnMoved = (params) => {
    if (params?.column?.colId && (showInputField || showDatePicker)) {
      setColumnWidth((prev) => ({
        ...prev,
        [params.column.colId]: params.column.actualWidth,
      }));
      // Store width in column state for cell renderers to access
      setTimeout(() => {
        try {
          rest?.columnApi?.applyColumnState({
            state: [
              {
                colId: params.column.colId,
                width: params.column.actualWidth,
              },
            ],
            defaultState: { width: null },
          });
        } catch (error) {
          console.warn("Error during column resize operation:", error);
        }
      }, 0);
    }
  };

  useEffect(() => {
    if (rest) {
      rest?.api?.addEventListener("columnResized", onColumnMoved);
    }
    return () => {
      rest?.api?.removeEventListener("columnResized", onColumnMoved);
    };
  }, [rest]);

  useEffect(() => {
    const colDef = rest?.column?.colDef;
    if (!colDef) return;

    if (isInputFocused) {
      if (originalSuppressHeaderKeyboardEventRef.current === undefined) {
        originalSuppressHeaderKeyboardEventRef.current =
          colDef.suppressHeaderKeyboardEvent;
      }
      colDef.suppressHeaderKeyboardEvent = () => true;
    } else {
      colDef.suppressHeaderKeyboardEvent =
        originalSuppressHeaderKeyboardEventRef.current;
    }

    return () => {
      if (colDef) {
        colDef.suppressHeaderKeyboardEvent =
          originalSuppressHeaderKeyboardEventRef.current;
      }
    };
  }, [isInputFocused, rest?.column?.colId]);

  useEffect(() => {
    if (containerRef.current) {
      setContainerHeight(containerRef.current?.clientHeight);
    }
  }, []);

  return (
    <div
      className={`custom-ag-header-container ${
        rest?.column?.colDef?.checkboxSelection ? "checkbox-selection" : ""
      }`}
      onClick={() => rest.onClick()}
      ref={containerRef}
    >
      {showDatePicker ? (
        <div
          className={`ia-search-input-field ${
            (columnWidth[rest?.column?.colId] ?? rest?.column?.actualWidth) <
            200
              ? "ia-search-input-narrow"
              : ""
          }`}
        >
          <DatePicker
            selectedDate={selectedDate}
            setSelectedDate={setSelectedDate}
            placeholder="Select Date"
            withPortal
            fullWidth
            isAgGridCellRenderer
            displayFormat={rest?.column?.colDef?.displayFormat || "MM-DD-YYYY"}
            showMonthYearSelect
            minDate={new Date("2000-01-01")}
            maxDate={new Date("2100-12-31")}
            onTertiaryButtonClick={() => {
              handleSearchChange(null);
              setShowDatePicker(false);
            }}
            onPrimaryButtonClick={() => {
              handleSearchChange(selectedDate);
              setShowDatePicker(false);
            }}
            onSecondaryButtonClick={() => {
              setShowDatePicker(false);
            }}
            customIcon={
              rest?.column?.colDef?.advanceSearchEnabled && (
                <TuneIcon
                  className="ia-search-input-field-custom-icon"
                  onClick={() => {
                    if (rest.onAdvanceSearchClick) {
                      rest.onAdvanceSearchClick(rest.column);
                      return;
                    }
                    rest.toggleAdvanceSearch(rest.column.colId);
                  }}
                />
              )
            }
          />
          <CloseIcon
            className="ia-search-input-field-close-icon"
            onClick={() => {
              handleCloseInputField?.();
              setShowDatePicker(false);
            }}
            style={{ cursor: "pointer" }}
          />
        </div>
      ) : showInputField ? (
        <div
          className={`ia-search-input-field ${
            (columnWidth[rest?.column?.colId] ?? rest?.column?.actualWidth) <
            200
              ? "ia-search-input-narrow"
              : ""
          }`}
        >
          <Input
            rightIcon={
              <Fragment>
                {searchText?.toString()?.length > 0 &&
                  (columnWidth[rest?.column?.colId] ??
                    rest?.column?.actualWidth) >= 200 && (
                    <CloseIcon
                      onClick={() => {
                        if (handleClearSearchInline) {
                          handleClearSearchInline(rest);
                        }
                        onCloseIconClick(rest.column.colId);
                      }}
                    />
                  )}
                {rest?.column?.colDef?.advanceSearchEnabled && (
                  <TuneIcon
                    onClick={() => {
                      if (rest.onAdvanceSearchClick) {
                        rest.onAdvanceSearchClick(rest.column);
                        return;
                      }
                      rest.toggleAdvanceSearch(rest.column.colId);
                    }}
                  />
                )}
              </Fragment>
            }
            value={searchText}
            placeholder="Search"
            onChange={(e) => {
              setSearchText(e.target.value);
              setHasActiveSearch(!!e.target.value);
              debouncedHandleSearchChange(e.target.value);
            }}
            onFocus={() => setIsInputFocused(true)}
            onBlur={() => setIsInputFocused(false)}
          />
          <CloseIcon
            className="ia-search-input-field-close-icon"
            onClick={() => {
              handleCloseInputField?.();
              setShowInputField(false);
            }}
            style={{ cursor: "pointer" }}
          />
        </div>
      ) : (
        <React.Fragment>
          <div
            className={`ag-header-cell-text ${
              rest?.column?.colDef?.sortable ? "sortable" : ""
            } ${enableHeaderTextWrap ? "header-wrap-enabled" : ""}`}
          >
            {rest?.column?.colDef?.field === "Selection" ||
            rest?.column?.colDef?.checkboxSelection ? (
              children
            ) : (
              <div
                className="header-text-content"
                ref={headerTextRef}
                onMouseEnter={() => {
                  setIsOverflowText(
                    headerTextRef.current?.scrollWidth >
                      headerTextRef.current?.clientWidth ||
                      headerTextRef?.current?.scrollHeight >
                        headerTextRef?.current?.clientHeight + 1
                  );
                }}
                style={{ WebkitLineClamp: containerHeight > 40 ? 4 : 2 }}
              >
                <Tooltip
                  variant="tertiary"
                  title={
                    isOverflowText && children !== "Selection" ? children : ""
                  }
                  orientation="bottom"
                >
                  {children}
                </Tooltip>

              </div>
            )}
            {rest?.column?.colDef?.sortable && (
              <img
                src={
                  currentSort === "asc"
                    ? TableSortAscIcon
                    : currentSort === "desc"
                    ? TableSortDescIcon
                    : TableSortIcon
                }
                alt="TableSortIcon"
                className="ia-table-sort-icon"
                onClick={onHeaderClick}
              />
            )}
          </div>
          <div
            className={`ia-icon-div ${
              hasActiveSearch ? "has-active-search" : ""
            } ${menuVisible ? "menu-visible" : ""}`}
          >
            {rest?.column?.colDef?.customHeaderIcons &&
              rest?.column?.colDef?.customHeaderIcons.map((icon) => {
                return icon;
              })}
            {rest?.column?.colDef?.isSearchable &&
              (hasActiveSearch || !showInputField) && (
                <Badge variant="dot" invisible={!hasActiveSearch}>
                  <SearchIcon
                    fontSize="small"
                    onClick={
                      rest.onColumnSearchClick
                        ? () => {
                            rest.onColumnSearchClick(rest);
                            setShowInputField(true);
                            if (
                              rest?.column?.colDef?.filter ===
                              "agDateColumnFilter"
                            ) {
                              setShowDatePicker(true);
                            } else if (
                              rest?.column?.colDef?.thirdOptionAsDropdown
                            ) {
                              // Open the dropdown when the search icon is clicked
                              setTimeout(() => {
                                setIsDropdownOpen(true);
                              }, 0);
                            }
                          }
                        : handleSearch
                    }
                    style={{
                      color: "#60697D",
                      cursor: "pointer",
                      backgroundColor: hasActiveSearch && "#ECEEFD",
                      display:
                        menuVisible && !hasActiveSearch ? "none" : "block",
                    }}
                  />
                </Badge>
              )}
            {!rest?.column?.colDef?.suppressMenu && (
              <div className="custom-ag-header-icons">
                <button
                  ref={menuRef}
                  className={`custom-ag-menu-icon-button`}
                  onClick={(e) => {
                    e.stopPropagation();
                    rest.showColumnMenu(menuRef.current);
                    setMenuvisible(true);
                  }}
                />
              </div>
            )}
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

export default AgGridHeader;
