const handleFilterApiClick = () => {
    console.log(`handleFilterApiClick triggered for activeTab: ${activeTab}, fetchFromApi: ${fetchFromApi}`);
  
    const logGroups = (label, groups) => {
      const totalRulesCount = groups.reduce((acc, group) => acc + group.length, 0);
      console.log(
        `${label} (${groups.length} groups, ${totalRulesCount} total rules):`,
        groups
      );
    };
  
    if (fetchFromApi) {
      // Data is from API mode
      console.log(`Using recent API data for tab: ${activeTab}`);
      if (activeTab === "ticketcreate") {
        const duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
        logGroups("Duplicate groups for Ticket Creation", duplicateGroups);
        setTicketCreationRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
      } else if (activeTab === "ticketupdate") {
        const duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
        logGroups("Duplicate groups for Ticket Update", duplicateGroups);
        setTicketUpdateRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
      } else if (activeTab === "hourly") {
        const duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
        logGroups("Duplicate groups for Hourly", duplicateGroups);
        setHourlyRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
      }
    } else {
      // Data is from entity (local DB) mode
      console.log(`Using entity data for tab: ${activeTab}`);
      // if (activeTab === "ticketcreate") {
      //   const duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
      //   logGroups("Duplicate groups for Ticket Creation (Entity)", duplicateGroups);
      //   setTicketCreationRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
      // } else if (activeTab === "ticketupdate") {
      //   const duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
      //   logGroups("Duplicate groups for Ticket Update (Entity)", duplicateGroups);
      //   setTicketUpdateRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
      // } else if (activeTab === "hourly") {
      //   const duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
      //   logGroups("Duplicate groups for Hourly (Entity)", duplicateGroups);
      //   setHourlyRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
      // }
    }
  };



on this runing, why it runs three times 

for ex. im in ticketupdate and choose duplicate_rules, it runs three times and then filtters. why 

fix in this code 

import React, { useState, useEffect, useRef, useMemo } from "react";
import {
  FwTabs,
  FwTab,
  FwTabPanel,
  FwSpinner,
  ToastController,
  FwToast,
  FwPagination,
  FwModalTitle,
  FwModalContent,
  FwToggle,
  FwButton,
  FwIcon,
  FwListOptions,
  FwPopover,
  FwModal,
} from "@freshworks/crayons/react";
import {
  getTicketCreationRules,
  getTicketUpdationRules,
  getHourlyRules,
  getAgents,
  pagination,
} from "../common";


export function findAndGroupExactDuplicates(rules = []) {
  // ✅ Filter only active rules first
  const activeRules = rules.filter(r => r.active === true || r.active === "true");

  const normalizeText = (text) =>
    typeof text === "string"
      ? text
          .replace(/&nbsp;/gi, "")
          .replace(/\u200B|\uFEFF/g, "")
          .replace(/\./g, "")
          .replace(/\s+/g, "")
          .toLowerCase()
      : "";

  const stripHTML4 = (htmlString) => {
    if (typeof window === "undefined") return "";
    if (typeof htmlString !== "string") htmlString = String(htmlString || "");

    const div = document.createElement("div");
    div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");

    const walkAndClean = (node) => {
      let result = "";
      for (const child of node.childNodes) {
        if (child.nodeType === Node.TEXT_NODE) {
          result += " " + child.nodeValue;
        } else if (child.nodeType === Node.ELEMENT_NODE) {
          result += " " + walkAndClean(child);
        }
      }
      return result;
    };

    return walkAndClean(div)
      .replace(/\u200B|\uFEFF/g, "")
      .replace(/[.]/g, "")
      .replace(/\s+/g, " ")
      .trim()
      .toLowerCase();
  };

  const deepEqual = (obj1, obj2) => {
    if (obj1 === obj2) return true;

    if (typeof obj1 === "string" && typeof obj2 === "string") {
      return normalizeText(stripHTML4(obj1)) === normalizeText(stripHTML4(obj2));
    }

    if (
      typeof obj1 !== "object" ||
      typeof obj2 !== "object" ||
      obj1 === null ||
      obj2 === null
    ) {
      return false;
    }

    const keys1 = Object.keys(obj1).sort();
    const keys2 = Object.keys(obj2).sort();
    if (keys1.length !== keys2.length) return false;

    for (const key of keys1) {
      if (!keys2.includes(key)) return false;

      let val1 = obj1[key];
      let val2 = obj2[key];

      if (typeof val1 === "string" && typeof val2 === "string") {
        val1 = normalizeText(stripHTML4(val1));
        val2 = normalizeText(stripHTML4(val2));
      }

      if (Array.isArray(val1) && Array.isArray(val2)) {
        if (val1.length !== val2.length) return false;

        const used = new Set();
        for (const item1 of val1) {
          const matchIndex = val2.findIndex((item2, idx) => {
            if (used.has(idx)) return false;
            if (deepEqual(item1, item2)) {
              used.add(idx);
              return true;
            }
            return false;
          });
          if (matchIndex === -1) return false;
        }
        continue;
      }

      if (typeof val1 === "object" && typeof val2 === "object") {
        if (!deepEqual(val1, val2)) return false;
      } else if (val1 !== val2) {
        return false;
      }
    }

    return true;
  };

  const normalizeConditions = (conditions) => {
    if (!Array.isArray(conditions)) return [];

    return conditions.map((set) => {
      const normalizedProps = (set.properties || []).map((prop) => {
        const copy = { ...prop };
        delete copy.case_sensitive;

        for (const key in copy) {
          if (typeof copy[key] === "string") {
            copy[key] = normalizeText(stripHTML4(copy[key]));
          } else if (Array.isArray(copy[key])) {
            copy[key] = copy[key]
              .map((v) => (typeof v === "string" ? normalizeText(stripHTML4(v)) : v))
              .sort();
          }
        }

        return sortObjectValues(copy);
      });

      return {
        match_type: set.match_type?.toLowerCase(),
        properties: normalizedProps.sort((a, b) =>
          JSON.stringify(a).localeCompare(JSON.stringify(b))
        ),
      };
    });
  };

  const sortObjectValues = (obj) => {
    if (Array.isArray(obj)) {
      return obj
        .map((item) =>
          typeof item === "object" && item !== null
            ? sortObjectValues(item)
            : normalizeText(stripHTML4(item))
        )
        .sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));
    }

    if (typeof obj === "object" && obj !== null) {
      if ("condition_set_1" in obj || "condition_set_2" in obj) {
        const { operator, ...rest } = obj;
        const allConditions = Object.values(rest)
          .flat()
          .map((val) => normalizeText(stripHTML4(val)))
          .sort();

        return {
          operator: normalizeText(stripHTML4(operator || "")),
          conditions: allConditions,
        };
      }

      return Object.fromEntries(
        Object.entries(obj)
          .map(([key, value]) => [key, sortObjectValues(value)])
          .sort(([a], [b]) => a.localeCompare(b))
      );
    }

    return normalizeText(stripHTML4(obj));
  };

  const areConditionsEqual = (setA, setB) => {
    if (setA.length !== setB.length) return false;

    const permutations = generatePermutations(setB);
    return permutations.some((perm) => {
      return setA.every((a, i) => deepEqual(a, perm[i]));
    });
  };

  const generatePermutations = (arr) => {
    if (arr.length <= 1) return [arr];
    const perms = [];

    for (let i = 0; i < arr.length; i++) {
      const rest = [...arr.slice(0, i), ...arr.slice(i + 1)];
      for (const perm of generatePermutations(rest)) {
        perms.push([arr[i], ...perm]);
      }
    }

    return perms;
  };

  const groups = [];
  const used = new Set();

  for (let i = 0; i < activeRules.length; i++) {
    if (used.has(i)) continue;

    const current = activeRules[i];
    const normSummary = sortObjectValues(current.summary);
    const normActions = sortObjectValues(current.actions);
    const normConditions = normalizeConditions(current.conditions);

    const group = [current];
    used.add(i);

    for (let j = i + 1; j < activeRules.length; j++) {
      if (used.has(j)) continue;
      const compare = activeRules[j];

      const match =
        deepEqual(normSummary, sortObjectValues(compare.summary)) &&
        deepEqual(normActions, sortObjectValues(compare.actions)) &&
        areConditionsEqual(normConditions, normalizeConditions(compare.conditions));

      if (match) {
        group.push(compare);
        used.add(j);
      }
    }

    if (group.length > 1) {
      groups.push(group);
    }
  }

  return groups;
}

const Filterrecords = async (automationTypeId, newRulePloadDB6) => {
  let allRecords = [];
  let nextMarker = null;

  try {
    do {
      const queryObj = { query: { automation_type_id: automationTypeId } };
      if (nextMarker) queryObj.next = { marker: nextMarker };

      const response = await newRulePloadDB6.getAll(queryObj);
      if (!response.records || !Array.isArray(response.records)) break;

      const filtered = response.records.map((record) => ({
        ...record.data,
        display_id: record.display_id,
        rule_id: record.data.rule_id,
        automation_type_id: record.data.automation_type_id,
        id: record.data.rule_id || record.data.id,
      }));

      allRecords = allRecords.concat(filtered);

      nextMarker = response.links?.next?.marker || null;
    } while (nextMarker);

    allRecords.sort((a, b) => {
      const posA = typeof a.position === "number" ? a.position : Number.MAX_SAFE_INTEGER;
      const posB = typeof b.position === "number" ? b.position : Number.MAX_SAFE_INTEGER;
      return posA - posB;
    });

    // console.log(`✅ Filtered Records for Type ${automationTypeId}:`, allRecords);
    console.log(`✅ Filtered Records for Type ${automationTypeId}:`, JSON.stringify(allRecords[0], null, 2));

    return allRecords;
  } catch (error) {
    console.error("❌ Error fetching filtered records:", error);
    return [];
  }
};

const calculateLastModified = (updated_at) => {
  const updatedDate = new Date(updated_at);
  const currentDate = new Date();
  const diffInMilliseconds = currentDate - updatedDate;
  const seconds = Math.floor(diffInMilliseconds / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  const months = Math.floor(days / 30);
  const years = Math.floor(days / 365);

  if (years > 0) return years === 1 ? "a year ago" : `${years} years ago`;
  if (months > 0) return months === 1 ? "a month ago" : `${months} months ago`;
  if (days > 0) return `${days} day${days > 1 ? "s" : ""} ago`;
  if (hours > 0) return `${hours} hour${hours > 1 ? "s" : ""} ago`;
  if (minutes > 0) return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
  return "Just now";
};

const AutomationCard = ({
  rule = {},
  index,
  isFirstInGroup = false,
  onDelete,
  agent,
  activeTab,
  onSelect,
}) => {
  const {
    id,
    name = "Default Rule Name",
    summary = "",
    description = "",
    updated_at = "N/A",
    last_updated_by = "Unknown",
    affected_tickets_count = "--",
    active = false,
    position,
    automation_type_id,
  } = rule;

  const [menuOpen, setMenuOpen] = useState(false);
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const modalRef = useRef(null);
  const menuContainerRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (menuContainerRef.current && !menuContainerRef.current.contains(event.target)) {
        setMenuOpen(false);
      }
    };

    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  useEffect(() => {
    if (showDeleteModal && modalRef.current) {
      modalRef.current.open();
    }
  }, [showDeleteModal]);

  const openModal = () => setShowDeleteModal(true);
  const closeModal = () => {
    setShowDeleteModal(false);
    if (modalRef.current) modalRef.current.close();
  };

  const handleConfirmDelete = () => {
    closeModal();
    if (onDelete) onDelete(rule);
  };

  const handleClick = () => {
    if (onSelect) {
      onSelect(rule);
    }
  };


  const renderAgentName = () => {
    if (rule.agentName) {
      return rule.agentName;
    }
    if (!agent || !Array.isArray(agent)) {
      return last_updated_by || "Unknown";
    } else {
      const foundAgent = agent.find((e) => e.value === last_updated_by);
      return foundAgent ? foundAgent.text : last_updated_by || "Unknown";
    }
  };

  function extractText(htmlString) {
    if (!htmlString || typeof htmlString !== "string") return "";
    let text = htmlString.replace(/<[^>]+>/g, "").trim();

    if (text.toLowerCase().startsWith("if ")) {
      text = text.substring(3).trim();
    }

    // console.log("Actual Text :", text);
    return text;  // do not convert to lowercase here
  }

  function generateSummary(summary) {
    if (!summary) return "";
    if (typeof summary === "string") {
      return summary;
    }
    let conditionTexts = [];
    if (summary.conditions) {
      for (const setKey in summary.conditions) {
        if (Object.prototype.hasOwnProperty.call(summary.conditions, setKey)) {
          const conditionsVal = summary.conditions[setKey];
          const conditionsArray = Array.isArray(conditionsVal) ? conditionsVal : [conditionsVal];
          const cleanConditions = conditionsArray.map(extractText);
          conditionTexts.push(cleanConditions.join(", "));
        }
      }
    }
    const conditionsStr = conditionTexts.join(", ");
    let actionsStr = "";
    if (summary.actions && Array.isArray(summary.actions)) {
      const cleanActions = summary.actions.map(extractText);
      actionsStr = cleanActions.join(", ");
    }
    if (conditionsStr && actionsStr) {
      return `if ${conditionsStr}, then ${actionsStr}`;
    } else if (conditionsStr) {
      return `if ${conditionsStr}`;
    } else if (actionsStr) {
      return actionsStr;
    }
    return "";
  }

  function MenuList({ visible, onEdit, onClone, rule }) {
    return (
      <ul
        style={{
          position: "absolute",
          backgroundColor: "white",
          boxShadow: "0 8px 24px rgba(0, 0, 0, 0.15)",
          borderRadius: 6,
          padding: "8px 0",
          minWidth: 160,
          right: 0,
          top: 28,
          listStyle: "none",
          zIndex: 9999,
          margin: 0,
          opacity: visible ? 1 : 0,
          transform: visible ? "translateY(0px) scale(1)" : "translateY(-10px) scale(0.98)",
          transition: "opacity 300ms ease, transform 300ms ease",
          pointerEvents: visible ? "auto" : "none",
          willChange: "opacity, transform",
        }}
      >
        {[
          { name: "edit", label: "Edit", onClick: onEdit },
          { name: "clone", label: "Clone", onClick: onClone },
          {
            name: "delete",
            label: "Delete",
            onClick: () => {
              setMenuOpen(false);
              openModal();
            },
          },
        ].map(({ name, label, onClick }) => (
          <li
            key={name}
            style={{
              display: "flex",
              alignItems: "center",
              gap: 8,
              padding: "8px 16px",
              cursor: "pointer",
              color: "#333",
              fontWeight: 500,
              userSelect: "none",
              backgroundColor: "transparent",
              transition: "background-color 0.2s",
            }}
            onClick={(e) => {
              e.stopPropagation();
              onClick?.();
              setMenuOpen(false);
            }}
            onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = "#f5f7f9")}
            onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = "transparent")}
          >
            <FwIcon name={name} size={18} color="#333" />
            <div>{label}</div>
          </li>
        ))}
      </ul>
    );
  }

  return (
    <>
      <div
        className="fw-card-1 fw-flex fw-flex-column"
        style={{
          overflow: "visible",
          border: "0.5px solid #ddd",
          backgroundColor: isFirstInGroup ? "#fff" : "#e5f2fd",
          cursor: "pointer",
        }}
        onClick={handleClick}
      >
        <section
          className="fw-flex-grow fw-px-16 fw-flex fw-flex-row"
          style={{
            justifyContent: "space-between",
            alignItems: "center",
            marginBottom: "40px",
          }}
        >
          <div
            style={{
              paddingLeft: "16px",
              maxWidth: "80%",
              flexBasis: "80%",
              flexShrink: 0,
              whiteSpace: "normal",
            }}
          >
            <h5 className="fw-type-h1 fw-mt-0 fw-mb-8">
              {position}. {name}
            </h5>
            <p
              className="fw-type-xs fw-mt-0 fw-mb-20"
              style={{ marginBottom: "10px", fontSize: "14px" }}
            >
              {generateSummary(rule.summary)}
            </p>
          </div>
          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: "8px",
              padding: "8px 16px",
              flexBasis: "20%",
              flexShrink: 0,
              marginTop: "-50px",
              justifyContent: "flex-end",
              position: "relative",
            }}
          >
            <FwToggle size="medium" checked={active} />
            <div ref={menuContainerRef} style={{ position: "relative" }}>
              <div
                role="button"
                tabIndex={0}
                onClick={(e) => {
                  e.stopPropagation();
                  setMenuOpen(!menuOpen);
                }}
                style={{
                  zIndex: 1,
                  background: "none",
                  border: "none",
                  cursor: "pointer",
                }}
              >
                <svg
                  xmlns="http://www.w3.org/2000/svg"
                  width="16"
                  height="16"
                  viewBox="0 0 24 24"
                  className="app-icon dropdown-toggle"
                >
                  <path
                    fillRule="evenodd"
                    d="M12 5c-1.38 0-2.5-1.12-2.5-2.5S10.62 0 12 0s2.5 1.12 2.5 2.5S13.38 5 12 5zM12 14c-1.38 0-2.5-1.12-2.5-2.5S10.62 9 12 9s2.5 1.12 2.5 2.5S13.38 14 12 14zM12 24c-1.38 0-2.5-1.12-2.5-2.5S10.62 19 12 19s2.5 1.12 2.5 2.5S13.38 24 12 24z"
                  />
                </svg>
              </div>
              <MenuList
                visible={menuOpen}
                onEdit={() => alert("Edit clicked")}
                onClone={() => alert("Clone clicked")}
                rule={rule}
              />
            </div>
          </div>
        </section>
        <section
          className="fw-type-xs fw-flex fw-flex-row fw-items-center options"
          style={{
            background: "#f5f7f9",
            padding: "10px 16px",
            borderRadius: "5px",
          }}
        >
          <div
            style={{
              display: "flex",
              alignItems: "center",
              justifyContent: "space-evenly",
              width: "100%",
              fontSize: "14px",
              color: "#666",
              textAlign: "center",
            }}
          >
            <span>
              Last Modified: <strong>{calculateLastModified(updated_at)}</strong>
            </span>
            <span>|</span>
            <span>By: {renderAgentName()}</span>
            <span>|</span>
            <span>Impacted tickets (Last 7 days): {affected_tickets_count}</span>
          </div>
        </section>
      </div>

      <FwModal
        id={`delete-modal-${id}`}
        ref={modalRef}
        size="small"
        submit-color="danger"
        submit-text="Delete"
        onFwSubmit={(e) => {
          e.preventDefault?.();
          handleConfirmDelete();
        }}
        onFwClose={() => {
          setShowDeleteModal(false);
          if (modalRef.current) modalRef.current.close();
        }}
      >
        <FwModalTitle>
          <span>Delete message</span>
        </FwModalTitle>
        <FwModalContent>
          <span>Are you sure you want to delete this Message?</span>
        </FwModalContent>
      </FwModal>
    </>
  );
};

const AutomationTabs = ({ client }) => {
  const [isRulesDBReady, setIsRulesDBReady] = useState(false);
  const [loadingBannerVisible, setLoadingBannerVisible] = useState(true);
  const intervalIdRef = useRef(null);
  const [showSearchHint, setShowSearchHint] = useState(false);

  const [searchTerm, setSearchTerm] = useState("");
  const [searchQuery, setSearchQuery] = useState("");
  const [searchTriggered, setSearchTriggered] = useState(false);

  const [errorMessage, setErrorMessage] = useState(null);

  const [activeTab, setActiveTab] = useState("ticketcreate");
  const [inputState, setInputState] = useState("normal");
  const [tabsInitialized, setTabsInitialized] = useState(false);
  const modalRef = useRef(null);

  const [ticketCreationRules, setTicketCreationRules] = useState([]);
  const [ticketUpdateRules, setTicketUpdateRules] = useState([]);
  const [hourlyTriggerRules, setHourlyTriggerRules] = useState([]);

  const [loading, setLoading] = useState(false);
  const [agent, setAgent] = useState([]);
  const rulesPerPage = 30;

  const [currentPage, setCurrentPage] = useState({
    ticketcreate: 1,
    ticketupdate: 1,
    hourly: 1,
  });

  const [recentDataCache, setRecentDataCache] = useState({
    ticketcreate: null,
    ticketupdate: null,
    hourly: null,
  });

  const toast = useRef(ToastController({ position: "top-center" }));

  const newRulePloadDB6 = useRef(null);
  const warningTimerRef = useRef(null);

  const ticketCreate = 1;
  const ticketUpdate = 4;
  const hourlyTriggers = 3;

  const [fetchFromApi, setFetchFromApi] = useState(false);

  const [showPagination, setShowPagination] = useState(false);

  const [ticketCreationRuleGroups, setTicketCreationRuleGroups] = useState([]);
  const [ticketUpdateRuleGroups, setTicketUpdateRuleGroups] = useState([]);
  const [hourlyRuleGroups, setHourlyRuleGroups] = useState([]);

  const ruleViewOptions = [
    {
      value: "all_rules",
      text: "All Rules",
      graphicsProps: { name: "list" },
    },
    {
      value: "duplicate_rules",
      text: "Duplicate Rules",
      graphicsProps: { name: "warning" },
    },
  ];
  

  const [ruleViewFilter, setRuleViewFilter] = useState(ruleViewOptions[0]);



  useEffect(() => {
    if (!loading) {
      const timer = setTimeout(() => {
        setShowPagination(true);
      }, 200);
      return () => clearTimeout(timer);
    } else {
      setShowPagination(false);
    }
  }, [loading, activeTab, currentPage]);

  const paginateDuplicateGroups = (groups, rulesPerPage, searchQuery) => {
    // const query = searchQuery.trim().toLowerCase();

    // const filteredGroups = groups
    //   .map((group) =>
    //     group.filter((rule) => {
    //       if (!query) return true;

    //       const name = rule.name?.toLowerCase() || '';
    //       const description = rule.description?.toLowerCase() || '';
    //       const customSummary =
    //       typeof rule.summary === 'string'
    //         ? rule.summary.toLowerCase()
    //         : rule.summary?.summary?.toLowerCase() || '';


    //       // Flatten and stringify all relevant searchable content
    //       const conditionStrings = [
    //         ...(rule.summary?.conditions?.condition_set_1 || []),
    //         ...(rule.summary?.conditions?.condition_set_2 || [])
    //       ].join(' ').toLowerCase();

    //       const actionStrings = (rule.summary?.actions || []).join(' ').toLowerCase();

    //       const conditionDetails = (() => {
    //         if (Array.isArray(rule.conditions)) {
    //           return rule.conditions
    //             .map((cond) => {
    //               if (Array.isArray(cond.properties)) {
    //                 return cond.properties
    //                   .map((prop) => {
    //                     const field = prop.field_name?.toString().toLowerCase() || '';
    //                     const operator = prop.operator?.toString().toLowerCase() || '';
    //                     const value = Array.isArray(prop.value)
    //                       ? prop.value.join(',').toLowerCase()
    //                       : prop.value?.toString().toLowerCase() || '';
    //                     return `${field} ${operator} ${value}`;
    //                   })
    //                   .join(' ');
    //               } else if (typeof cond.properties === 'string') {
    //                 return cond.properties.toLowerCase();
    //               }
    //               return '';
    //             })
    //             .join(' ');
    //         } else if (typeof rule.conditions === 'string') {
    //           return rule.conditions.toLowerCase();
    //         } else {
    //           // Fallback in case rule.conditions is an object or something unexpected
    //           return JSON.stringify(rule.conditions || '').toLowerCase();
    //         }
    //       })();


    //       const actionDetails = (rule.actions || [])
    //         .map((a) => a.field_name?.toString().toLowerCase() || '')
    //         .join(' ');

    //       const combinedSearchData = [
    //         name,
    //         description,
    //         conditionStrings,
    //         actionStrings,
    //         conditionDetails,
    //         actionDetails,
    //         customSummary
    //       ].join(' ');

    //       return combinedSearchData.includes(query);
    //     })
    //   )
    //   .filter((group) => group.length > 0);


    const query = searchQuery.trim().toLowerCase();

    const filteredGroups = groups
      .map((group) =>
        group.filter((rule) => {
          if (!query) return true;

          const name = rule.name?.toLowerCase() || '';
          const description = rule.description?.toLowerCase() || '';
          const customSummary =
            typeof rule.summary === 'string'
              ? rule.summary.toLowerCase()
              : rule.summary?.summary?.toLowerCase() || '';

          const conditionStrings = [
            ...(rule.summary?.conditions?.condition_set_1 || []),
            ...(rule.summary?.conditions?.condition_set_2 || [])
          ].join(' ').toLowerCase();

          const actionStrings = (rule.summary?.actions || []).join(' ').toLowerCase();

          const conditionDetails = (() => {
            if (Array.isArray(rule.conditions)) {
              return rule.conditions
                .map((cond) => {
                  if (Array.isArray(cond.properties)) {
                    return cond.properties
                      .map((prop) => {
                        const field = prop.field_name?.toString().toLowerCase() || '';
                        const operator = prop.operator?.toString().toLowerCase() || '';
                        const value = Array.isArray(prop.value)
                          ? prop.value.join(',').toLowerCase()
                          : prop.value?.toString().toLowerCase() || '';
                        return `${field} ${operator} ${value}`;
                      })
                      .join(' ');
                  } else if (typeof cond.properties === 'string') {
                    return cond.properties.toLowerCase();
                  }
                  return '';
                })
                .join(' ');
            } else if (typeof rule.conditions === 'string') {
              return rule.conditions.toLowerCase();
            } else {
              return JSON.stringify(rule.conditions || '').toLowerCase();
            }
          })();

          const actionDetails = (() => {
            if (Array.isArray(rule.actions)) {
              return rule.actions.map((a) => a.field_name?.toString().toLowerCase() || '').join(' ');
            } else if (typeof rule.actions === "string") {
              return rule.actions.toLowerCase();
            }
            return "";
          })();

          const combinedSearchData = [
            name,
            description,
            conditionStrings,
            actionStrings,
            conditionDetails,
            actionDetails,
            customSummary
          ].join(' ');

          return combinedSearchData.includes(query);
        })
      )
      .filter((group) => group.length > 0);

    const paginatedGroups = [];
    let currentChunk = [];
    let currentCount = 0;

    for (const group of filteredGroups) {
      const groupSize = group.length;

      if (groupSize > rulesPerPage) {
        if (currentCount > 0) {
          paginatedGroups.push(currentChunk);
          currentChunk = [];
          currentCount = 0;
        }
        paginatedGroups.push([group]);
      } else {
        if (currentCount + groupSize <= rulesPerPage) {
          currentChunk.push(group);
          currentCount += groupSize;
        } else {
          if (currentCount > 0) {
            paginatedGroups.push(currentChunk);
          }
          currentChunk = [group];
          currentCount = groupSize;
        }
      }
    }

    if (currentCount > 0) {
      paginatedGroups.push(currentChunk);
    }

    return paginatedGroups;
  };


  
  useEffect(() => {
    const initializeDatabase = async () => {
      const entity = await client.db.entity({ version: "v1" });
      newRulePloadDB6.current = entity.get("newRulePloadDB6");

      const agentdaa = await getAgents(client);
      setAgent(agentdaa);

      try {
        const tabData = await client.db.get("TabDB");
        if (!tabData || !tabData.LastVisitedTab) {
          await client.db.set("TabDB", { LastVisitedTab: "ticketcreate" });
          setActiveTab("ticketcreate");
        } else {
          setActiveTab(tabData.LastVisitedTab);
        }
      } catch (error) {
        await client.db.set("TabDB", { LastVisitedTab: "ticketcreate" });
        setActiveTab("ticketcreate");
      } finally {
        setTabsInitialized(true);
      }
    };

    initializeDatabase();
  }, [client]);

  useEffect(() => {
    setCurrentPage((prev) => ({
      ...prev,
      [activeTab]: 1,
    }));
    setRuleViewFilter(ruleViewOptions[0]);
  }, [activeTab, fetchFromApi]);

  useEffect(() => {
    const fetchOnTabOrModeChange = async () => {
      setLoading(true);
      setErrorMessage(null);

      try {
        let error = null;

        if (fetchFromApi) {
          if (recentDataCache.agent) {
            setAgent(recentDataCache.agent);
          } else {
            await getAgents(client, (data) => {
              setAgent(data);
              setRecentDataCache((prev) => ({ ...prev, agent: data }));
            });
          }

          if (recentDataCache[activeTab]) {
            if (activeTab === "ticketcreate") {
              setTicketCreationRules(recentDataCache.ticketcreate);
            } else if (activeTab === "ticketupdate") {
              setTicketUpdateRules(recentDataCache.ticketupdate);
            } else if (activeTab === "hourly") {
              setHourlyTriggerRules(recentDataCache.hourly);
            }
          } else {
            if (activeTab === "ticketcreate") {
              error = await getTicketCreationRules(client, (data) => {
                setTicketCreationRules(data);
                setRecentDataCache((prev) => ({ ...prev, ticketcreate: data }));
              });
            } else if (activeTab === "ticketupdate") {
              error = await getTicketUpdationRules(client, (data) => {
                setTicketUpdateRules(data);
                setRecentDataCache((prev) => ({ ...prev, ticketupdate: data }));
              });
            } else if (activeTab === "hourly") {
              error = await getHourlyRules(client, (data) => {
                setHourlyTriggerRules(data);
                setRecentDataCache((prev) => ({ ...prev, hourly: data }));
              });
            }
          }
        } else {
          if (!newRulePloadDB6.current) {
            setLoading(false);
            return;
          }

          if (activeTab === "ticketcreate") {
            const data = await Filterrecords(ticketCreate, newRulePloadDB6.current);
            setTicketCreationRules(data);
          } else if (activeTab === "ticketupdate") {
            const data = await Filterrecords(ticketUpdate, newRulePloadDB6.current);
            setTicketUpdateRules(data);
          } else if (activeTab === "hourly") {
            const data = await Filterrecords(hourlyTriggers, newRulePloadDB6.current);
            setHourlyTriggerRules(data);
          }

          setRecentDataCache({
            ticketcreate: null,
            ticketupdate: null,
            hourly: null,
            agent: null,
          });

          setAgent(null);
        }

        if (error) {
          setErrorMessage(error);
        }
      } catch (err) {
        setErrorMessage("An unexpected error occurred while fetching data.");
      }

      setLoading(false);
    };

    if (tabsInitialized && isRulesDBReady) {
      fetchOnTabOrModeChange();
    }
  }, [activeTab, fetchFromApi, client, tabsInitialized, isRulesDBReady]);

  // const duplicateGroupsMap = useMemo(() => {
  //   // groups: array of arrays of duplicate rules with length > 1
  //   let allRules = [];
  //   if (activeTab === "ticketcreate") allRules = ticketCreationRules;
  //   else if (activeTab === "ticketupdate") allRules = ticketUpdateRules;
  //   else if (activeTab === "hourly") allRules = hourlyTriggerRules;

  //   // group duplicates, filtered active only
  //   const groups = groupDuplicates(allRules).filter((g) => g.length > 1);

  //   // Map rule_id -> isFirstInGroup flag (true only for first rule of each duplicate group)
  //   const firstRuleIds = new Set();
  //   groups.forEach((group) => {
  //     if (group.length > 0) {
  //       firstRuleIds.add(group[0].id);
  //     }
  //   });

  //   // Return structure for lookup: firstRuleIds set + flattened set of all duplicate IDs
  //   const duplicateRuleIds = new Set(groups.flat().map((r) => r.id));

  //   return { firstRuleIds, duplicateRuleIds };
  // }, [activeTab, ticketCreationRules, ticketUpdateRules, hourlyTriggerRules]);


  const duplicateGroupsMap = useMemo(() => {
    let allRules = [];
    if (activeTab === "ticketcreate") allRules = ticketCreationRules;
    else if (activeTab === "ticketupdate") allRules = ticketUpdateRules;
    else if (activeTab === "hourly") allRules = hourlyTriggerRules;
  
    const groups = findAndGroupExactDuplicates(allRules);
  
    const firstRuleIds = new Set();
    groups.forEach((group) => {
      if (group.length > 0) {
        firstRuleIds.add(group[0].id);
      }
    });
  
    const duplicateRuleIds = new Set(groups.flat().map((r) => r.id));
  
    return { firstRuleIds, duplicateRuleIds };
  }, [activeTab, ticketCreationRules, ticketUpdateRules, hourlyTriggerRules]);

  const highlightDuplicates =
    ruleViewFilter.value === "all_rules" &&
    (!searchQuery || searchQuery.trim() === "");

  // const getFilteredRules = (rules) => {
  //   if (!searchQuery.trim()) return rules;

  //   const query = searchQuery.trim().toLowerCase();

  //   return rules.filter((rule) => {
  //     const name = rule.name?.toLowerCase() || '';
  //     const description = rule.description?.toLowerCase() || '';

  //     const summaryConditionText = [
  //       ...(rule.summary?.conditions?.condition_set_1 || []),
  //       ...(rule.summary?.conditions?.condition_set_2 || [])
  //     ]
  //       .map((x) => x.replace(/<[^>]+>/g, '').toLowerCase())
  //       .join(' ');

  //     const summaryActionsText = Array.isArray(rule.summary?.actions)
  //       ? rule.summary.actions.map((x) => x.replace(/<[^>]+>/g, '').toLowerCase()).join(' ')
  //       : '';

  //     const deepConditionText = Array.isArray(rule.conditions)
  //       ? rule.conditions
  //         .map((set) => {
  //           if (Array.isArray(set.properties)) {
  //             return set.properties
  //               .map((p) => {
  //                 const field = p.field_name?.toString().toLowerCase() || '';
  //                 const op = p.operator?.toString().toLowerCase() || '';
  //                 const val = Array.isArray(p.value)
  //                   ? p.value.join(',').toLowerCase()
  //                   : p.value?.toString().toLowerCase() || '';
  //                 return `${field} ${op} ${val}`;
  //               })
  //               .join(' ');
  //           } else if (typeof set.properties === 'string') {
  //             return set.properties.toLowerCase();
  //           }
  //           return '';
  //         })
  //         .join(' ')
  //       : typeof rule.conditions === 'string'
  //         ? rule.conditions.toLowerCase()
  //         : JSON.stringify(rule.conditions || '').toLowerCase();

  //     const actionText = Array.isArray(rule.actions)
  //       ? rule.actions.map((a) => a.field_name?.toLowerCase() || '').join(' ')
  //       : '';

  //     const fullText = [
  //       name,
  //       description,
  //       summaryConditionText,
  //       summaryActionsText,
  //       deepConditionText,
  //       actionText
  //     ].join(' ');

  //     return fullText.includes(query);
  //   });
  // };


  // New Serch
  

  const getFilteredRules = (rules) => {
    if (!searchQuery.trim()) return rules;
  
    const query = searchQuery.trim().toLowerCase();
  
    return rules.filter((rule) => {
      const name = rule.name?.toLowerCase() || '';
      const description = rule.description?.toLowerCase() || '';
  
      // If summary is a string, use it directly; if object, try to get conditions/actions from it
      let summaryText = '';
      let summaryConditionText = '';
      let summaryActionsText = '';
  
      if (typeof rule.summary === 'string') {
        summaryText = rule.summary.toLowerCase();
      } else if (typeof rule.summary === 'object' && rule.summary !== null) {
        summaryConditionText = [
          ...(rule.summary.conditions?.condition_set_1 || []),
          ...(rule.summary.conditions?.condition_set_2 || [])
        ]
          .map((x) => x.replace(/<[^>]+>/g, '').toLowerCase())
          .join(' ');
  
        summaryActionsText = Array.isArray(rule.summary.actions)
          ? rule.summary.actions.map((x) => x.replace(/<[^>]+>/g, '').toLowerCase()).join(' ')
          : '';
      }
  
      // Deep condition text (usually from conditions field)
      const deepConditionText = Array.isArray(rule.conditions)
        ? rule.conditions
            .map((set) => {
              if (Array.isArray(set.properties)) {
                return set.properties
                  .map((p) => {
                    const field = p.field_name?.toString().toLowerCase() || '';
                    const op = p.operator?.toString().toLowerCase() || '';
                    const val = Array.isArray(p.value)
                      ? p.value.join(',').toLowerCase()
                      : p.value?.toString().toLowerCase() || '';
                    return `${field} ${op} ${val}`;
                  })
                  .join(' ');
              } else if (typeof set.properties === 'string') {
                return set.properties.toLowerCase();
              }
              return '';
            })
            .join(' ')
        : typeof rule.conditions === 'string'
        ? rule.conditions.toLowerCase()
        : JSON.stringify(rule.conditions || '').toLowerCase();
  
      // Actions text (usually from actions field)
      const actionText = Array.isArray(rule.actions)
        ? rule.actions.map((a) => a.field_name?.toLowerCase() || '').join(' ')
        : typeof rule.actions === 'string'
        ? rule.actions.toLowerCase()
        : '';
  
      const fullText = [
        name,
        description,
        summaryText,
        summaryConditionText,
        summaryActionsText,
        deepConditionText,
        actionText
      ].join(' ');
  
      return fullText.includes(query);
    });
  };

  const flattenGroups = (groups) => groups.flat();

  // useEffect(() => {
  //   if (ruleViewFilter.value === "duplicate_rules") {
  //     // Recalculate duplicate groups for the active tab automatically
  //     if (activeTab === "ticketcreate") {
  //       const grouped = groupDuplicates(ticketCreationRules);
  //       const duplicateGroups = grouped
  //         .filter((group) => group.length > 1)
  //         .sort((a, b) => b.length - a.length);
  //       setTicketCreationRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
  //     } else if (activeTab === "ticketupdate") {
  //       const grouped = groupDuplicates(ticketUpdateRules);
  //       const duplicateGroups = grouped
  //         .filter((group) => group.length > 1)
  //         .sort((a, b) => b.length - a.length);
  //       setTicketUpdateRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
  //     } else if (activeTab === "hourly") {
  //       const grouped = groupDuplicates(hourlyTriggerRules);
  //       const duplicateGroups = grouped
  //         .filter((group) => group.length > 1)
  //         .sort((a, b) => b.length - a.length);
  //       setHourlyRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
  //     }
  //   } else {
  //     // Clear duplicate groups when switching away from duplicate_rules view
  //     setTicketCreationRuleGroups([]);
  //     setTicketUpdateRuleGroups([]);
  //     setHourlyRuleGroups([]);
  //   }
  // }, [ruleViewFilter, activeTab, ticketCreationRules, ticketUpdateRules, hourlyTriggerRules]);


  // useEffect(() => {
  //   if (ruleViewFilter.value === "duplicate_rules") {
  //     let duplicateGroups = [];
  
  //     if (activeTab === "ticketcreate") {
  //       duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
  //       setTicketCreationRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
  //     } else if (activeTab === "ticketupdate") {
  //       duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
  //       setTicketUpdateRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
  //     } else if (activeTab === "hourly") {
  //       duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
  //       setHourlyRuleGroups(duplicateGroups);
  //       setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
  //     }
  //   } else {
  //     // Clear duplicate groups when switching away from duplicate_rules view
  //     setTicketCreationRuleGroups([]);
  //     setTicketUpdateRuleGroups([]);
  //     setHourlyRuleGroups([]);
  //   }
  // }, [ruleViewFilter, activeTab, ticketCreationRules, ticketUpdateRules, hourlyTriggerRules]);


  useEffect(() => {
    if (ruleViewFilter.value === "duplicate_rules") {
      let duplicateGroups = [];
  
      if (fetchFromApi) {
        console.log(`[Duplicate Filter] Using API data for active tab: ${activeTab}`);
  
        if (activeTab === "ticketcreate") {
          duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
          setTicketCreationRuleGroups(duplicateGroups);
          setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
        } else if (activeTab === "ticketupdate") {
          duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
          setTicketUpdateRuleGroups(duplicateGroups);
          setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
        } else if (activeTab === "hourly") {
          duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
          setHourlyRuleGroups(duplicateGroups);
          setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
        }
      } else {
        console.log(`[Duplicate Filter] Using entity data for active tab: ${activeTab}`);
          
        switch (activeTab) {
          case "ticketcreate":
            console.log("Entity Active Ticket Create (Type 1/3)");
            setTicketCreationRuleGroups(findDuplicateRulestype1and3(ticketCreationRules));
            setCurrentPage(prev => ({ ...prev, ticketcreate: 1 }));
            break;
        
          case "ticketupdate":
            console.log("Entity Active Ticket Update (Type 4)");
            setTicketUpdateRuleGroups(findDuplicateRulestype4(ticketUpdateRules));
            setCurrentPage(prev => ({ ...prev, ticketupdate: 1 }));
            break;
        
          case "hourly":
            console.log("Entity Active Hourly (Type 1/3)");
            setHourlyRuleGroups(findDuplicateRulestype1and3(hourlyTriggerRules));
            setCurrentPage(prev => ({ ...prev, hourly: 1 }));
            break;
        
          default:
            break;
        }
        
        
      }
    } else {
      
      console.log("[Duplicate Filter] Filter cleared, resetting duplicate groups and pagination");
  
      setTicketCreationRuleGroups([]);
      setTicketUpdateRuleGroups([]);
      setHourlyRuleGroups([]);
  
      setCurrentPage({
        ticketcreate: 1,
        ticketupdate: 1,
        hourly: 1,
      });
    }
  }, [
    ruleViewFilter,
    activeTab,
    ticketCreationRules,
    ticketUpdateRules,
    hourlyTriggerRules,
    fetchFromApi,
  ]);


  function findDuplicateRulestype1and3(records = [], { flat = false } = {}) {
    const seenKeys = new Map();  // key -> group key or representative record
    const groupsMap = new Map(); // group key -> array of rules
    const duplicateRecords = []; // for flat mode
  
    const stripHTML4 = (htmlString) => {
      if (typeof htmlString !== "string") {
        htmlString = String(htmlString || "");
      }
  
      const div = document.createElement("div");
      div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");
  
      function walkAndClean(node) {
        let result = "";
        for (const child of node.childNodes) {
          if (child.nodeType === Node.TEXT_NODE) {
            result += child.nodeValue;
          } else if (child.nodeType === Node.ELEMENT_NODE) {
            result += walkAndClean(child);
          }
        }
        return result;
      }
  
      return walkAndClean(div)
        .replace(/\u200B|\uFEFF|\u00A0/g, "")
        .replace(/\./g, "")
        .replace(/\s+/g, "")
        .toLowerCase();
    };
  
    const normalizeConditionParts = (rawConditions) => {
      // console.log("✅ [normalizeConditionParts] rawConditions:", rawConditions);
      // console.log("ℹ️ Type of rawConditions:", typeof rawConditions);
    
      const parts = typeof rawConditions === "string" ? rawConditions.split(",") : [];
    
      // if (typeof rawConditions !== "string") {
      //   console.warn("⚠️ [normalizeConditionParts] Expected string but got:", typeof rawConditions, rawConditions);
      // }
    
      const set1 = [], set2 = [];
      let currentSet = null;
      let tempClause = [];
    
      const stripHTML4 = (htmlString) => {
        if (typeof htmlString !== "string") htmlString = String(htmlString || "");
        const div = document.createElement("div");
        div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");
        return div.textContent || div.innerText || "";
      };
    
      const pushClause = (targetSet, includeOperator = null) => {
        if (tempClause.length && targetSet) {
          const joinedClause = tempClause.join(",").trim();
          const cleaned = stripHTML4(joinedClause);
          // console.log("📦 [pushClause] Cleaned clause:", cleaned);
          if (cleaned) targetSet.push(cleaned);
          tempClause = [];
    
          if (includeOperator) {
            // console.log("➕ [pushClause] Operator pushed:", includeOperator);
            targetSet.push(includeOperator);
          }
        }
      };
    
      const isSetMarker = (part) =>
        part.includes("condition_set_1") || part.includes("condition_set_2");
    
      const handleSetSwitch = (rawPart) => {
        pushClause(currentSet);
        if (rawPart.includes("condition_set_1")) return set1;
        if (rawPart.includes("condition_set_2")) return set2;
        return currentSet;
      };
    
      const isLogicalOperator = (part) => {
        const op = part.toLowerCase();
        return op === "any" || op === "all";
      };
    
      for (let i = 0; i < parts.length; i++) {
        const rawPart = parts[i].trim();
        if (isSetMarker(rawPart)) {
          // console.log("🔀 [Set Switch] Switching set for part:", rawPart);
          currentSet = handleSetSwitch(rawPart);
        } else if (isLogicalOperator(rawPart)) {
          // console.log("⚙️ [Operator] Found logical operator:", rawPart);
          pushClause(currentSet, rawPart.toLowerCase());
        } else if (currentSet) {
          tempClause.push(rawPart);
        }
      }
    
      pushClause(currentSet);
      set1.sort();
      set2.sort();
    
      // console.log("✅ Final set1:", set1);
      // console.log("✅ Final set2:", set2);
    
      return { set1, set2 };
    };
    
  
    const normalizeActions = (rawActions) => {
      if (typeof rawActions !== 'string' || !rawActions) {
        return '';
      }
    
      const parts = rawActions.split("&?");
      const normalizedClauses = [];
    
      for (const part of parts) {
        const items = part.split(",").map(v => stripHTML4(v));
        const clause = items.sort().join(" ").trim();
        if (clause) normalizedClauses.push(clause);
      }
    
      normalizedClauses.sort((a, b) => a.localeCompare(b));
    
      return normalizedClauses.join(" | ");
    };
  
    for (const record of records) {
      const data = record.data ?? record;
      const { conditions = "", actions = "", operator = "", active } = data;
  
      if (!(active === true || active === "true")) continue;
  
      const { set1, set2 } = normalizeConditionParts(conditions);
      const normalizedActions = normalizeActions(actions);
      const normalizedOperator = stripHTML4(operator);
  
      const key1 = `${set1.join("|")}|${set2.join("|")}|${normalizedActions}|${normalizedOperator}`;
      const key2 = `${set2.join("|")}|${set1.join("|")}|${normalizedActions}|${normalizedOperator}`;
  
      if (flat) {
        // Flat duplicate logic
        if (seenKeys.has(key1) || seenKeys.has(key2)) {
          const existing = seenKeys.get(key1) || seenKeys.get(key2);
          if (!duplicateRecords.includes(existing)) {
            duplicateRecords.push(existing);
          }
          duplicateRecords.push(record);
        } else {
          seenKeys.set(key1, record);
        }
      } else {
        // Grouped duplicate logic
        if (seenKeys.has(key1)) {
          const groupKey = seenKeys.get(key1);
          groupsMap.get(groupKey).push(record);
        } else if (seenKeys.has(key2)) {
          const groupKey = seenKeys.get(key2);
          groupsMap.get(groupKey).push(record);
        } else {
          seenKeys.set(key1, key1);
          groupsMap.set(key1, [record]);
        }
      }
    }
  
    return flat
      ? duplicateRecords
      : Array.from(groupsMap.values()).filter(group => group.length > 1);
  }
  

function findDuplicateRulestype4(records = []) {
  const seenRules = new Map(); // key => array of records 
  // 3with that key
  const duplicateGroups = [];

  const stripHTML4 = (htmlString) => {
    if (typeof htmlString !== "string") {
      htmlString = String(htmlString || "");
    }

    if (typeof document === "undefined") return htmlString;

    const div = document.createElement("div");
    div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");

    function walkAndClean(node) {
      let result = "";
      for (const child of node.childNodes) {
        if (child.nodeType === Node.TEXT_NODE) {
          result += child.nodeValue;
        } else if (child.nodeType === Node.ELEMENT_NODE) {
          result += walkAndClean(child);
        }
      }
      return result;
    }

    return walkAndClean(div)
      .replace(/\u200B|\uFEFF|\u00A0/g, "")
      .replace(/\./g, "")
      .replace(/\s+/g, "")
      .toLowerCase();
  };

  const normalizeConditionParts = (rawConditions) => {
    // console.log("✅ [normalizeConditionParts] rawConditions:", rawConditions);
    // console.log("ℹ️ Type of rawConditions:", typeof rawConditions);
  
    const parts = typeof rawConditions === "string" ? rawConditions.split(",") : [];
  
    // if (typeof rawConditions !== "string") {
    //   console.warn("⚠️ [normalizeConditionParts] Expected string but got:", typeof rawConditions, rawConditions);
    // }
  
    const set1 = [], set2 = [];
    let currentSet = null;
    let tempClause = [];
  
    const stripHTML4 = (htmlString) => {
      if (typeof htmlString !== "string") htmlString = String(htmlString || "");
      const div = document.createElement("div");
      div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");
      return div.textContent || div.innerText || "";
    };
  
    const pushClause = (targetSet, includeOperator = null) => {
      if (tempClause.length && targetSet) {
        const joinedClause = tempClause.join(",").trim();
        const cleaned = stripHTML4(joinedClause);
        // console.log("📦 [pushClause] Cleaned clause:", cleaned);
        if (cleaned) targetSet.push(cleaned);
        tempClause = [];
  
        if (includeOperator) {
          // console.log("➕ [pushClause] Operator pushed:", includeOperator);
          targetSet.push(includeOperator);
        }
      }
    };
  
    const isSetMarker = (part) =>
      part.includes("condition_set_1") || part.includes("condition_set_2");
  
    const handleSetSwitch = (rawPart) => {
      pushClause(currentSet);
      if (rawPart.includes("condition_set_1")) return set1;
      if (rawPart.includes("condition_set_2")) return set2;
      return currentSet;
    };
  
    const isLogicalOperator = (part) => {
      const op = part.toLowerCase();
      return op === "any" || op === "all";
    };
  
    for (let i = 0; i < parts.length; i++) {
      const rawPart = parts[i].trim();
  
      if (isSetMarker(rawPart)) {
        console.log("🔀 [Set Switch] Switching set for part:", rawPart);
        currentSet = handleSetSwitch(rawPart);
      } else if (isLogicalOperator(rawPart)) {
        console.log("⚙️ [Operator] Found logical operator:", rawPart);
        pushClause(currentSet, rawPart.toLowerCase());
      } else if (currentSet) {
        tempClause.push(rawPart);
      }
    }
  
    pushClause(currentSet);
    set1.sort();
    set2.sort();
  
    // console.log("✅ Final set1:", set1);
    // console.log("✅ Final set2:", set2);
  
    return { set1, set2 };
  };
  

  const normalizeField = (value) => {
    if (Array.isArray(value)) {
      return value
        .map((item) =>
          Object.values(item)
            .map((v) => stripHTML4(v))
            .join(" ")
        )
        .sort()
        .join(",");
    } else if (typeof value === "string") {
      return value
        .split(",")
        .map((item) => stripHTML4(item))
        .sort()
        .join(",");
    }
    return "";
  };

  const normalizeEvents = (eventString) => {
    if (typeof eventString !== "string") return "";
    return eventString
      .split(/\s+or\s+/i)
      .map((item) => stripHTML4(item))
      .sort()
      .join(" or ");
  };

  const normalizeActions = (rawActions) => {
    if (typeof rawActions !== 'string' || !rawActions) return '';
  
    const parts = rawActions.split("&?");
    const normalizedClauses = [];
  
    const stripHTML4 = (htmlString) => {
      if (typeof htmlString !== "string") htmlString = String(htmlString || "");
      const div = document.createElement("div");
      div.innerHTML = htmlString.replace(/&nbsp;/gi, " ");
      return div.textContent || div.innerText || "";
    };
  
    for (const part of parts) {
      const items = part.split(",").map(v => stripHTML4(v));
      const clause = items.sort().join(" ").trim();
      if (clause) normalizedClauses.push(clause);
    }
  
    normalizedClauses.sort((a, b) => a.localeCompare(b));
    return normalizedClauses.join(" | ");
  };
  

  // ✅ Filter only active records
  const activeRecords = records.filter(
    (record) => record?.active === true || record?.active === "true"
  );

  activeRecords.forEach((record, index) => {
    if (!record || typeof record !== "object") {
      console.warn(`⚠️ Skipping invalid record at index ${index}`, record);
      return;
    }

    const {
      conditions = "",
      actions = "",
      operator = "",
      events = "",
      performer = "",
    } = record;

    const { set1, set2 } = normalizeConditionParts(conditions);
    const normalizedActions = normalizeActions(actions);
    const normalizedEvents = normalizeEvents(events);
    const normalizedPerformer = normalizeField(performer);
    const normalizedOperator = stripHTML4(operator);

    const key1 = `${set1.join("|")}|${set2.join("|")}|${normalizedActions}|${normalizedOperator}|${normalizedEvents}|${normalizedPerformer}`;
    const key2 = `${set2.join("|")}|${set1.join("|")}|${normalizedActions}|${normalizedOperator}|${normalizedEvents}|${normalizedPerformer}`;

    let groupKey = null;
    if (seenRules.has(key1)) {
      groupKey = key1;
    } else if (seenRules.has(key2)) {
      groupKey = key2;
    }

    if (groupKey) {
      seenRules.get(groupKey).push(record);
    } else {
      seenRules.set(key1, [record]);
    }
  });

  for (const group of seenRules.values()) {
    if (group.length > 1) {
      duplicateGroups.push(group);
    }
  }

  return duplicateGroups;
}

  
  
  
  

  const getCurrentTotalCount = () => {
    if (activeTab === "ticketcreate") {
      if (ruleViewFilter.value === "duplicate_rules" && ticketCreationRuleGroups.length > 0) {
        return flattenGroups(ticketCreationRuleGroups).filter(
          (r) =>
            !searchQuery.trim() ||
            r.name?.toLowerCase().includes(searchQuery.toLowerCase()) ||
            r.description?.toLowerCase().includes(searchQuery.toLowerCase())
        ).length;
      }
      return getFilteredRules(ticketCreationRules).length;
    } else if (activeTab === "ticketupdate") {
      if (ruleViewFilter.value === "duplicate_rules" && ticketUpdateRuleGroups.length > 0) {
        return flattenGroups(ticketUpdateRuleGroups).filter(
          (r) =>
            !searchQuery.trim() ||
            r.name?.toLowerCase().includes(searchQuery.toLowerCase()) ||
            r.description?.toLowerCase().includes(searchQuery.toLowerCase())
        ).length;
      }
      return getFilteredRules(ticketUpdateRules).length;
    } else if (activeTab === "hourly") {
      if (ruleViewFilter.value === "duplicate_rules" && hourlyRuleGroups.length > 0) {
        return flattenGroups(hourlyRuleGroups).filter(
          (r) =>
            !searchQuery.trim() ||
            r.name?.toLowerCase().includes(searchQuery.toLowerCase()) ||
            r.description?.toLowerCase().includes(searchQuery.toLowerCase())
        ).length;
      }
      return getFilteredRules(hourlyTriggerRules).length;
    }
    return 0;
  };


  const renderRulesOrGroups = () => {
    if (loading || isrunning) {
      return (
        <div style={{ display: "flex", justifyContent: "center", alignItems: "center", height: "200px" }}>
          <FwSpinner size="medium" color="green" />
        </div>
      );
    }
  
    // Determine current groups and flatRules based on active tab
    let groups = [];
    let flatRules = [];
    switch (activeTab) {
      case "ticketcreate":
        groups = ticketCreationRuleGroups;
        flatRules = ticketCreationRules;
        break;
      case "ticketupdate":
        groups = ticketUpdateRuleGroups;
        flatRules = ticketUpdateRules;
        break;
      case "hourly":
        groups = hourlyRuleGroups;
        flatRules = hourlyTriggerRules;
        break;
      default:
        break;
    }
  
    // Helper: render AutomationCard wrapped in container div with consistent styling
    const renderRuleCard = (rule, index, isFirstInGroup = true) => (
      <div
        key={rule.id || index}
        className="fw-card-1"
        style={{
          marginBottom: "5px",
          marginTop: "10px",
          padding: "5px 8px",
          marginLeft: 10,
          marginRight: "auto",
        }}
      >
        <AutomationCard
          rule={rule}
          index={index}
          isFirstInGroup={isFirstInGroup}
          onDelete={() => deleteRule(rule, fetchFromApi, getEntityDataForCurrentTab())}
          activeTab={activeTab}
          onSelect={openRuleDetails}
          agent={agent}
        />
      </div>
    );
  
    if (ruleViewFilter.value === "duplicate_rules") { 
      const paginatedGroups = paginateDuplicateGroups(groups, rulesPerPage, searchQuery);
      const pageIndex = currentPage[activeTab] - 1;
      const groupsToShow = paginatedGroups[pageIndex] || [];
  
      // Flatten & filter rules on this page
      const flattenedRulesOnPage = flattenGroups(groupsToShow);
      const filteredRulesOnPage = getFilteredRules(flattenedRulesOnPage);
  
      // Filter groups to only include rules present in filteredRulesOnPage
      const filteredGroupsToShow = groupsToShow
        .map((group) => group.filter((rule) => filteredRulesOnPage.some((f) => f.id === rule.id)))
        .filter((group) => group.length > 0);
  
      if (filteredGroupsToShow.length === 0) {
        return (
          <p className="no-rules-message" style={{ textAlign: "center", marginTop: "20px" }}>
            No Rules Found.
          </p>
        );
      }
  
      if (groups.length === 0) {
        return (
          <p className="no-rules-message" style={{ textAlign: "center", marginTop: "20px" }}>
            No Rules Found.
          </p>
        );
      }
  
      return (
        <div style={{ marginLeft: 10, marginRight: "auto" }}>
          {filteredGroupsToShow.map((group, groupIdx) => (
            <div
              key={`group-${pageIndex}-${groupIdx}`}
              style={{ marginBottom: "12px", boxShadow: "0 4px 8px rgba(0, 0, 0, 0.2)" }}
            >
              {group.map((rule, i) => {
                // Use index + 1 for 1-based indexing as before
                return (
                  <div
                    key={rule.id}
                    className="fw-card-1"
                    style={{
                      marginTop: i === 0 ? "10px" : "2px",
                      padding: "5px 8px",
                      borderRadius: "4px",
                    }}
                  >
                    <AutomationCard
                      rule={rule}
                      index={i + 1}
                      isFirstInGroup={i === 0}
                      onDelete={() => {
                        const entityData = getEntityDataForCurrentTab();
                        deleteRule(rule, fetchFromApi, entityData);
                      }}
                      activeTab={activeTab}
                      onSelect={openRuleDetails}
                      agent={agent}
                    />
                  </div>
                );
              })}
            </div>
          ))}
        </div>
      );
    } else {
      
      const filteredFlatRules = getFilteredRules(flatRules);
  
      if (filteredFlatRules.length === 0) {
        return (
          <p className="no-rules-message" style={{ textAlign: "center", marginTop: "20px" }}>
            No Rules Found.
          </p>
        );
      }
  
      const paginatedFlatRules = pagination(filteredFlatRules, currentPage[activeTab]);
  
      if (paginatedFlatRules.length === 0) {
        return (
          <p className="no-rules-message" style={{ textAlign: "center", marginTop: "20px" }}>
            No Rules Found.
          </p>
        );
      }
  
      const highlightAllDuplicates = highlightDuplicates;
  
      return paginatedFlatRules.map((rule, idx) => {
        const isDuplicate = duplicateGroupsMap.duplicateRuleIds.has(rule.id);
        const isFirstInGroup = duplicateGroupsMap.firstRuleIds.has(rule.id);
  
        if (highlightAllDuplicates && isDuplicate) {
          return renderRuleCard(rule, idx + 1, isFirstInGroup);
        } else {
          return renderRuleCard(rule, idx + 1, true);
        }
      });
    }
  };

  /* Timer state for each tab */
  const [timers, setTimers] = useState({
    ticketcreate: null,
    ticketupdate: null,
    hourly: null,
  });

  const timerIntervals = useRef({
    ticketcreate: null,
    ticketupdate: null,
    hourly: null,
  });
  /* Stored RulesDB data */
  const [storedvalue1, setStoredValue1] = useState(null);
  const [processingStatus, setProcessingStatus] = useState({
    Ticketcreation: false,
    HourlyTriggers: false,
    TicketUpdates: false,
  });

  useEffect(() => {
    let intervalId;
  
    async function fetchStoredValue() {
      try {
        const val = await client.db.get("RulesDB");
        console.log("Rules DB Data :", val);
  
        setStoredValue1(val);
        setProcessingStatus({
          Ticketcreation: val?.creationTotal > 0,
          HourlyTriggers: val?.hourlyTotal > 0,
          TicketUpdates: val?.updateTotal > 0,
        });
  
        if (val.creationTotal === 0 || val.creationTotal == null) {
          if (newRulePloadDB6.current) {
            const createData = await Filterrecords(ticketCreate, newRulePloadDB6.current);
            setTicketCreationRules(createData);
            console.log("Fetched Ticket Creation rules because creationTotal is zero");
          }
        }
  
        if (val.hourlyTotal === 0 || val.hourlyTotal == null) {
          if (newRulePloadDB6.current) {
            const hourlyData = await Filterrecords(hourlyTriggers, newRulePloadDB6.current);
            setHourlyTriggerRules(hourlyData);
            console.log("Fetched Hourly rules because hourlyTotal is zero");
          }
        }
  
        if (val.updateTotal === 0 || val.updateTotal == null) {
          if (newRulePloadDB6.current) {
            const updateData = await Filterrecords(ticketUpdate, newRulePloadDB6.current);
            setTicketUpdateRules(updateData);
            console.log("Fetched Ticket Update rules because updateTotal is zero");
          }
        }
  
        // Only set interval if NOT all totals are zero or null
        if (
          !(
            (val.creationTotal === 0 || val.creationTotal == null) &&
            (val.hourlyTotal === 0 || val.hourlyTotal == null) &&
            (val.updateTotal === 0 || val.updateTotal == null)
          )
        ) {
          if (!intervalId) {
            intervalId = setInterval(fetchStoredValue, 60000);
          }
        } else {
          // All totals zero, so clear interval if exists
          clearInterval(intervalId);
        }
      } catch (error) {
        setStoredValue1(null);
        setProcessingStatus({
          Ticketcreation: false,
          HourlyTriggers: false,
          TicketUpdates: false,
        });
        console.error("Error fetching RulesDB", error);
  
        // On error also clear interval to avoid repeated failing calls
        clearInterval(intervalId);
      }
    }
  
    fetchStoredValue();
  
    // NOTE: At this point, no interval started by default.
    // Interval is conditionally started *inside* fetchStoredValue()
  
    return () => {
      clearInterval(intervalId);
    };
  }, [client]);

  const fetchedAfterTimerEnd = useRef({
    ticketcreate: false,
    ticketupdate: false,
    hourly: false,
  });

  /* Timer function */
  const startTimer = (tabKey, duration) => {
    const now = Date.now();
    localStorage.setItem(`timerStart_${tabKey}`, now.toString());
    localStorage.setItem(`timerDuration_${tabKey}`, duration.toString());

    if (timerIntervals.current[tabKey]) {
      clearInterval(timerIntervals.current[tabKey]);
    }

    setTimers((prev) => ({
      ...prev,
      [tabKey]: duration,
    }));

    timerIntervals.current[tabKey] = setInterval(() => {
      setTimers((prev) => {
        if (!prev[tabKey]) return prev;
        const newTime = prev[tabKey] - 1;
        if (newTime <= 0) {
          clearInterval(timerIntervals.current[tabKey]);
          timerIntervals.current[tabKey] = null;
          return { ...prev, [tabKey]: null };
        }
        return { ...prev, [tabKey]: newTime };
      });
    }, 1000);
  };

  useEffect(() => {
    const restoreTimers = () => {
      ["ticketcreate", "ticketupdate", "hourly"].forEach((tabKey) => {
        const start = localStorage.getItem(`timerStart_${tabKey}`);
        const duration = localStorage.getItem(`timerDuration_${tabKey}`);
        console.log(`[restoreTimers] Read localStorage for ${tabKey}: start=${start}, duration=${duration}`);
        if (start && duration) {
          const elapsed = Math.floor((Date.now() - parseInt(start)) / 1000);
          const remaining = parseInt(duration) - elapsed;
          console.log(`[restoreTimers] Calculated remaining time for ${tabKey}: ${remaining}`);
          if (remaining > 0) {
            startTimer(tabKey, remaining);
          } else {
            setTimers((prev) => ({ ...prev, [tabKey]: null }));
          }
        }
      });
    };

    restoreTimers();

    return () => {
      Object.values(timerIntervals.current).forEach((interval) => {
        if (interval) clearInterval(interval);
      });
    };
  }, []);


  /* Timer End Hook */
  useEffect(() => {
    const fetchDataForTab = async (tabKey) => {
      if (tabKey === "ticketcreate") {
        const data = await Filterrecords(ticketCreate, newRulePloadDB6.current);
        setTicketCreationRules(data);
      } else if (tabKey === "ticketupdate") {
        const data = await Filterrecords(ticketUpdate, newRulePloadDB6.current);
        setTicketUpdateRules(data);
      } else if (tabKey === "hourly") {
        const data = await Filterrecords(hourlyTriggers, newRulePloadDB6.current);
        setHourlyTriggerRules(data);
      }
    };

    Object.entries(timers).forEach(([tabKey, time]) => {
      if (time === null && !fetchedAfterTimerEnd.current[tabKey]) {
        fetchedAfterTimerEnd.current[tabKey] = true;
        fetchDataForTab(tabKey);
      }
      if (time !== null && fetchedAfterTimerEnd.current[tabKey]) {
        fetchedAfterTimerEnd.current[tabKey] = false;
      }
    });
  }, [timers]);


  // const openRuleDetails = (rule) => {
  //   console.log("Complete Rule Log:", rule);
  // };

  const [timerSeconds, setTimerSeconds] = useState({
    ticketcreate: 0,
    ticketupdate: 0,
    hourly: 0,
  });
  const [timerRunning, setTimerRunning] = useState({
    ticketcreate: false,
    ticketupdate: false,
    hourly: false,
  });
  const timerInterval = useRef(null);
  // Load timer state from local storage and start timer if it was running
  useEffect(() => {
    const storedTimerSeconds = localStorage.getItem("timerSeconds");
    if (storedTimerSeconds) {
      setTimerSeconds(JSON.parse(storedTimerSeconds));
    }
    const storedTimerRunning = localStorage.getItem("timerRunning");
    if (storedTimerRunning) {
      const parsedTimerRunning = JSON.parse(storedTimerRunning);
      setTimerRunning(parsedTimerRunning);
      // Start timers for tabs that were running before refresh
      Object.keys(parsedTimerRunning).forEach((tab) => {
        if (parsedTimerRunning[tab]) {
          startTimer(tab);
        }
      });
    }
  }, []);
  // Save timer state to local storage
  useEffect(() => {
    localStorage.setItem("timerSeconds", JSON.stringify(timerSeconds));
  }, [timerSeconds]);
  useEffect(() => {
    localStorage.setItem("timerRunning", JSON.stringify(timerRunning));
  }, [timerRunning]);

  useEffect(() => {
    if (!storedvalue1) return;

    const rulesPerPage = 100;
    const pageTime = 60;
    const overhead = 60;

    console.log("-------------------Ticket Create ------------------");
    const creationPages = Math.ceil(storedvalue1.creationTotal / rulesPerPage);
    console.log("Creation Page Count:", creationPages);

    const creationTime = creationPages * pageTime + overhead;
    console.log("Time-Create (seconds):", creationTime);

    const creationTimeMinutes = creationTime / 60;
    console.log(`Time-Create (minutes): ${creationTimeMinutes.toFixed(2)} mins`);



    console.log("-------------------Hourly Time ------------------");
    // Step 2: Hourly
    const hourlyPages = Math.ceil(storedvalue1.hourlyTotal / rulesPerPage);
    console.log("Hourly Page Count:", hourlyPages);

    const hourlyTime = creationTime + hourlyPages * pageTime + overhead;
    console.log("Time-Hourly (seconds):", hourlyTime);

    const hourlyTimeMinutes = hourlyTime / 60;
    console.log(`Time-Hourly (minutes): ${hourlyTimeMinutes.toFixed(2)} mins`);



    console.log("-------------------Ticket Update Time ------------------");
    const updatePages = Math.ceil(storedvalue1.updateTotal / rulesPerPage);
    console.log("Update Page Count:", updatePages);

    const updateTime = hourlyTime + updatePages * pageTime + overhead;
    console.log("Time-Update (seconds):", updateTime);

    const updateTimeMinutes = updateTime / 60;
    console.log(`Time-Update (minutes): ${updateTimeMinutes.toFixed(2)} mins`);


    if (storedvalue1.creationTotal > 0) {
      startTimer("ticketcreate", creationTime);
    } else {
      setTimers((prev) => ({ ...prev, ticketcreate: null }));
    }

    if (storedvalue1.hourlyTotal > 0) {
      startTimer("hourly", hourlyTime);
    } else {
      setTimers((prev) => ({ ...prev, hourly: null }));
    }

    if (storedvalue1.updateTotal > 0) {
      startTimer("ticketupdate", updateTime);
    } else {
      setTimers((prev) => ({ ...prev, ticketupdate: null }));
    }

    return () => {
      Object.values(timerIntervals.current).forEach((interval) => {
        if (interval) clearInterval(interval);
      });
    };
  }, [storedvalue1]);



  const renderTimerMessage = (tabKey) => {
    if (!timers[tabKey]) return null;

    return (
      <div
        style={{
          position: "fixed",
          top: "50%",
          left: "50%",
          width: "60%",
          transform: "translate(-75%, -50%)",
          backgroundColor: "transparent",
          color: "black",
          zIndex: 9999,
          userSelect: "none",
          fontSize: "16px",
          fontFamily: "sans-serif",
          display: "flex",
          flexDirection: "column", // Stack vertically
          alignItems: "center",
          whiteSpace: "normal", // allow wrapping if needed
          textAlign: "center",
        }}
      >
        <div>
          The app is currently processing the data. Please refresh the page or revisit the app after (
          <strong>{timers[tabKey]} sec </strong>) seconds.
        </div>
        <FwSpinner size="small" color="green" style={{ marginTop: "8px" }} />
      </div>
    );
  };

  const deleteFromEntityIfMatched = async (list, rule) => {
    const matchedEntityRule = list.find(item => item.rule_id === rule.id);
    if (matchedEntityRule) {
      console.log("Matched entity rule for deletion:", matchedEntityRule);
      console.log("Matched entity rule display id:", matchedEntityRule.display_id);
      try {
        await newRulePloadDB6.current.delete(matchedEntityRule.display_id);
        console.log("Deleted from Entity");
      } catch (err) {
        console.error("Error deleting from entity:", err);
      }
    } else {
      console.log("No matching entity rule found with rule_id:", rule.id);
    }
  };

  const deleteRule = async (rule, allRulesList, isRecentData, entityDataForTab) => {
    const { id } = rule;
    // const matchedRecord = allRulesList.find((rec) => rec.id === id);
    // console.log("Matched ID :", matchedRecord);
    let automationTypeId;
    let currentRules,
      setRulesFunc,
      groupSetterFunc,
      currentTabPage,
      tabKey;

    // console.log("Delete Triggered :", rule);

    switch (activeTab) {
      case "ticketcreate":
        automationTypeId = ticketCreate;
        currentRules = ticketCreationRules;
        setRulesFunc = setTicketCreationRules;
        groupSetterFunc = setTicketCreationRuleGroups;
        currentTabPage = currentPage.ticketcreate;
        tabKey = "ticketcreate";
        break;
      case "ticketupdate":
        automationTypeId = ticketUpdate;
        currentRules = ticketUpdateRules;
        setRulesFunc = setTicketUpdateRules;
        groupSetterFunc = setTicketUpdateRuleGroups;
        currentTabPage = currentPage.ticketupdate;
        tabKey = "ticketupdate";
        break;
      case "hourly":
        automationTypeId = hourlyTriggers;
        currentRules = hourlyTriggerRules;
        setRulesFunc = setHourlyTriggerRules;
        groupSetterFunc = setHourlyRuleGroups;
        currentTabPage = currentPage.hourly;
        tabKey = "hourly";
        break;
      default:
        return;
    }




    const targetDisplayId = rule.display_id;
    if (targetDisplayId && newRulePloadDB6.current) {
      try {
        await newRulePloadDB6.current.delete(targetDisplayId);
        console.log("Deleted From Entity");
      } catch (err) { }
    }

    // if (fetchFromApi) {
    //   console.log(`Deleting from Recent Data mode. Entity data for tab :`);
    //   if (activeTab === "ticketcreate") {
    //     const data = await Filterrecords(ticketCreate, newRulePloadDB6.current);
      
        
    //     const matchedEntityRule = data.find(item => item.rule_id === rule.id);
    //     if (matchedEntityRule) {
    //       console.log("Matched entity rule for deletion:", matchedEntityRule);
    //       console.log("Matched entity rule for deletion id :", matchedEntityRule.display_id);

    //       try {
    //         await newRulePloadDB6.current.delete(matchedEntityRule.display_id);
    //         console.log("Deleted From Entity");
    //       } catch (err) { }

    //     } else {
    //       console.log("No matching entity rule found with rule_id:", rule.id);
    //     }
        
        
    //   } else if (activeTab === "ticketupdate") {
    //     const data = await Filterrecords(ticketUpdate, newRulePloadDB6.current);
        
    //     const matchedEntityRule = data.find(item => item.rule_id === rule.id);
    //     if (matchedEntityRule) {
    //       console.log("Matched entity rule for deletion:", matchedEntityRule);
    //       console.log("Matched entity rule for deletion id :", matchedEntityRule.display_id);
    //     } else {
    //       console.log("No matching entity rule found with rule_id:", rule.id);
    //     }
        
        
    //   } else if (activeTab === "hourly") {
    //     const data = await Filterrecords(hourlyTriggers, newRulePloadDB6.current);
        
    //     const matchedEntityRule = data.find(item => item.rule_id === rule.id);
    //     if (matchedEntityRule) {
    //       console.log("Matched entity rule for deletion:", matchedEntityRule);
    //       console.log("Matched entity rule for deletion id :", matchedEntityRule.display_id);
    //     } else {
    //       console.log("No matching entity rule found with rule_id:", rule.id);
    //     }
        
        
    //   }
    // }

    if (fetchFromApi) {
      let data;
      if (activeTab === "ticketcreate") {
        data = await Filterrecords(ticketCreate, newRulePloadDB6.current);
      } else if (activeTab === "ticketupdate") {
        data = await Filterrecords(ticketUpdate, newRulePloadDB6.current);
      } else if (activeTab === "hourly") {
        data = await Filterrecords(hourlyTriggers, newRulePloadDB6.current);
      }
      if (data) {
        await deleteFromEntityIfMatched(data, rule);
      }
    }

    try {
      const response = await client.request.invokeTemplate("deleterule", {
        context: {
          automationid: automationTypeId,
          ruleid: id,
        },
      });
      if (response.status === 204) {
        console.log("Deleted From api too.")
        // Remove deleted rule from the current flat rules list
        const updatedRules = currentRules.filter((r) => r.id !== id);
        setRulesFunc(updatedRules);
        if (ruleViewFilter.value === "duplicate_rules") {
          // Recalculate duplicate groups with updated rules after deletion
          const updatedGroups = groupDuplicates(updatedRules)
            .filter((g) => g.length > 1)
            // Optional: sort largest groups first or as you prefer
            .sort((a, b) => b.length - a.length);
          groupSetterFunc(updatedGroups);
          // Flatten the updated groups to find rules on current page
          const flattenUpdatedGroups = flattenGroups(updatedGroups);
          const filteredRules = getFilteredRules(flattenUpdatedGroups);
          const paginated = pagination(filteredRules, currentTabPage);
          // If current page empty and not first page, shift current page back
          if (paginated.length === 0 && currentTabPage > 1) {
            setCurrentPage((prev) => ({ ...prev, [tabKey]: Math.max(1, prev[tabKey] - 1) }));
          }
        } else {
          // In "all_rules" mode or others, just clear groups cache (optional)
          groupSetterFunc([]);
          const filteredRules = getFilteredRules(updatedRules);
          const paginated = pagination(filteredRules, currentTabPage);
          if (paginated.length === 0 && currentTabPage > 1) {
            setCurrentPage((prev) => ({ ...prev, [tabKey]: Math.max(1, prev[tabKey] - 1) }));
          }
        }
        toast.current.trigger({ type: "success", content: "Rule deleted successfully!" });
      } else {
        toast.current.trigger({ type: "error", content: "Failed to delete rule." });
      }


    } catch (error) {
      console.log(error);
      toast.current.trigger({ type: "error", content: "Error deleting rule." });
    }

  };

  const openRuleDetails = async (rule) => {
    if (!fetchFromApi) {    
      console.log("fetchFromApi is false");
      console.log("Checking if the rule is in api");
      console.log("Clicked Rule ID :", rule.id);
      console.log("Clicked Rule Automation Type ID :", rule.automation_type_id);
      console.log("Clicked Rule Display ID :", rule.display_id);
      // correctly working
  
      try {
        // Call the API to fetch the rule details using automation_type_id and rule id
        const response = await client.request.invokeTemplate("getid", {
          context: {
            automationid: rule.automation_type_id,
            ruleid: rule.id
          },
        });
  
        // Log the formatted JSON rule details
        console.log("Yes it is in Instance. Formatted JSON output:");
        console.log(response);
  
      } catch (error) {
        console.error("Error fetching rule details:", error);
  
        const status = error.status || error.response?.status || error.statusCode || null;
        console.log("Detected status:", status);
  
        if (status === 404) {
          console.log("Moving to delete rule from entity.");
          toast.current.trigger({ type: "error", content: "Rule not found. Try refreshing the page." });
          if (rule.display_id && newRulePloadDB6.current) {
            try {
              await newRulePloadDB6.current.delete(rule.display_id);
              console.log("Deleted from local entity store due to 404.");
            } catch (err) {
              console.error("Failed to delete from entity store:", err);
            }
          }
        }
      }
    } else {
      console.log("This is Recent Data inthis it will never work.");
    }

  };

  // const handleFilterApiClick = () => {



  //   const logGroups = (label, groups) => {
  //     const totalRulesCount = groups.reduce((acc, group) => acc + group.length, 0);
  //     console.log(
  //       `${label} (${groups.length} groups, ${totalRulesCount} total rules):`,
  //       groups
  //     );
  //   };
  
  //   if (activeTab === "ticketcreate") {
  //     const duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
  
  //     logGroups("Duplicate groups for Ticket Creation", duplicateGroups);
  
  //     setTicketCreationRuleGroups(duplicateGroups);
  //     setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
  //   } else if (activeTab === "ticketupdate") {
  //     const duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
  
  //     logGroups("Duplicate groups for Ticket Update", duplicateGroups);
  
  //     setTicketUpdateRuleGroups(duplicateGroups);
  //     setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
  //   } else if (activeTab === "hourly") {
  //     const duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
  
  //     logGroups("Duplicate groups for Hourly", duplicateGroups);
  
  //     setHourlyRuleGroups(duplicateGroups);
  //     setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
  //   }
  // };


  const handleFilterApiClick = () => {
    console.log(`handleFilterApiClick triggered for activeTab: ${activeTab}, fetchFromApi: ${fetchFromApi}`);
  
    const logGroups = (label, groups) => {
      const totalRulesCount = groups.reduce((acc, group) => acc + group.length, 0);
      console.log(
        `${label} (${groups.length} groups, ${totalRulesCount} total rules):`,
        groups
      );
    };
  
    if (fetchFromApi) {
      // Data is from API mode
      console.log(`Using recent API data for tab: ${activeTab}`);
      if (activeTab === "ticketcreate") {
        const duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
        logGroups("Duplicate groups for Ticket Creation", duplicateGroups);
        setTicketCreationRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
      } else if (activeTab === "ticketupdate") {
        const duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
        logGroups("Duplicate groups for Ticket Update", duplicateGroups);
        setTicketUpdateRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
      } else if (activeTab === "hourly") {
        const duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
        logGroups("Duplicate groups for Hourly", duplicateGroups);
        setHourlyRuleGroups(duplicateGroups);
        setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
      }
    } else {
      // Data is from entity (local DB) mode
      console.log(`Using entity data for tab: ${activeTab}`);
      // if (activeTab === "ticketcreate") {
      //   const duplicateGroups = findAndGroupExactDuplicates(ticketCreationRules);
      //   logGroups("Duplicate groups for Ticket Creation (Entity)", duplicateGroups);
      //   setTicketCreationRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, ticketcreate: 1 }));
      // } else if (activeTab === "ticketupdate") {
      //   const duplicateGroups = findAndGroupExactDuplicates(ticketUpdateRules);
      //   logGroups("Duplicate groups for Ticket Update (Entity)", duplicateGroups);
      //   setTicketUpdateRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, ticketupdate: 1 }));
      // } else if (activeTab === "hourly") {
      //   const duplicateGroups = findAndGroupExactDuplicates(hourlyTriggerRules);
      //   logGroups("Duplicate groups for Hourly (Entity)", duplicateGroups);
      //   setHourlyRuleGroups(duplicateGroups);
      //   setCurrentPage((prev) => ({ ...prev, hourly: 1 }));
      // }
    }
  };


const getPaginatedItemCount = () => {
    let rules = [];
    if (activeTab === "ticketcreate") rules = ticketCreationRules;
    else if (activeTab === "ticketupdate") rules = ticketUpdateRules;
    else if (activeTab === "hourly") rules = hourlyTriggerRules;

    let groups = [];
    if (activeTab === "ticketcreate") groups = ticketCreationRuleGroups;
    else if (activeTab === "ticketupdate") groups = ticketUpdateRuleGroups;
    else if (activeTab === "hourly") groups = hourlyRuleGroups;

    if (ruleViewFilter.value === "duplicate_rules" && groups.length > 0) {
      const flatList = flattenGroups(groups);
      const filtered = getFilteredRules(flatList);
      const paginated = pagination(filtered, currentPage[activeTab]);
      return paginated.length;
    } else {
      const flatList = rules;
      const filtered = getFilteredRules(flatList);
      const paginated = pagination(filtered, currentPage[activeTab]);
      // console.log("Paginated Item Count");
      // console.log(paginated);
      return paginated.length;
    }
  };

  useEffect(() => {
    setSearchTerm("");
    setSearchQuery("");
    setCurrentPage((prev) => ({ ...prev, [activeTab]: 1 }));
  }, [activeTab]);

  useEffect(() => {
    const fwTabs = document.querySelector("fw-tabs");

    const saveActiveTab = async (e) => {
      const newActiveTab = e.target.panel;
      setActiveTab(newActiveTab);

      try {
        let tabData = (await client.db.get("TabDB")) || {};
        tabData.LastVisitedTab = newActiveTab;
        await client.db.set("TabDB", tabData);
      } catch (error) { }
    };

    if (fwTabs) {
      fwTabs.addEventListener("fwChange", saveActiveTab);
    }

    return () => {
      if (fwTabs) {
        fwTabs.removeEventListener("fwChange", saveActiveTab);
      }
    };
  }, [client]);

  const [useCustomPagination, setUseCustomPagination] = useState(true);
  const [isrunning, setIsrunning] = useState(false);

  const CustomPagination = ({ currentPage, itemsPerPage, totalItems, onPageChange }) => {
    const [isLoading, setIsLoading] = useState(false);

    const totalPages = Math.ceil(totalItems / itemsPerPage);
    const hasMorePages = totalPages > 0;

    const startItem = getCumulativeStartItem(totalItems);
    const endItem = getCurrentPageItemCount(totalItems);


    if (!totalItems || totalItems <= 0) {
      // Don't render pagination if no items exist
      return null;
    }



    const handlePageChangeWithDelay = (page) => {
      setIsrunning(true);
      setTimeout(() => {
        onPageChange(page);
        setIsrunning(false);
      }, 1000); // 1 second delay
    };

    const handlePrevious = () => {
      if (currentPage > 1) {
        handlePageChangeWithDelay(currentPage - 1);
      }
    };

    const handleNext = () => {
      if (currentPage < totalPages) {
        handlePageChangeWithDelay(currentPage + 1);
      }
    };

    const handlePaginationClick = (page) => {
      if (page === currentPage) return;  // Do nothing if clicked page is active page
      handlePageChangeWithDelay(page);
    };

    const renderPageNumbers = () => {
      const pageNumbers = [];
      const maxVisiblePages = 5;
      const ellipsis = <span style={{ margin: '0 5px', color: '#888' }}>…</span>;

      const addPageNumber = (page) => {
        pageNumbers.push(
          <button
            key={page}
            onClick={() => handlePaginationClick(page)}
            style={{
              cursor: page === currentPage ? 'default' : 'pointer',
              margin: '0 2px',
              padding: '8px',
              border: '1px solid #ccc',
              borderRadius: '4px',
              width: '40px',
              backgroundColor: page === currentPage ? 'white' : 'transparent',
              color: '#333',
              boxShadow: page === currentPage ? '0 0 5px rgba(51, 102, 255, 0.5)' : 'none',
              pointerEvents: page === currentPage ? 'none' : 'auto',
            }}
          >
            {page}
          </button>
        );
      };

      if (totalPages <= maxVisiblePages) {
        for (let i = 1; i <= totalPages; i++) {
          addPageNumber(i);
        }
      } else {
        let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
        let endPage = Math.min(totalPages, currentPage + Math.floor(maxVisiblePages / 2));

        if (endPage - startPage + 1 < maxVisiblePages) {
          if (startPage === 1) {
            endPage = Math.min(totalPages, maxVisiblePages);
          } else if (endPage === totalPages) {
            startPage = Math.max(1, totalPages - maxVisiblePages + 1);
          }
        }

        addPageNumber(1);

        if (startPage > 2) {
          pageNumbers.push(ellipsis);
        }

        for (let i = startPage; i <= endPage; i++) {
          if (i !== 1 && i !== totalPages) {
            addPageNumber(i);
          }
        }

        if (endPage < totalPages - 1) {
          pageNumbers.push(ellipsis);
        }

        addPageNumber(totalPages);
      }

      return pageNumbers;
    };

    return (
      <div style={{ position: 'relative', width: '100%', minHeight: '80px' }}>
        { }
        {!isrunning && (
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '10px' }}>
            <button
              onClick={handlePrevious}
              disabled={currentPage === 1 || !hasMorePages}
              style={{
                padding: '8px',
                cursor: 'pointer',
                border: '1px solid #ccc',
                borderRadius: '4px',
                backgroundColor: '#f0f0f0',
                color: '#333',
                marginRight: '5px',
                opacity: currentPage === 1 || !hasMorePages ? 0.5 : 1,
              }}
            >
              &lt;&lt;
            </button>
            {renderPageNumbers()}
            <button
              onClick={handleNext}
              disabled={currentPage === totalPages || !hasMorePages}
              style={{
                padding: '8px',
                cursor: 'pointer',
                border: '1px solid #ccc',
                borderRadius: '4px',
                backgroundColor: '#f0f0f0',
                color: '#333',
                marginLeft: '5px',
                opacity: currentPage === totalPages || !hasMorePages ? 0.5 : 1,
              }}
            >
              &gt;&gt;
            </button>
            <div style={{ marginLeft: '20px' }}>
              Showing {startItem} - {endItem} of {totalItems} rules
            </div>
          </div>
        )}
      </div>
    );
  };

  const getCumulativeStartItem = (totalItems) => {
    if (ruleViewFilter.value !== "duplicate_rules") {
      const calculatedStart = (currentPage[activeTab] - 1) * rulesPerPage + 1;
      return Math.min(Math.max(calculatedStart, 1), totalItems === 0 ? 0 : totalItems);
    }
  
    let groups = [];
  
    if (activeTab === "ticketcreate") groups = ticketCreationRuleGroups;
    else if (activeTab === "ticketupdate") groups = ticketUpdateRuleGroups;
    else if (activeTab === "hourly") groups = hourlyRuleGroups;
  
    const paginatedGroups = paginateDuplicateGroups(groups, rulesPerPage, searchQuery);
    let pageIndex = currentPage[activeTab] - 1;
    pageIndex = Math.max(0, Math.min(pageIndex, paginatedGroups.length - 1));
  
    let startItem = 1;
  
    for (let i = 0; i < pageIndex; i++) {
      const groupsToShow = paginatedGroups[i];
      if (groupsToShow && groupsToShow.length > 0) {
        startItem += flattenGroups(groupsToShow).length;
      }
    }
  
    return Math.min(startItem, totalItems === 0 ? 0 : totalItems);
  };

  const getCurrentPageItemCount = (totalItems) => {
    if (ruleViewFilter.value !== "duplicate_rules") {
      const calculatedEnd = currentPage[activeTab] * rulesPerPage;
      return Math.min(calculatedEnd, totalItems);
    }
  
    let groups = [];
  
    if (activeTab === "ticketcreate") groups = ticketCreationRuleGroups;
    else if (activeTab === "ticketupdate") groups = ticketUpdateRuleGroups;
    else if (activeTab === "hourly") groups = hourlyRuleGroups;
  
    const paginatedGroups = paginateDuplicateGroups(groups, rulesPerPage, searchQuery);
    let pageIndex = currentPage[activeTab] - 1;
    pageIndex = Math.max(0, Math.min(pageIndex, paginatedGroups.length - 1));
  
    let cumulativeCount = 0;
  
    for (let i = 0; i <= pageIndex; i++) {
      const groupsToShow = paginatedGroups[i];
      if (groupsToShow && groupsToShow.length > 0) {
        cumulativeCount += flattenGroups(groupsToShow).length;
      }
    }
    return Math.min(cumulativeCount, totalItems === 0 ? 0 : totalItems);
  };

  const getPaginationTotalCount = () => {
    if (ruleViewFilter.value === "duplicate_rules") {
      let groups = [];
      if (activeTab === "ticketcreate") groups = ticketCreationRuleGroups;
      else if (activeTab === "ticketupdate") groups = ticketUpdateRuleGroups;
      else if (activeTab === "hourly") groups = hourlyRuleGroups;
  
      // Flatten all groups first
      const flatRules = flattenGroups(groups);
  
      // Apply the same filter used in rendering
      const filteredRules = getFilteredRules(flatRules);
  
      return filteredRules.length;
    } else {
      return getCurrentTotalCount();
    }
  };

  
  const paginateGroup = (group, itemsPerPage, currentPage) => {
    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = Math.min(startIndex + itemsPerPage, group.length);
    return group.slice(startIndex, endIndex);
  };
  
  const paginateGroups = (groups, itemsPerPage, currentPage) => {        
    let allItems = [];
    for (const group of groups) {
      allItems = allItems.concat(group);
    }
    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = Math.min(startIndex + itemsPerPage, allItems.length);
    const pageItems = allItems.slice(startIndex, endIndex);
    // Reconstruct the page based on the original group structure
    const pageGroups = [];
    let currentIndex = 0;
    for (const group of groups) {
      let groupIndex = 0;
      while (groupIndex < group.length && pageItems.includes(group[groupIndex])) {
        if (!pageGroups[pageGroups.length - 1] || pageGroups[pageGroups.length - 1].length >= itemsPerPage) {
          pageGroups.push([]);
        }
        pageGroups[pageGroups.length - 1].push(group[groupIndex]);
        groupIndex++;
      }
      currentIndex += group.length;
    }
    return pageItems;
  };

  const handlePageChange = (tab) => {
    return (newPage) => {
      setCurrentPage((prev) => {
        let newPageValue = newPage;
        const totalPages = Math.ceil(getPaginationTotalCount() / rulesPerPage);
        const currentPageItemCount = getPaginatedItemCount();

        if (newPage > totalPages && totalPages > 0) {
          newPageValue = Math.max(1, totalPages); // Go back to the last available page
        } else if (currentPageItemCount === 0 && newPage > 1) {
          newPageValue = Math.max(1, newPage - 1);
        }
        return {
          ...prev,
          [tab]: newPageValue,
        };
      });
    };
  };

  const getEntityDataForCurrentTab = () => {

    if (fetchFromApi) {
      if (activeTab === "ticketcreate") return recentDataCache.ticketcreate;
      if (activeTab === "ticketupdate") return recentDataCache.ticketupdate;
      if (activeTab === "hourly") return recentDataCache.hourly;
    }
    
    if (activeTab === "ticketcreate") return ticketCreationRules;
    if (activeTab === "ticketupdate") return ticketUpdateRules;
    if (activeTab === "hourly") return hourlyTriggerRules;
    return null;

  };

  const fetchData = async () => {
    setSearchTerm("");
    setSearchQuery("");
    setCurrentPage((prev) => ({ ...prev, [activeTab]: 1 }));

    setFetchFromApi((prev) => !prev);

    toast.current.trigger({
      type: "info",
      content: `${fetchFromApi ? "Going Back" : "Fetching Recent Data"}...`,
    });
  };

  const checkAndSetButtonState = async () => {
    try {
      const storedvalue1 = await client.db.get("RulesDB");
      console.log("Rules Database :", storedvalue1);
      
    const isButtonEnabled = (storedvalue1?.updateTotal === 0 || storedvalue1?.updateTotal == null);

      if (isButtonEnabled) {
        setIsRulesDBReady(true);
        setLoadingBannerVisible(false);

        if (intervalIdRef.current) {
          clearInterval(intervalIdRef.current);
          intervalIdRef.current = null;
        }
      } else {
        setIsRulesDBReady(false);
        setLoadingBannerVisible(true);
        if (!intervalIdRef.current) {
          intervalIdRef.current = setInterval(checkAndSetButtonState, 60000);
        }
      }
    } catch (error) {
      if (error.status === 404) {
        setIsRulesDBReady(false);
        setLoadingBannerVisible(true);
        if (intervalIdRef.current) {
          clearInterval(intervalIdRef.current);
          intervalIdRef.current = null;
        }
      }
    }
  };

  useEffect(() => {
    checkAndSetButtonState();
    return () => {
      if (intervalIdRef.current) clearInterval(intervalIdRef.current);
    };
  }, []);

  const ruleViewPopoverRef = useRef(null);

  const triggerButtonRef = useRef(null);

  const [isPopoverOpen, setIsPopoverOpen] = useState(false);

  const searchInputs = (
    <div
      style={{
        display: "flex",
        alignItems: "center",
        marginBottom: 10,
        marginLeft: 20,
        marginTop: 15,
        maxWidth: "100%",
        gap: "20px",
      }}
    >


<div style={{ flexShrink: 0 }}>
  <FwPopover
    sameWidth="false"
    placement="bottom-start"
  >
    <FwButton
      slot="popover-trigger"
      color="secondary"
      showCaretIcon
      ref={triggerButtonRef}
    >
      <FwIcon slot="before-label" name={ruleViewFilter.graphicsProps.name} />
      <span>{ruleViewFilter.text}</span>
    </FwButton>

    <div slot="popover-content" style={{ width: 220 }}>
      <span
        style={{ fontStyle: "italic" }}
        className="row fw-flex fw-type-xs fw-p-4 fw-type-semibold"
      >
        Select Rule View
      </span>
      <hr style={{ margin: 0 }} />
      <FwListOptions
  onFwChange={(event) => {
    const selected = event.detail?.meta?.selectedOptions[0];
    if (selected) {
      setRuleViewFilter(selected);
      setCurrentPage((prev) => ({ ...prev, [activeTab]: 1 }));

      if (selected.value === "all_rules") {
        setTicketCreationRuleGroups([]);
        setTicketUpdateRuleGroups([]);
        setHourlyRuleGroups([]);
      } else if (selected.value === "duplicate_rules") {
        handleFilterApiClick();
      }      
    }
  }}
  selectedOptions={[ruleViewFilter]}
  options={ruleViewOptions}
  variant="icon"
/>

    </div>
  </FwPopover>
</div>

      <div style={{ flex: 1, display: "flex", justifyContent: "center", marginTop: 20 }}>
        <fw-input
          // clear-input
          ref={useRef(null)}
          icon-left="search"
          hint-text="Type Keyword to Search"
          placeholder="Enter a Keyword to Search..."
          warning-text="Please Enter a Keyword to Search..."
          state={inputState}
          style={{
            width: "400px",
            height: "60px",
            fontSize: "18px",
          }}
          value={searchTerm}
          onInput={(e) => {
            const val = e.target.value;
            if (val.length < searchTerm.length) {
              setSearchQuery("");
            }
            setSearchTerm(val);
            if (showSearchHint) setShowSearchHint(false);
            if (inputState !== "normal") setInputState("normal");
            if (warningTimerRef.current) {
              clearTimeout(warningTimerRef.current);
              warningTimerRef.current = null;
            }
          }}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              const trimmed = e.target.value.trim();
              if (!trimmed) {
                setSearchQuery("");
                setShowSearchHint(false);
                setInputState("warning");

                warningTimerRef.current = setTimeout(() => {
                  setInputState("normal");
                  warningTimerRef.current = null;
                }, 3000);
              } else {
                setSearchQuery(trimmed);
                setShowSearchHint(false);
                setInputState("normal");
              }
              setCurrentPage((prev) => ({ ...prev, [activeTab]: 1 }));
            }
          }}
          fwInputClear={() => {
            setSearchTerm("");
            setSearchQuery("");
            setCurrentPage((prev) => ({ ...prev, [activeTab]: 1 }));
            setInputState("normal");

            if (warningTimerRef.current) {
              clearTimeout(warningTimerRef.current);
              warningTimerRef.current = null;
            }
          }}
        />
      </div>

      <div style={{ flexShrink: 0 }}>
        <FwButton color="primary" onFwClick={() => { }}>
          <fw-icon name="plus" size="16" style={{ marginRight: "8px" }}></fw-icon>
          Add New Rule
        </FwButton>
      </div>
    </div>
  );

  return (
    <>
      {errorMessage ? (
        <div
          style={{
            position: "fixed",
            top: 0,
            left: 0,
            width: "100vw",
            height: "100vh",
            display: "flex",
            justifyContent: "center",
            alignItems: "center",
            backgroundColor: "rgba(255, 255, 255, 0.8)",
            zIndex: 9999,
          }}
        >
          <div
            style={{
              color: "red",
              fontSize: "2rem",
              fontWeight: "bold",
              textAlign: "center",
              padding: "20px",
              backgroundColor: "white",
            }}
          >
            {errorMessage}
          </div>
        </div>
      ) : (
        <>
          <h2>Automations - Rules</h2>

          {showSearchHint && (
            <p style={{ color: "red", marginTop: "4px", fontSize: "0.9em" }}>
              Please enter a search term before searching.
            </p>
          )}

          {loadingBannerVisible && !isRulesDBReady && (
            <div
              style={{
                justifyContent: "center",
                alignItems: "center",
                height: "40px",
                width: "50%",
                margin: "0 auto",
              }}
            >

            </div>
          )}

          {tabsInitialized && (
            <div style={{ width: "60%", marginRight: "auto" }}>
              <div
                style={{
                  display: "flex",
                  justifyContent: fetchFromApi ? "flex-start" : "flex-end",
                  marginBottom: 15,
                }}
              >
                <FwButton color="secondary" onFwClick={fetchData} disabled={!isRulesDBReady}>
                  {fetchFromApi ? (
                    <>
                      <FwIcon
                        slot="before-label"
                        name="arrow-left"
                        size={16}
                        style={{ marginRight: "8px" }}
                      />
                      Back
                    </>
                  ) : (
                    <>
                      Get Recent Data
                      <FwIcon
                        slot="after-label"
                        name="refresh"
                        size={16}
                        style={{ marginLeft: "8px" }}
                      />
                    </>
                  )}
                </FwButton>
              </div>

              <FwTabs activeTab={activeTab}>
  <FwTab slot="tab" panel="ticketcreate" onClick={() => setActiveTab("ticketcreate")}>
    Ticket Creation
  </FwTab>
  <FwTab slot="tab" panel="ticketupdate" onClick={() => setActiveTab("ticketupdate")}>
    Ticket Updates
  </FwTab>
  <FwTab slot="tab" panel="hourly" onClick={() => setActiveTab("hourly")}>
    Hourly Triggers
  </FwTab>

  <FwTabPanel name="ticketcreate">
    {searchInputs}

    {timers.ticketcreate ? (
      renderTimerMessage("ticketcreate")
    ) : (
      <>
        {renderRulesOrGroups()}
        {showPagination && getPaginatedItemCount() > 0 && (
          <div style={{ marginTop: 10 }}>
            <CustomPagination
              currentPage={currentPage.ticketcreate}
              itemsPerPage={rulesPerPage}
              totalItems={getPaginationTotalCount()}
              onPageChange={handlePageChange("ticketcreate")}
            />
          </div>
        )}
      </>
    )}
  </FwTabPanel>

  <FwTabPanel name="ticketupdate">
    {searchInputs}

    {timers.ticketupdate ? (
      renderTimerMessage("ticketupdate")
    ) : (
      <>
        {renderRulesOrGroups()}
        {showPagination && getPaginatedItemCount() > 0 && (
          <div style={{ marginTop: 10 }}>
            <CustomPagination
              currentPage={currentPage.ticketupdate}
              itemsPerPage={rulesPerPage}
              totalItems={getPaginationTotalCount()}
              onPageChange={handlePageChange("ticketupdate")}
            />
          </div>
        )}
      </>
    )}
  </FwTabPanel>

  <FwTabPanel name="hourly">
    {searchInputs}

    {timers.hourly ? (
      renderTimerMessage("hourly")
    ) : (
      <>
        {renderRulesOrGroups()}
        {showPagination && getPaginatedItemCount() > 0 && (
          <div style={{ marginTop: 10 }}>
            <CustomPagination
              currentPage={currentPage.hourly}
              itemsPerPage={rulesPerPage}
              totalItems={getPaginationTotalCount()}
              onPageChange={handlePageChange("hourly")}
            />
          </div>
        )}
      </>
    )}
  </FwTabPanel>
</FwTabs>
           </div>
          )}
        </>
      )}

      <FwToast />
    </>
  );

};

export default AutomationTabs;