init();

async function init() {
  console.log("Initializing app...");
  await new Promise((resolve) => setTimeout(resolve, 100)); 
  window.client = await app.initialized();

  client.events.on("app.activated", function () {
    console.log(" App activated! Calling RoleAccess...");
    setTimeout(async () => {
      await RoleAccess();
    }, 300);
  });
}
const duplicates = [];
const type1 = 0;
const type3 = 0;
const type4 = 0;
const automationTypeIdOneRecords = [];
const automationTypeIdfourRecords = [];
const automationTypeIdthreeRecords = [];
const duplicatesType1 = [];
const duplicatesType3 = [];
const duplicatesType4 = [];
const sessionTabStore = {};
 
  async function setupTabListener(tabContainerId, sharedKey) {
      while (typeof client === "undefined") {
          console.warn("⚠️ Waiting for 'client' to be ready...");
          await new Promise((resolve) => setTimeout(resolve, 500));
      }
  
      const fwTabs = document.querySelector(`#${tabContainerId} fw-tabs`);
  
      if (!fwTabs) {
          console.error(`❌ ERROR: <fw-tabs> NOT found inside #${tabContainerId}!`);
          return;
      }
  
      console.log(`✅ Found <fw-tabs> inside #${tabContainerId}. Attaching event listener...`);
      

      const savedTab = sessionTabStore[sharedKey] || "Ticket Creation";
  
      const tabElement = fwTabs.querySelector(`fw-tab[panel='${savedTab}']`);
      const pageContainer = document.getElementById(tabContainerId);
  
      if (tabElement) {
          if (pageContainer.style.display !== "none") {
              console.log(`✅ Restoring tab: ${savedTab}`);
               
              tabElement.click();
             
          } else {
              console.warn(`⚠️ Page #${tabContainerId} hidden. Waiting to restore tab:`, savedTab);
  
              const observer = new MutationObserver((mutationsList, observer) => {
                  for (const mutation of mutationsList) {
                      if (mutation.attributeName === "style" && pageContainer.style.display !== "none") {
                          console.log(`✅ Page visible now. Restoring tab:`, savedTab);
                          tabElement.click();
                          observer.disconnect();
                      }
                  }
              });
  
              observer.observe(pageContainer, { attributes: true });
          }
      } else {
          console.warn(`⚠️ Saved tab not found in DOM:`, savedTab);
      }
  
      fwTabs.addEventListener("fwChange", (event) => {
          const tabIndex = event.detail.tabIndex;
         const tabs = fwTabs.querySelectorAll("fw-tab");
  
          if (tabs[tabIndex]) {
            window.activeTab = tabs[tabIndex].getAttribute("panel");
            
              console.log(`🟢 Active tab changed to: ${activeTab}`);
              sessionTabStore[sharedKey] = activeTab; 
        
          } else {
              console.warn(`No active tab found at index ${tabIndex}`);
          }
      });
  }
  

  document.addEventListener("DOMContentLoaded", async () => {
    console.log("📌 Page Loaded! Restoring last visited tab (from memory)...");
    await setupTabListener("Automation-page", "LastVisitedTab");
  });
  
document.addEventListener("DOMContentLoaded", function () {
  const progressBar = document.getElementById("progress-container");

  if (progressBar) {
    
      progressBar.style.transition = "width 0.2s linear, opacity 0.3s"; 
      progressBar.style.width = "0%"; 
      progressBar.style.height = "3px"; 
    
      progressBar.style.opacity = "0";

      progressBar.start = function () {
          progressBar.style.width = "70%"; 
          progressBar.style.opacity = "1";
      };

      progressBar.done = function () {
          progressBar.style.width = "100%";
          setTimeout(() => {
              progressBar.style.width = "0%"; 
              progressBar.style.opacity = "0";
          }, 1000); 
      };
  } else {
      console.error("❌ Progress bar element not found!");
  }
});

async function RoleAccess() {
  try {
    const iparamSelectedCategory = await client.iparams.get();
    const selectedCategoryArray = formatSelectedCategories(iparamSelectedCategory.accessvalue);
    const fdFields = iparamSelectedCategory.fd_fields;

    if (!Array.isArray(selectedCategoryArray)) {
      console.error("accessvalue is not an array", selectedCategoryArray);
      return;
    }

    const contactData = await client.data.get("loggedInUser");
    const { agentIdStr, groupsStr, rolesStr } = extractLoggedInUser(contactData);

const hasAccess = checkAccess(fdFields, selectedCategoryArray, agentIdStr, rolesStr, groupsStr);

    if (hasAccess) {
      showAutomationUI();
      await initializeAutomationTabs();
    } else {
      hideAutomationUI();
    }
  } catch (error) {
    console.error("Error in RoleAccess function:", error);
  }
}

function formatSelectedCategories(accessvalue) {
  if (!Array.isArray(accessvalue)) return [];
  return accessvalue.map(v => v.toString().trim());
}

function extractLoggedInUser(contactData) {
  const user = contactData.loggedInUser || {};
  return {
    agentIdStr: user.id?.toString().trim() || "",
    groupsStr: (user.group_ids || []).map(g => g.toString().trim()),
    rolesStr: (user.role_ids || []).map(r => r.toString().trim())
  };
}

function checkAccess(fdFields, selected, agentId, roles, groups) {
  switch (fdFields) {
    case "agent":
      return selected.includes(agentId);
    case "role":
      return roles.some(role => selected.includes(role));
    case "group":
      return groups.some(group => selected.includes(group));
    default:
      console.error("Unknown fd_fields value:", fdFields);
      return false;
  }
}

function showAutomationUI() {
  document.getElementById("loader").style.display = "none";
  document.getElementById("Automation-page").style.display = "block";
  document.getElementById("no_user").style.display = "none";
}

function hideAutomationUI() {
  document.getElementById("Automation-page").style.display = "none";
  document.getElementById("no_user").style.display = "block";
}

async function initializeAutomationTabs() {
  await showLoader("Ticketcreation");
  await checkAndSetButtonState();
  await checkAndSetButtonState1(1, 'Ticketcreation');
  await checkAndSetButtonState1(3, 'HourlyTriggers');
  await checkAndSetButtonState1(4, 'TicketUpdates');
  initializeGlobalFlags();

}

// function isCreationTotalZero() {
//   if(storedvalue1.creationTotal <= 0);{
//    console.log("creation total zero function called");
//     //  runTabBasedRuleCheck('Ticketcreation');
//      handleDuplicateRulestype(1);
//     }
// }
function getDurationForTotal(total) {
  console.log(`getDurationForTotal called with total: ${total}`);

 if (total <= 0) {
  console.log("No data found, skipping timer setup.");
  return 0; // No timer needed
}


  const baseDuration = 120; // Minimum 2 minutes (for total between 1–100)
  const itemsPerStep = 100;
  const secondsPerStep = 60;

  const steps = Math.ceil(total / itemsPerStep);
  const duration = baseDuration + ((steps - 1) * secondsPerStep);

  console.log(`Total: ${total}, Steps: ${steps}, Duration: ${duration} seconds`);
  return duration;
}
const triggeredTabs = {
  Ticketcreation: false,
  HourlyTriggers: false,
  TicketUpdates: false
};

const ruleMap = {
  Ticketcreation: { get total() { return storedvalue1.creationTotal; }, typeId: 1 },
  HourlyTriggers: { get total() { return storedvalue1.hourlyTotal; }, typeId: 3 },
  TicketUpdates: { get total() { return storedvalue1.updateTotal; }, typeId: 4 }
};
const inProgressTabs = {}; // Global or module-level map to track ongoing calls

async function runTabBasedRuleCheck(containerid) {
  console.log("🔍 Checking rules with containerid =", containerid);

  const needsInitialization =
    (storedvalue1.creationTotal === 0 ||
      storedvalue1.hourlyTotal === 0 ||
      storedvalue1.updateTotal === 0) &&
    !window.isDatabaseInitialized;

  if (needsInitialization) {
    console.log("Initializing database...", window.isDatabaseInitialized);
    await initializeDatabase();
    window.isDatabaseInitialized = true;
    console.log("After initialization database...", window.isDatabaseInitialized);
  }

  const ruleMap = {
    Ticketcreation: {
      total: storedvalue1.creationTotal,
      type: 1,
    },
    HourlyTriggers: {
      total: storedvalue1.hourlyTotal,
      type: 3,
    },
    TicketUpdates: {
      total: storedvalue1.updateTotal,
      type: 4,
    },
  };

  const ruleInfo = ruleMap[containerid];

  if (!ruleInfo) return;

  if (ruleInfo.total <= 0) {
    console.log(`✅ Triggering for ${containerid}`);
    handleDuplicateRulestype(ruleInfo.type);
  } else {
    showLoader(containerid);
  }
}

function runRuleChecks() {
  console.log("function called");

  if (Number(storedvalue1.creationTotal) <= 0 ) {
    handleDuplicateRulestype(1);
 
  }

  if (Number(storedvalue1.hourlyTotal) <= 0) {
    handleDuplicateRulestype(3);
 
  }

  if (Number(storedvalue1.updateTotal) <= 0 ) {
    handleDuplicateRulestype(4);
  
  }
}



async function checkAndSetButtonState() {
  try {
    await loadStoredValues();
    await initializeIfNeeded();

    if (storedvalue1.creationTotal <= 0) {
      console.log("creation total zero");
      handleDuplicateRulestype(1);
    }

    updateButtonState();
    setupButtonCheckInterval();

  } catch (error) {
    handleError(error);
  }
}

async function loadStoredValues() {
  window.storedvalue1 = await client.db.get("RulesDB");
  console.log("Initially stored all value from RulesDB:", storedvalue1);
}

async function initializeIfNeeded() {
  const needsInit =
    (storedvalue1.creationTotal === 0 ||
      storedvalue1.hourlyTotal === 0 ||
      storedvalue1.updateTotal === 0) &&
    !window.isDatabaseInitialized;

  if (needsInit) {
    console.log("Initializing database...");
    await initializeDatabase();
    window.isDatabaseInitialized = true;
  }
}

function updateButtonState() {
  const button = document.querySelector("fw-button");
  if (storedvalue1.updateTotal === 0 && button) {
    button.disabled = false;
    clearInterval(intervalId);
  } else if (button) {
    button.disabled = true;
    console.log("🚫 Button disabled because all totals are non-zero.");
  }
}

function setupButtonCheckInterval() {
  if (!window.intervalId) {
    window.intervalId = setInterval(async () => {
      await checkAndSetButtonState();
      await runRuleChecks();
    }, 60000);
  }
}

function handleError(error) {
  const button = document.querySelector("fw-button");

  if (error.status === 404) {
    console.warn("⚠️ RulesDB not found, assuming first-time install.");
    if (button) button.disabled = true;
  } else {
    console.error("❌ Error retrieving stored value from RulesDB:", error);
  }
}





// checkbutton state ending

//  async function handleTimerEnd() {
//    await showLoader("Ticketcreation");
//    if(!window.isDatabaseInitialized){
//    await initializeDatabase();
//    window.isDatabaseInitialized =true;
//    }
//     console.log("handleTimerEnd called")
//     handleDuplicateRulestype(1);
//   }

  //checkandsetbuttonstate1 starting 
async function checkAndSetButtonState1(data, containerid) {
  try {
    storeCheckState(data, containerid);

    // logStoredValues(data);

    await handleContainerBasedAction(containerid);
    
  } catch (error) {
    handleStateError(error);
  }
}
async function handleContainerBasedAction(containerid) {
  if (containerid === "Ticketcreation" && storedvalue1.creationTotal > 0) {
    await handleTicketCreation();
  } else if (containerid === "HourlyTriggers" && storedvalue1.hourlyTotal > 0) {
    await handleHourlyTriggers();
  } else if (containerid === "TicketUpdates" && storedvalue1.updateTotal > 0) {
    await handleTicketUpdates();
  }
}

function storeCheckState(data, containerid) {
  localStorage.setItem("checkState_data", JSON.stringify(data));
  localStorage.setItem("checkState_containerid", containerid);
}

async function handleTicketCreation() {
  await showLoader("Ticketcreation");

  const duration = getDurationForTotal(storedvalue1.creationTotal);
  if (!isValidDuration(duration)) return;

  const container = document.getElementById("Ticketcreation");
  if (!container || document.getElementById("simple-timer-Ticketcreation")) return;

  startTimer(container, "simple-timer-Ticketcreation", duration, () => {
     handleDuplicateRulestype(1); // You already defined this
  });
}

async function handleHourlyTriggers() {
  await showLoader("HourlyTriggers");

  const totalDuration =
    getDurationForTotal(storedvalue1.creationTotal) +
    getDurationForTotal(storedvalue1.hourlyTotal);

  if (!isValidDuration(totalDuration)) return;

  const container = document.getElementById("HourlyTriggers");
  if (!container || document.getElementById("simple-timer-HourlyTriggers")) return;

  startTimer(container, "simple-timer-HourlyTriggers", totalDuration, () => {
    handleDuplicateRulestype(3);
  });
}

async function handleTicketUpdates() {
  await showLoader("Ticketcreation");

  const totalDuration =
    getDurationForTotal(storedvalue1.creationTotal) +
    getDurationForTotal(storedvalue1.hourlyTotal) +
    getDurationForTotal(storedvalue1.updateTotal);

  if (!isValidDuration(totalDuration)) return;

  const container = document.getElementById("TicketUpdates");
  if (!container || document.getElementById("simple-timer-TicketUpdates")) return;

  startTimer(container, "simple-timer-TicketUpdates", totalDuration, () => {
    handleDuplicateRulestype(4);
  });
}

function startTimer(container, timerId, duration, onComplete) {
  const timerDiv = document.createElement("div");
  timerDiv.id = timerId;
  timerDiv.style.cssText = `
    position: fixed;
    top: 63%;
    left: 50%;
    transform: translateX(-50%);
    color: black;
    padding: 10px 20px;
    border-radius: 5px;
    font-family: sans-serif;
    font-size: 16px;
    z-index: 9999;
  `;
  container.appendChild(timerDiv);

  const endTime = Date.now() + duration * 1000;

  const interval = setInterval(() => {
    const remaining = Math.max(0, Math.round((endTime - Date.now()) / 1000));
    timerDiv.innerHTML = `The app is currently processing the data. Please refresh the page or revisit the app after <strong>${remaining} sec...</strong>`;

    if (remaining <= 0) {
      clearInterval(interval);
      timerDiv.remove();
      onComplete();
    }
  }, 1000);
}

function isValidDuration(duration) {
  if (typeof duration !== "number" || isNaN(duration)) {
    console.error("❌ Invalid duration calculated. Skipping timer setup.");
    return false;
  }
  return true;
}

function handleStateError(error) {
  if (error.status === 404) {
    console.warn("⚠️ RulesDB not found, assuming first-time install.");
    const button = document.querySelector("fw-button");
    if (button) {
      button.disabled = true;
    }
  } else {
    console.error("❌ Error retrieving stored value from RulesDB:", error);
  }
}
  //checkandsetbuttonstate1 ending 


async function initializeDatabase() {
  try {
    console.log("Initializing database...");
    const entity = await client.db.entity({ version: "v1" });
    console.log("Entity Initialized:", entity);

    
   
   window.newRulePloadDB5 = entity.get("newRulePloadDB5");
    console.log("📌 Entity Reference:", newRulePloadDB5);

  
    const data1 = await newRulePloadDB5.schema();
    console.log("📄 Schema Data:", data1);

  } catch (error) {
    console.error("❌ Error initializing database:", error);
  }
}

let recentcount = 0;
let agentcount = 0;
async function recentdata() {
  console.log("recentdata called");
  console.log(` Setting up Workflow-Automation-page...`);
  await setupTabListener("Workflow-Automation-page", "LastVisitedTab");
 
  if(agentcount === 0){
    await  GetAgents().then(agents => {
      console.log("✅ Agents fetching completed. Final List:", agents);
      window.globalAgents = agents; 
      console.log("🔍 Checking globalAgents before function call:", globalAgents);
      
    });
    agentcount++;
  }
 
  document.getElementById("Automation-page").style.display = "none";
  document.getElementById("button").style.display = "none";
  document.getElementById("main-container1").style.display = "block";
  

  if(recentcount === 0){
   
  const workflowPage = document.getElementById("Workflow-Automation-page");
    if (workflowPage) {
      workflowPage.style.visibility = "visible"; 
      workflowPage.style.opacity = "1"; 
    } else {
      console.error("❌ Still not found!");
    }
    recentcount++;
  }else{
   
  document.getElementById("Workflow-Automation-page").style.display = "block";
  document.getElementById("button1").style.display = "block";

  }
      

 console.log("recentdata function completes");


  
}
async function entitydata(){
  window.isFetchingHourly = false;
  ruleConfigMap[3].counter = 0;

  window.isFetching = false;
  ruleConfigMap[4].counter = 0;

  window.isFetchingRules = false;
  ruleConfigMap[1].counter = 0;
  
  document.getElementById("Ticketcreation1").innerHTML = "";
  document.getElementById("TicketUpdates1").innerHTML = "";
  document.getElementById("HourlyTriggers1").innerHTML = "";
  automationTypeIdOneRecords.length = 0;
  duplicatesType1.length = 0;
  console.log(" empty array of type3 records ",automationTypeIdOneRecords);
  console.log(" empty array inside finally block log ",duplicatesType1);

  automationTypeIdthreeRecords.length = 0;
  duplicatesType3.length = 0;
  console.log(" empty array of type3 records ",automationTypeIdthreeRecords);
  console.log(" empty array inside finally block log ",duplicatesType3);
  console.log("array inside finally block log",duplicatesType4);

  automationTypeIdfourRecords.length = 0;
  duplicatesType4.length = 0;
  console.log(" empty array of type3 records ",automationTypeIdfourRecords);
  console.log(" empty array inside finally block log ",duplicatesType4);

  document.getElementById("Workflow-Automation-page").style.display = "none";
  document.getElementById("button1").style.display = "none";
  
  document.getElementById("Automation-page").style.display = "block";
  document.getElementById("button").style.display = "block";
  await setupTabListener("Automation-page", "LastVisitedTab");
  

 }

async function GetAgents(page = 1, agentsArray = []) {
  console.log(`📄 Fetching agents for page ${page}`);

  try {
    const { response } = await client.request.invokeTemplate("filter", {
      context: { page }
    });

    const agentData = JSON.parse(response);

    if (agentData.length === 0) {
      // console.log("✅ No more agents to fetch. Total agents:", agentsArray.length);
      return agentsArray;
    }

    agentsArray.push(...agentData);

    // Recursively fetch the next page
    return await GetAgents(page + 1, agentsArray);

  } catch (error) {
    // console.error("❌ Error fetching agents:", error);
     
    if (error.headers?.status?.includes("401")) {
      document.getElementById("Automation-page").style.display = "none";
      document.getElementById("Workflow-Automation-page").style.display = "none";
      document.getElementById("no_user2").style.display = "block";
    }

    return agentsArray;
  }
}

// async function GetAgents(page = 1, agentsArray = []) {
//   console.log(`Fetching agents for page ${page}`);

//   try {
//       const GetAgentsResponse = await client.request.invokeTemplate("fetchList", {
//           context: { page: page }
//       });

//       const responses = GetAgentsResponse.response;
//       const agentData = JSON.parse(responses);

//       if (agentData.length === 0) {
//           console.log("✅ No more agents to fetch. Total agents:", agentsArray.length);
//           return agentsArray;
//       }

//       agentsArray.push(...agentData);

      
//       return await GetAgents(page + 1, agentsArray);

//   } catch (error) {
//       console.error("❌ Error fetching agents:", error);

//       if (error.headers && error.headers.status.includes("401")) {  
//           document.getElementById("Automation-page").style.display = "none";
//           document.getElementById("Workflow-Automation-page").style.display = "none";
//           document.getElementById("no_user2").style.display = "block";
//       }

//       return agentsArray; 
//   }
// }


  function showLoader(containerId) {
  console.log("showLoader called for container:", containerId);

  const container = document.getElementById(containerId);
  let spinnerContainer = document.getElementById("spinner-container");


  if (!container) {
    console.error("Target container not found:", containerId);
    return;
  }

  if (!spinnerContainer) {
    console.log("Spinner container not found, creating new one.");
    spinnerContainer = document.createElement("div");
    spinnerContainer.id = "spinner-container";
    spinnerContainer.innerHTML = `<fw-spinner id="spinner" class="spinner" size="large"></fw-spinner>`;
    document.body.appendChild(spinnerContainer);
  }

 
  if (!container.contains(spinnerContainer)) {
    console.log("Appending spinner to container:", containerId);
    container.appendChild(spinnerContainer);
  }


  spinnerContainer.classList.add("show");
}

function hideLoader() {
  console.log("hide spinner called");
  const spinnerContainer = document.getElementById("spinner-container");
  if (spinnerContainer) {
 
    spinnerContainer.classList.remove("show");
  }
}





//fetchanduserules starting

async function fetchAndUseRules(automation_type_id) {
  const config = ruleConfigMap[automation_type_id];
  if (!config) {
    console.warn("⚠️ Unknown automation_type_id:", automation_type_id);
    return;
  }

  try {
    await handleRuleFetch(config);
    config.counter++;
  } catch (error) {
    console.error("❌ Error in fetchAndUseRules:", error);
  }
}
const ruleConfigMap = {
  1: {
    isFetchingFlag: "isFetchingRules",
    counter: 0,
    loaderId: "Ticketcreation1",
    fetchFn: listrules,
    recordArray: automationTypeIdOneRecords,
    duplicateStore: duplicatesType1,
    displayFn: displayGroupedRules4,
    displayId: "Ticketcreation1",
    typeId: 1
  },
  3: {
    isFetchingFlag: "isFetchingHourly",
    counter: 0,
    loaderId: "HourlyTriggers1",
    fetchFn: listhourlyrules,
    recordArray: automationTypeIdthreeRecords,
    duplicateStore: duplicatesType3,
    displayFn: displayGroupedRules4,
    displayId: "HourlyTriggers1",
    typeId: 3
  },
  4: {
    isFetchingFlag: "isFetching",
    counter: 0,
    loaderId: "TicketUpdates1",
    fetchFn: listupdaterules,
    recordArray: automationTypeIdfourRecords,
    duplicateStore: duplicatesType4,
    displayFn: processAndDisplayDuplicates,
    displayId: "TicketUpdates1",
    typeId: 4
  }
};
async function handleRuleFetch(config) {
  const { isFetchingFlag, counter, loaderId, fetchFn, recordArray, duplicateStore, displayFn, displayId, typeId } = config;

  if (window[isFetchingFlag] || counter > 0) {
    console.log(`⏭️ Skipping fetch for type ${typeId} (already fetched or fetching)...`);
    return;
  }

  window[isFetchingFlag] = true;
  await showLoader(loaderId);

  try {
    const rules = await fetchFn();
    console.log(`${loaderId} Rules:`, rules);

    recordArray.length = 0;      // ✅ Clear old records
    duplicateStore.length = 0;   // ✅ Clear old duplicates

    rules.forEach(rule => {
      if (rule.active) recordArray.push(rule);
    });

    findDuplicatesWithinType(recordArray, duplicateStore);
    console.log("duplicatestores", duplicateStore);
    displayFn(duplicateStore, displayId, typeId, window.globalAgents);
  } catch (error) {
    handleFetchError1(error);
  } finally {
    hideLoader(loaderId);
    window[isFetchingFlag] = false;
  }
}
function handleFetchError1(error) {
  console.error("❌ Error fetching rules:", error);

  const hideSections = () => {
    document.getElementById("Automation-page").style.display = "none";
    document.getElementById("Workflow-Automation-page").style.display = "none";
  };

  if (error.status === 401) {
    hideSections();
    document.getElementById("no_user2").style.display = "block";
  }

  if (error.status === 429) {
    hideSections();
    document.getElementById("no_user1").style.display = "block";
  }
}


//fetchanduserules ending


async function listrules(page = 1, rulesArray = []) {
  console.log(`Fetching rules for page ${page}`);

  try {
      const rulesResponse = await client.request.invokeTemplate('listrules', {
          context: {
              page: page
          }
      });

      const responses = rulesResponse.response;
      const rulesData = JSON.parse(responses);

      if (rulesData.length === 0) {
          console.log("✅ No more rules to fetch. Total rules:", rulesArray.length);
          return rulesArray; 
      }

      rulesArray.push(...rulesData);

      // Fetch the next page
      return await listrules(page + 1, rulesArray);

  } catch (error) {
     console.error("❌ Error fetching rules:", error);
console.log("Type of error.status:", typeof error.status); // Logs type (e.g., "string" or "number")
console.log("Value of error.status:", error.status);       // Logs actual value

// alert("STATUS: " + error.status); // Optional alert for quick browser popup

if (error.status === 401) {
  document.getElementById("Automation-page").style.display = "none";
  document.getElementById("Workflow-Automation-page").style.display = "none";
  document.getElementById("no_user2").style.display = "block";
} else if (error.status === 429) {
  document.getElementById("Automation-page").style.display = "none";
  document.getElementById("Workflow-Automation-page").style.display = "none";
  document.getElementById("no_user1").style.display = "block";
}
      return rulesArray; 
  }
}
async function listupdaterules(page = 1, rulesArray = []) {
  console.log(`Fetching rules for page ${page}`);

  try {
      const rulesResponse = await client.request.invokeTemplate('listupdaterules', {
          context: {
              page: page
          }
      });

      const responses = rulesResponse.response;
      const rulesData = JSON.parse(responses);

      if (rulesData.length === 0) {
          console.log("✅ No more rules to fetch. Total rules:", rulesArray.length);
          return rulesArray; 
      }

      rulesArray.push(...rulesData);

      // Fetch the next page
      return await listupdaterules(page + 1, rulesArray);

  } catch (error) {
      console.error("❌ Error fetching rules:", error);
      if (error.headers && error.headers.status.includes("401"))  {
        document.getElementById("Automation-page").style.display = "none";
        document.getElementById("Workflow-Automation-page").style.display = "none";
        
        document.getElementById("no_user2").style.display = "block";
       
      }
      else  if (error.status === 429 ) { 
          document.getElementById( "main-container").style.display = "none";
         document.getElementById( "main-container1").style.display = "none";
         document.getElementById("Automation-page").style.display = "none";
        document.getElementById("Workflow-Automation-page").style.display = "none";
        
        document.getElementById("no_user1").style.display = "block";
      }
      return rulesArray; 
  }
}
async function listhourlyrules(page = 1, rulesArray = []) {
  console.log(`Fetching rules for page ${page}`);

  try {
      const rulesResponse = await client.request.invokeTemplate('listhourlyrules', {
          context: {
              page: page
          }
      });

      const responses = rulesResponse.response;
      const rulesData = JSON.parse(responses);

      if (rulesData.length === 0) {
          console.log("✅ No more rules to fetch. Total rules:", rulesArray.length);
          return rulesArray; 
      }

      rulesArray.push(...rulesData);

      // Fetch the next page
      return await listhourlyrules(page + 1, rulesArray);

  } catch (error) {
      console.error("❌ Error fetching rules:", error);
      if (error.headers && error.headers.status.includes("401"))  {
        document.getElementById("Automation-page").style.display = "none";
        document.getElementById("Workflow-Automation-page").style.display = "none";
        
        document.getElementById("no_user2").style.display = "block";
        
      }
    else  if (error.status === 429 ) { 
      console.log("Type of error.status:", typeof error.status); // Logs type (e.g., "string" or "number")
console.log("Value of error.status:", error.status); 
      // alert("STATUS: " + error.status);

      console.log("Error object:", error);
      console.log(document.getElementById("Automation-page"));
console.log(document.getElementById("Workflow-Automation-page"));
console.log(document.getElementById("no_user1"));  // or "no_user2"
 document.getElementById("Automation-page").style.display = "none";
         document.getElementById("Workflow-Automation-page").style.display = "none";
         document.getElementById("no_user1").style.display = "block";
         document.getElementById("no_user1").style.background = "red";
      }
      return rulesArray; 
  }
}


function 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 usedIndices = new Set();
      for (const item1 of val1) {
        const matchIndex = val2.findIndex((item2, idx) => {
          if (usedIndices.has(idx)) return false;
          if (deepEqual(item1, item2)) {
            usedIndices.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;
}
// function normalizeText(text) {
//   if (typeof text !== 'string') return '';

//   return text
//     .replace(/&nbsp;/gi, '')            // Remove non-breaking spaces
//     .replace(/\u200B|\uFEFF/g, '')      // Remove hidden characters
//     .replace(/[^a-zA-Z0-9]/g, '')       // Remove all non-alphanumerics (includes spaces, dots, punctuations)
//     .toLowerCase();                     // Normalize case
// }
function normalizeText(text) {
  if (typeof text !== 'string') return '';

  return text
    .replace(/&nbsp;/gi, '')        // Remove non-breaking spaces
    .replace(/\u200B|\uFEFF/g, '')  // Remove hidden Unicode characters
    .replace(/\./g, '')             // Remove full stops only
    .replace(/\s+/g, '')            // Remove all types of spaces
    .toLowerCase();                 // Normalize case
}


// function normalizeText(text) {
//   if (typeof text !== 'string') return '';

//   const cleaned = text
//     .replace(/[.]/g, '')                            // remove punctuation
//     .replace(/\s+/g, ' ')                            // normalize spaces
//     .replace(/([a-zA-Z])\s+(\d)/g, '$1$2')           // collapse letter-number like "hello 2" → "hello2"
//     .replace(/(\d)\s+([a-zA-Z])/g, '$1$2')           // collapse number-letter like "3 hi" → "3hi"
//     .trim()
//     .toLowerCase();

//   // If it's purely digits and spaces (e.g. "123  45 67"), remove *all* spaces
//   if (/^[\d\s]+$/.test(text)) {
//     return text.replace(/\s+/g, '');
//   }

//   return cleaned;
// }
function stripHTML4(htmlString) {
  if (typeof htmlString !== 'string') {
    htmlString = String(htmlString || '');
  }

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

  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/g, '')     // remove hidden Unicode characters
    .replace(/[.]/g, '')               // remove full stops
    .replace(/\s+/g, ' ')              // normalize whitespace
    .trim()
    .toLowerCase();
}


function normalizeConditionsForGrouping(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);
    }).sort((a, b) => JSON.stringify(a).localeCompare(JSON.stringify(b)));

    return {
      match_type: set.match_type?.toLowerCase(),
      properties: normalizedProps
    };
  });
}

function areConditionsEquivalent(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]));
  });
}

function generatePermutations(array) {
  if (array.length <= 1) return [array];

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

function findDuplicatesWithinType(records, duplicatesArray) {
  const seenRecords = [];

  records.forEach((rule) => {
    const { summary, actions, conditions } = rule;

    if (summary && actions && conditions) {
      const normalizedSummary = sortObjectValues(summary);
      const normalizedActions = sortObjectValues(actions);
      const normalizedConditions = normalizeConditionsForGrouping(conditions);

      const duplicate = seenRecords.find(seen => {
        const summaryMatch = deepEqual(sortObjectValues(seen.summary), normalizedSummary);
        const actionMatch = deepEqual(sortObjectValues(seen.actions), normalizedActions);
        const conditionMatch = areConditionsEquivalent(seen.conditions, normalizedConditions);

        return summaryMatch && actionMatch && conditionMatch;
      });

      if (duplicate) {
        duplicatesArray.push(rule);
        if (!duplicatesArray.includes(duplicate.rule)) {
          duplicatesArray.push(duplicate.rule);
        }
      } else {
        seenRecords.push({
          summary: normalizedSummary,
          actions: normalizedActions,
          conditions: normalizedConditions,
          rule
        });
      }
    }
  });
}

function 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 (Object.prototype.hasOwnProperty.call(obj, 'condition_set_1') || 
    Object.prototype.hasOwnProperty.call(obj, 'condition_set_2')) {

      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));
}


function capitalizeFirstLetter(text) {
  if (!text) return text;
  return text.charAt(0).toUpperCase() + text.slice(1);
}
function normalizeConditionProps(set) {
  if (!Array.isArray(set) || set.length === 0) return [];

  return set.flatMap(conditionSet => {
    const matchType = normalizeText(stripHTML4(conditionSet.match_type || ""));

    return (conditionSet.properties || []).map(prop => {
      const field = normalizeText(stripHTML4(prop.field_name));
      const operator = normalizeText(stripHTML4(prop.operator));
      const value = Array.isArray(prop.value)
        ? prop.value.map(v => normalizeText(stripHTML4(v))).join(";")
        : normalizeText(stripHTML4(prop.value));

      return `${matchType}:${field}:${operator}:${value}`;
    });
  }).sort();
}

// function normalizeConditionProps(set) {
//   return (set?.[0]?.properties || [])
//     .map(prop => {
//       return [
//         normalizeText(stripHTML4(prop.field_name)),
//         normalizeText(stripHTML4(prop.operator)),
//         normalizeText(stripHTML4(prop.value))
//       ].join(":");
//     })
//     .sort();
// }
function normalizeAction(action = {}) {
  const result = [];

  Object.entries(action).forEach(([key, value]) => {
    if (value === null || value === "") return;

    const normalizedKey = normalizeText(stripHTML4(key));

    if (typeof value === "string") {
      result.push(`${normalizedKey}:${normalizeText(stripHTML4(value))}`);
    } else if (Array.isArray(value)) {
      const normalizedArray = value.map(v => normalizeText(stripHTML4(v))).sort();
      result.push(`${normalizedKey}:[${normalizedArray.join(",")}]`);
    } else if (typeof value === "object") {
      result.push(`${normalizedKey}:{${normalizeAction(value)}}`);
    }
  });

  return result.sort().join(" ");
}
function combineConditionsAndActions4({
  condition_set_1_summary,
  condition_set_2_summary,
  operator,
  condition_set_1_real,
  condition_set_2_real,
  actions_summary,
  actions_real
}) {
  const originalConditions = buildOriginalConditions(condition_set_1_summary, condition_set_2_summary, operator);
  const originalActionText = buildOriginalActions(actions_summary);
  const originalContent = `${originalConditions} ${originalActionText}`.trim();

  const sortedConditions = buildSortedConditions(condition_set_1_real, condition_set_2_real, operator);
  const sortedActions = buildSortedActions(actions_real);
  const sortedContent = `${sortedConditions} ${sortedActions}`.trim();

  return { originalContent, sortedContent };
}

function buildOriginalConditions(set1, set2, operator) {
  const processedSet1 = (set1 || []).map(stripHTML4);
  const processedSet2 = (set2 || []).map(stripHTML4);
  const op = operator ? ` ${operator} ` : "";
  return [...processedSet1, op, ...processedSet2].join(" ");
}

function buildOriginalActions(actions) {
  return Array.isArray(actions) && actions.length > 0
    ? actions.map(stripHTML4).join(" ")
    : "";
}

function buildSortedConditions(real1, real2, operator) {
  const normalizedSet1 = normalizeConditionProps(real1);
  const normalizedSet2 = normalizeConditionProps(real2);
  const all = [...normalizedSet1, ...normalizedSet2].sort((a, b) => a.localeCompare(b));
  return [...all, normalizeText(operator || "")].join(" ");
}

function buildSortedActions(actions) {
  return (actions || []).map(normalizeAction).sort().join(" ");
}



function normalizeText1(text) {
  if (typeof text !== "string") return text;
  return text
    .replace(/<[^>]*>/g, "") 
    .replace(/[.,]/g, "")      
    .replace(/\s+/g, " ")      
    .trim();
}

function processRecord(record, groupedRules, automation_type_id) {
  const rule = extractRule(record);
  if (!rule) return;

  const {
    name, summary, position, updated_at,
    last_updated_by, affected_tickets_count, id
  } = rule;

  const actions = summary.actions || [];

  const { originalContent, sortedContent } = combineConditionsAndActions4({
    condition_set_1_summary: summary.conditions.condition_set_1,
    condition_set_2_summary: summary.conditions.condition_set_2,
    operator: summary.conditions.operator,
    condition_set_1_real: filterConditions(record, "condition_set_1"),
    condition_set_2_real: filterConditions(record, "condition_set_2"),
    actions_summary: actions,
    actions_real: record.actions
  });

  if (!groupedRules.has(sortedContent)) {
    groupedRules.set(sortedContent, []);
  }

  groupedRules.get(sortedContent).push({
    name,
    position,
    combinedContent: originalContent,
    conditions: summary.conditions,
    actions,
    updated_at,
    last_updated_by,
    affected_tickets_count,
    id,
    automation_type_id
  });
}

function extractRule(record) {
  const rule = record.parsedPayload || record.rule || record;
  if (!rule || !rule.summary || !rule.summary.conditions) return null;
  return rule;
}

function filterConditions(record, setName) {
  return (record.conditions || []).filter(cond => cond.name === setName);
}



     function calculateLastModified(updated_at) {
  const updatedDate = new Date(updated_at);
  const currentDate = new Date();

  const diffInSeconds = Math.floor((currentDate - updatedDate) / 1000);
  const timeChunks = [
    { label: "year", seconds: 31536000 },
    { label: "month", seconds: 2592000 },
    { label: "day", seconds: 86400 },
    { label: "hour", seconds: 3600 },
    { label: "minute", seconds: 60 }
  ];

  for (const chunk of timeChunks) {
    const amount = Math.floor(diffInSeconds / chunk.seconds);
    if (amount >= 1) {
      return amount === 1 ? `a ${chunk.label} ago` : `${amount} ${chunk.label}s ago`;
    }
  }

  return "Just now";
}
window.currentPage4 = 1;
const itemsPerPage4 = 5;

function displayGroupedRules4(records, containerId, automation_type_id,globalAgents) {
  console.log("automationtypeid log at start of displaygroups",automation_type_id  )
  const container = document.getElementById(containerId);
  if (!container) {
    console.error(`Container with ID "${containerId}" not found.`);
    return;
  }

  container.innerHTML = ""; 

  if (records.length <= 1) {
    console.log("records length zero")
    container.innerHTML = `
    <div style="
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80%;
  font-size: 24px;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin: 300px auto; /* Push it down + center horizontally */
">
 

          No duplicate rules found.
      </div>`;
    return;
}

const groupedRules = new Map();



records.forEach((record) => {
  processRecord(record, groupedRules, automation_type_id);
});


const groupedRulesArray = Array.from(groupedRules.values()).filter(group => group.length > 1);
  const totalgroup = Math.ceil(groupedRulesArray.length );
  console.log(totalgroup,"*********************")
  const totalPages4 = Math.ceil(groupedRulesArray.length / itemsPerPage4);
  window.currentPage4 = Math.max(1, Math.min(currentPage4, totalPages4)); // Ensure valid page number

  console.log("Total Pages:", totalPages4, "Current Page:", currentPage4);

  const startIdx = (currentPage4 - 1) * itemsPerPage4;
  const paginatedRules = groupedRulesArray.slice(startIdx, startIdx + itemsPerPage4);

  console.log("Displaying Records:", paginatedRules);

 const arrayLength = paginatedRules.length;
  console.log("Records Length:", arrayLength);

  if (arrayLength === 0) {
  console.log("Array is empty.");
     container.innerHTML = `
    <div style="
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80%;
  font-size: 24px;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin: 300px auto; /* Push it down + center horizontally */
">
 

          No duplicate rules found.
      </div>`;
    return;
}
  paginatedRules.forEach((titles) => {
    const rulesCount = titles.length;

    if (rulesCount === 1) {
        console.log(`Skipping group with only 1 rule: ${titles[0].name}`);
        return; 
    }
    
    const groupContainer = document.createElement("div");
    groupContainer.style.border = "1px solid #ccc";
    groupContainer.style.padding = "16px";
    groupContainer.style.margin = "16px";
    groupContainer.style.borderRadius = "8px";
    groupContainer.style.backgroundColor = "#f5f7f9";
    groupContainer.style.width = "87%";

    titles.forEach(({  name, position, combinedContent, conditions, actions,updated_at,last_updated_by,affected_tickets_count,automation_type_id,id
    }, index) => {
      const card = document.createElement("div");
      // card.className = "fw-card-1 fw-py-16 fw-flex fw-flex-column";
    card.style.border = "1px solid #ddd";
    card.style.padding = "16px";
    card.style.margin = "8px 0"
    card.style.fontFamily =
      "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
    card.style.borderRadius = "8px";
    card.style.backgroundColor = index === 0 ? "#fff" : "#e5f2fd";
    card.style.marginBottom = "10px";
    card.style.paddingBottom = "0";
    card .style.overflow ="hidden"
     
     
      
    const cardHeader = document.createElement("div");
    cardHeader.style.display = "flex";
    cardHeader.style.justifyContent = "space-between";
    cardHeader.style.alignItems = "center";
      
      // Create a wrapper for the title
      const cardTitle = document.createElement("h4");
      cardTitle.style.margin = "0";
      cardTitle.style.cursor = "pointer";
      cardTitle.style.fontSize = "14px";
      cardTitle.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
      cardTitle.style.color = "#183247";
      cardTitle.style.transition = "color 0.2s ease";
      cardTitle.style.fontWeight = "600"; 

// Create the serial number (position)
if (position) {
  const serialNumber = document.createElement("span");
  serialNumber.textContent = position + ". ";
  serialNumber.style.color = "#183247"; // Keep serial number color fixed
  cardTitle.appendChild(serialNumber);
}

// Create the actual name (clickable part)
const titleText = document.createElement("span");
titleText.textContent = name;
titleText.style.color = "#183247"; 
titleText.style.transition = "color 0.2s ease";

// Add hover effect for only the name
titleText.addEventListener("mouseover", () => {
    titleText.style.color = "#007bff"; // Change only name color on hover
});
titleText.addEventListener("mouseout", () => {
    titleText.style.color = "#183247"; // Reset name color when not hovering
});
 window.isPopupOpen = false;
titleText.addEventListener("click", () => {
    titleText.style.color = "#ff5733"; // Change title color on click
    console.log("automation type id before popup",automation_type_id)
      if (window.isPopupOpen) return; 
  window.isPopupOpen = true;
    showPopupCard(name, { conditions: conditions, actions: actions },automation_type_id)
});

// Append name to title
cardTitle.appendChild(titleText);




      // Append title and actions to the cardHeader
      cardHeader.appendChild(cardTitle);
      // Create a container for the horizontal line and the gap
const cardContainer = document.createElement("div");

// Style the container to have a background color in the gap
cardContainer.style.backgroundColor = "#f0f0f0";  // Set the background color for the gap (change to desired color)
cardContainer.style.paddingBottom = "20px";  
cardContainer.style.marginLeft="-15px";
cardContainer.style.borderRadius = "4px";
// cardContainer.style.width="103%";
cardContainer.style.position = "relative";
cardContainer.style.width = "calc(103% + 30px)";

// Create a horizontal line after the cardBody
const horizontalLine = document.createElement("div");
horizontalLine.style.height = "1px"; // Set the height to 1px for a thin line
horizontalLine.style.backgroundColor = "#ccc"; // Set the color of the horizontal line
horizontalLine.style.marginTop = "16px"; // Add space above the line (adjust as needed)
// horizontalLine.style.width = "100%"; // Ensure the line stretches the full width of the container
horizontalLine.style.marginLeft="-3px";
      

    function truncateTextByLength(content, maxLength) {
  return content.length > maxLength ? content.slice(0, maxLength) + "..." : content;
}

function splitIntoLines(text, maxLength, lines) {
  const words = text.split(" ");
  const result = [];
  let line = "";
  let currentLine = 1;
  const maxPerLine = Math.floor(maxLength / lines);

  for (const word of words) {
    if ((line + " " + word).trim().length <= maxPerLine) {
      line += (line ? " " : "") + word;
    } else {
      result.push(line);
      line = word;
      currentLine++;
      if (currentLine > lines) break;
    }
  }

  if (currentLine <= lines && line) {
    result.push(line);
  }

  return {
    text: result.join(" "),
    truncated: currentLine > lines,
  };
}

function truncateContent(content, maxLength, lines) {
  const truncated = truncateTextByLength(content, maxLength);
  const { text, truncated: wasTruncated } = splitIntoLines(truncated, maxLength, lines);
  return text + (wasTruncated ? "..." : "");
}


    
    
      
      
   
      // console.log("updated at",calculateLastModified(updated_at));
      
      const lastModifiedRow = document.createElement("div");
      lastModifiedRow.style.display = "grid";
      lastModifiedRow.style.gridTemplateColumns = "repeat(auto-fit, minmax(150px, 1fr))"; // Responsive columns with minimum size 150px
      lastModifiedRow.style.alignItems = "center";
      lastModifiedRow.style.gap = "16px"; // Space between items
      lastModifiedRow.style.width = "100%"; // Ensure full width
      lastModifiedRow.style.gridTemplateRows = "auto"; // Auto row size to fit content
      
      // Function to create a label-value pair container
      function createLabelValue(labelText, valueText) {
        const container = document.createElement("div");
        container.style.display = "flex";
        container.style.flexDirection = "row"; // Make sure content is horizontal
        container.style.alignItems = "center"; // Align vertically in center
      
        const label = document.createElement("span");
        label.textContent = labelText;
        label.style.color = "#183247";
        label.style.marginTop = "10px";
        label.style.marginLeft = "15%";
        label.style.fontSize = "12px";
        label.style.fontFamily ="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";

        
        const value = document.createElement("span");
        value.textContent = valueText;
        value.style.color = "#183247";
        value.style.fontWeight = "600";
        value.style.fontSize = "12px";
        value.style.marginTop = "10px";
        value.style.marginLeft = "10px";
        value.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";

        value.style.marginLeft = "10px"; // Add space between label and value
      
        container.appendChild(label);
        container.appendChild(value);
      
        return container;
      }
      
      // Create and append content to the lastModifiedRow
      const lastModifiedText = calculateLastModified(updated_at);
      lastModifiedRow.appendChild(createLabelValue("Last Modified :", lastModifiedText));
      
      // Vertical line between sections
      const verticalLine = document.createElement("div");
      verticalLine.style.gridRow = "span 1"; // Ensuring vertical line doesn't span more than one row
      verticalLine.style.height = "20px"; 
      verticalLine.style.marginTop = "10px";
      verticalLine.style.marginLeft = "30px"; // Add gap at the top// Adjust the height as needed
      verticalLine.style.borderLeft = "2px solid #ccc";
      lastModifiedRow.appendChild(verticalLine);
      
      // Matching agent data
      const agentsid = last_updated_by;
      const matchingAgent = globalAgents.find(agent => String(agent.id) === String(agentsid));
      const agentNameText = matchingAgent ? matchingAgent.contact.name : "Unknown Agent";
      lastModifiedRow.appendChild(createLabelValue("By :", agentNameText));
      
      // Vertical line after the agent name
      const verticalLine2 = document.createElement("div");
      verticalLine2.style.gridRow = "span 1"; // Same for second vertical line
      verticalLine2.style.height = "20px";
      verticalLine2.style.marginTop = "10px"; 
      verticalLine2.style.marginLeft = "30px"; // Adjust the height as needed
      verticalLine2.style.borderLeft = "2px solid #ccc";
      lastModifiedRow.appendChild(verticalLine2);
      
      // Impacted tickets info
      const affectedTicketsText = affected_tickets_count === 0 ? "--" : affected_tickets_count;
      // lastModifiedRow.appendChild(createLabelValue("Impacted tickets (Last 7 days) :", affectedTicketsText));
      const impactedTickets = createLabelValue("Impacted tickets (Last 7 days) :", affectedTicketsText);
  impactedTickets.firstChild.style.marginLeft = "-50%"; // Adjust label alignment
  lastModifiedRow.appendChild(impactedTickets);
      
 

 
      const cardBody = document.createElement("div"); // Create a container for card content and actions
      cardBody.style.display = "flex"; // Flexbox to align items horizontally
      cardBody.style.justifyContent = "space-between"; // Ensure there's space between content and actions
      cardBody.style.alignItems = "flex-start"; // Align items to the top (optional, depending on your needs)
               

const truncatedContent = truncateContent(combinedContent, 200, 2);

const cardContent = document.createElement("pre");
cardContent.textContent = truncatedContent;

// Style the card content
cardContent.style.marginTop = "8px";
cardContent.style.padding = "8px";
cardContent.style.color="#183247";
cardContent.style.fontweight="600";
cardContent.style.fontFamily= "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
cardContent.style.whiteSpace = "pre-wrap"; // Ensure text wraps
cardContent.style.overflow = "hidden"; // Hide overflow content
cardContent.style.textOverflow = "ellipsis"; // Add ellipsis for overflow
cardContent.style.maxWidth = "75%"; // Limit the card width to half the container's width
cardContent.style.fontSize="12px";
cardContent.style.marginLeft="15px";


     // Create the container for card actions
const cardActionsContainer = document.createElement("div");
cardActionsContainer.style.display = "flex"; // Display actions horizontally
cardActionsContainer.style.justifyContent = "flex-end"; // Align to the right
cardActionsContainer.style.marginTop = "10px"; // Add some spacing above the actions
cardActionsContainer.style.gap = "8px"; // Set space between the toggle and the delete icon
function initializeDeleteModal() {
  if (!document.getElementById("deleteConfirmationPopup")) {
    const modal = document.createElement("fw-modal");
    modal.setAttribute("id", "deleteConfirmationPopup");
    modal.setAttribute("title-text", "Delete Rule");
    modal.innerHTML = `
      <fw-text>Are you sure you want to delete the rule?</fw-text>
      <fw-modal-footer></fw-modal-footer>
    `;
    document.body.appendChild(modal);
  }
}
      const fwIcon = document.createElement("fw-icon");
      fwIcon.setAttribute("name", "delete");
      fwIcon.setAttribute("size", "18");
      fwIcon.style.cursor = "pointer";
      fwIcon.style.color = "red"; // Set the color to red
      // Add a pointer cursor for interactivity
      fwIcon.title = "Delete";
      fwIcon.addEventListener("click", () => {
  console.log("Delete icon clicked");

  // currentRuleId = id; 1
  window.currentAutomationId = automation_type_id;

  // console.log("rule id:", currentRuleId);      2

  initializeDeleteModal();

  const modal = document.getElementById("deleteConfirmationPopup");
  // const footer = modal.querySelector("fw-modal-footer");

  // Remove old listeners from modal
  const newModal = modal.cloneNode(true);
  modal.replaceWith(newModal);

  // Reassign modal after clone
  const freshModal = document.getElementById("deleteConfirmationPopup");
  const freshFooter = freshModal.querySelector("fw-modal-footer");

  // Add listeners
  freshModal.addEventListener("fwSubmit", () => {
    console.log("Delete confirmed.");
    try {
      recenetconfirmDeletion(id, currentAutomationId); //3
    } catch (error) {
      console.error("❌ Error in deletion process inside event listener:", error);
    }
    freshModal.removeAttribute("is-open");
  });

  freshFooter.addEventListener("fwClose", () => {
    freshModal.removeAttribute("is-open");
    console.log("Delete operation was cancelled.");
  });

  // Open modal
  freshModal.setAttribute("is-open", "true");
});
     

    
          cardActionsContainer.appendChild(fwIcon);
          card.appendChild(cardHeader);
          cardBody.appendChild(cardContent);
          cardBody.appendChild(cardActionsContainer);
          card.appendChild(cardBody);
          cardContainer.appendChild(horizontalLine);
          // card.appendChild(horizontalLine);
         
          cardContainer.appendChild(lastModifiedRow);
          card.appendChild(cardContainer)
          groupContainer.appendChild(card);
        });
    
        container.appendChild(groupContainer);
      });
    // Add pagination component
    addFwPagination4(containerId,records,totalgroup,automation_type_id);
    }

// Function to add pagination for displayGroupedRules4
function addFwPagination4(containerId, records, totalgroup, automation_type_id) {
  const itemsPerPage = itemsPerPage4;
  const totalPages = Math.ceil(totalgroup / itemsPerPage);
  console.log("Adding Bootstrap pagination to container:", containerId);
  console.log("Automation Type ID at Page Change:", automation_type_id);

  const container = document.getElementById(containerId);
  if (!container) {
    console.warn(`Container with ID "${containerId}" not found.`);
    return;
  }

  if (totalgroup <= itemsPerPage) {
    console.log("Total records are less than or equal to items per page, skipping pagination.");
    return;
  }

  const existingPagination = container.querySelector("#bootstrap-pagination-4");
  if (existingPagination) existingPagination.remove();

  const paginationWrapper = document.createElement("nav");
  paginationWrapper.setAttribute("aria-label", "Page navigation");
  paginationWrapper.id = "bootstrap-pagination-4";
  paginationWrapper.style.marginLeft = "40%";

  const ul = document.createElement("ul");
  ul.className = "pagination";

  ul.appendChild(createPrevNextButtons4(currentPage4, totalPages, records, containerId, totalgroup, true, automation_type_id)); // Previous
  ul.appendChild(createPageLinks4(totalPages, currentPage4, records, containerId, totalgroup, automation_type_id)); // Pages
  ul.appendChild(createPrevNextButtons4(currentPage4, totalPages, records, containerId, totalgroup, false, automation_type_id)); // Next

  paginationWrapper.appendChild(ul);
  container.appendChild(paginationWrapper);
}
function createPaginationLink4(text, isDisabled, onClickHandler, isActive = false) {
  const li = document.createElement("li");
  li.className = "page-item" + (isDisabled ? " disabled" : "") + (isActive ? " active" : "");

  const link = document.createElement("a");
  link.className = "page-link" + (isDisabled ? " disabled-hover" : "");
  link.href = "#";
  link.innerHTML = text;

  if (isDisabled) {
    link.setAttribute("tabindex", "-1");
    link.setAttribute("aria-disabled", "true");
  }

  link.addEventListener("click", (e) => {
    e.preventDefault();
    if (!isDisabled) onClickHandler();
  });

  li.appendChild(link);
  return li;
}

function createPrevNextButtons4(currentPage4, totalPages, records, containerId, totalgroup, isPrev, automation_type_id) {
  const isDisabled = isPrev ? currentPage4 === 1 : currentPage4 === totalPages;
  const text = isPrev
    ? `<span class="label-wrapper">&laquo; Previous<span class="hover-symbol" aria-hidden="true">🚫</span></span>`
    : `<span class="label-wrapper">Next &raquo;<span class="hover-symbol" aria-hidden="true">🚫</span></span>`;

  const handler = () => {
    window.currentPage4 += isPrev ? -1 : 1;
    displayGroupedRules4(records, containerId, localStorage.getItem("automation_type_id"), globalAgents);
    addFwPagination4(containerId, records, totalgroup, automation_type_id);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  return createPaginationLink4(text, isDisabled, handler);
}

function createPageLinks4(totalPages, currentPage4, records, containerId, totalgroup, automation_type_id) {
  const fragment = document.createDocumentFragment();

  for (let i = 1; i <= totalPages; i++) {
    const handler = () => {
      if (window.currentPage4 !== i) {
        window.currentPage4 = i;
        displayGroupedRules4(records, containerId, localStorage.getItem("automation_type_id"), globalAgents);
        addFwPagination4(containerId, records, totalgroup, automation_type_id);
        window.scrollTo({ top: 0, behavior: "smooth" });
      }
    };

    const li = createPaginationLink4(i, false, handler, i === currentPage4);
    li.querySelector("a").textContent = i;
    fragment.appendChild(li);
  }

  return fragment;
}



async function Fetchentity(automationTypeId, nextMarker = null, allRecords1 = []) {
  try {
    if (!newRulePloadDB5) return await handleEntityNotReady();

    await showLoader();

    const queryObj = buildQueryObject(automationTypeId, nextMarker);
    console.log("📤 Fetching records with query:", JSON.stringify(queryObj, null, 2));

    const response = await newRulePloadDB5.getAll(queryObj);
    const records = response.records;

    if (!Array.isArray(records)) {
      console.error("❌ Invalid response format:", response);
      hideLoader();
      return allRecords1;
    }

    console.log(`📥 Retrieved ${records.length} records`);
    window.allRecords1 = allRecords1.concat(records);
     
    const newNextMarker = response.links?.next?.marker;
    if (newNextMarker) {
      console.log(`🔄 More pages exist. Next marker: ${newNextMarker}`);
      return Fetchentity(automationTypeId, newNextMarker, allRecords1);
    }

    console.log("✅ No more pages.");
    console.log(`📌 Total Filtered Records: ${allRecords1.length}`);
    hideLoader();

    return handleFinalRecords(automationTypeId, window.allRecords1);

  } catch (error) {
    return handleFetchError(error);
  }
}

function buildQueryObject(automationTypeId, nextMarker) {
  const query = {
    query: {
      $and: [
        { automation_type_id: automationTypeId },
        { active: "true" }
      ]
    }
  };
  if (nextMarker) query.next = { marker: nextMarker };
  return query;
}

async function handleEntityNotReady() {
  console.error("Entity is not initialized yet!");
  await showLoader();
  setTimeout(() => location.reload(), 1000);
  return [];
}

function handleFinalRecords(automationTypeId, allRecords) {
  if (automationTypeId === 1 || automationTypeId === 3) {
    return findDuplicateRulestype1and3(allRecords);
  }else 
  console.warn("⚠️ Unknown automationTypeId:", automationTypeId);
  return allRecords;
}

function handleFetchError(error) {
  console.error("❌ Error fetching filtered records:", error);
  hideLoader();
  if (error.status === 429) {
    document.getElementById("Automation-page").style.display = "none";
    document.getElementById("Workflow-Automation-page").style.display = "none";
    document.getElementById("no_user3").style.display = "block";
  }
  return [];
}

function getDisplayIdByRuleId(entityRecords, id) { //11
  console.log("getdisplayid function Rule ID:", id); //12

  if (!Array.isArray(entityRecords) || entityRecords.length === 0) {
    console.warn(" No records found in entity storage.");
    return { displayId: null, updatedArray: entityRecords };
  }

  const recordIndex = entityRecords.findIndex(record =>
    String(record?.data?.rule_id) === String(id) //13
  );

  if (recordIndex === -1) {
    console.warn(`❌ Rule ID ${id} not found in records.`);//14
    return { displayId: null, updatedArray: entityRecords };
  }

  const matchedRecord = entityRecords[recordIndex];
  const displayId = matchedRecord.display_id;

  // ✅ Remove the record from the original array
  entityRecords.splice(recordIndex, 1);

  console.log(`✅ Record with Rule ID ${id} and Display ID ${displayId} removed.`);//15

  return { displayId, updatedArray: entityRecords };
}


// recenetconfirmDeletion starting
async function recenetconfirmDeletion(id, automation_type_id) {
  console.log("entered into recentdeletfunction");
  console.log("Deleting rule with ID:", id, typeof id);
  console.log("count no 1 delete function called ******************");
  console.log("automation type id log", automation_type_id);

  const progressLoader = document.querySelector("#progress-container");

  try {
    if (progressLoader?.start) progressLoader.start();

    const response = await client.request.invokeTemplate("deleterule", {
      context: { automationid: automation_type_id, ruleid: id },
    });

    if (response.status === 204) {
      showSuccessToast("Rule deleted successfully");

      if (Number(automation_type_id) === 1) {
        await handleAutomationType1(id, automation_type_id, progressLoader);
      } else if (Number(automation_type_id) === 3) {
        await handleAutomationType3(id, automation_type_id, progressLoader);
      } else {
        console.warn("Unhandled automation ID:", automation_type_id);
      }
    }
  } catch (error) {
    await handleDeletionError1(error, progressLoader);
  }
}
function showSuccessToast(message) {
  const valid = document.getElementById("type_toast");
  valid.setAttribute("content", message);
  valid.setAttribute("type", "success");
  valid.setAttribute("open", true);
}
async function handleAutomationType1(id, automation_type_id, progressLoader) {
  const ruleIndex = duplicatesType1.findIndex(rule => String(rule.id) === String(id));
  if (ruleIndex !== -1) {
    const ruleToDelete = duplicatesType1[ruleIndex];
    duplicatesType1.splice(ruleIndex, 1);
    console.log("Removed from duplicatesType1:", ruleToDelete.id);
    displayGroupedRules4(duplicatesType1, "Ticketcreation1", automation_type_id, globalAgents);
    await safelyFinishProgressLoader(progressLoader);
  } else {
    console.warn(`Rule ID ${id} not found in duplicatesType1`);
  }

if (!Array.isArray(window.entitytype1) || window.entitytype1.length === 0) {
  window.entitytype1 = await Fetchentity(1);
}

  const { displayId, updatedArray } = getDisplayIdByRuleId(entitytype1, id);
  displayGroupedRules(updatedArray, "Ticketcreation");

  if (displayId) await safelyDeleteRecord(displayId);
}
async function handleAutomationType3(id, automation_type_id, progressLoader) {
  const ruleIndex = duplicatesType3.findIndex(rule => String(rule.id) === String(id));
  if (ruleIndex !== -1) {
    const ruleToDelete = duplicatesType3[ruleIndex];
    duplicatesType3.splice(ruleIndex, 1);
    console.log("Removed from duplicatesType3:", ruleToDelete.id);
    displayGroupedRules4(duplicatesType3, "HourlyTriggers1", automation_type_id, globalAgents);
    await safelyFinishProgressLoader(progressLoader);
  } else {
    console.warn(`Rule ID ${id} not found in duplicatesType3`);
  }

if (!Array.isArray(window.entitytype3) || window.entitytype3.length === 0) {
  window.entitytype3 = await Fetchentity(3);
}


  const { displayId, updatedArray } = getDisplayIdByRuleId(entitytype3, id);
  displayGroupedRules(updatedArray, "HourlyTriggers");

  if (displayId) await safelyDeleteRecord(displayId);
}
async function handleDeletionError1(error, progressLoader) {
  console.error("Error deleting rule:", error);
  await safelyFinishProgressLoader(progressLoader);

  if (error.status === 404) {
    const toast = document.getElementById("type_toast");
    toast.setAttribute("content", "Rule not found. Try refreshing the page.");
    toast.setAttribute("type", "error");
    toast.setAttribute("open", true);
  }
}
async function safelyFinishProgressLoader(progressLoader) {
  try {
    if (progressLoader?.done) await progressLoader.done();
  } catch (e) {
    console.warn("⚠️ progressLoader.done() failed:", e);
  }
}
async function safelyDeleteRecord(displayId) {
  try {
    console.log("Deleting record with Display ID:", displayId);
    await newRulePloadDB5.delete(displayId);
  } catch (error) {
    console.warn(`Error deleting Display ID ${displayId}, continuing...`);
  }
}


// recenetconfirmDeletion ending


function combineConditionsAndActions({
  condition_set_1_summary,
  condition_set_2_summary,
  operator,
  condition_set_1_real,
  condition_set_2_real,
  actions_summary,
  actions_real,
  performer = "",
  eventText = []
}) {
  const processedPerformer = normalizeText(stripHTML4(performer));
  const processedEventText = processEventText(eventText);

  const originalConditions = buildOriginalConditions1(condition_set_1_summary, condition_set_2_summary, operator);
  const originalActionText = buildOriginalActions1(actions_summary);
  const originalContent = `${stripHTML4(performer)} ${eventText.map(stripHTML4).join(" ")} ${originalConditions} ${originalActionText}`.trim();

  const sortedConditions = buildSortedConditions1(condition_set_1_real, condition_set_2_real, operator);
  const sortedActions = buildSortedActions1(actions_real);

  const sortedContent = `${processedPerformer} ${processedEventText} ${sortedConditions} ${sortedActions}`.trim();

  return { originalContent, sortedContent };
}

function processEventText(eventText) {
  return eventText.map(e => normalizeText(stripHTML4(e))).sort().join(" ");
}

function buildOriginalConditions1(set1, set2, operator) {
  const processedSet1 = (set1 || []).map(stripHTML4);
  const processedSet2 = (set2 || []).map(stripHTML4);
  const op = operator ? ` ${operator} ` : "";
  return [...processedSet1, op, ...processedSet2].join(" ");
}

function buildOriginalActions1(actions) {
  return Array.isArray(actions) && actions.length > 0 ? actions.map(stripHTML4).join(" ") : "";
}

function buildSortedConditions1(real1, real2, operator) {
  const normalizedSet1 = normalizeConditionProps(real1);
  const normalizedSet2 = normalizeConditionProps(real2);
  const all = [...normalizedSet1, ...normalizedSet2].sort((a, b) => a.localeCompare(b));
  return [...all, normalizeText(operator || "")].join(" ");
}

function buildSortedActions1(actions) {
  return (actions || []).map(normalizeAction).sort().join(" ");
}


//arrow function's helper function
function extractRuleFromRecord(record) {
  return record.parsedPayload || record.rule || record;
}

function isValidRule(rule, record) {
  if (!rule || !rule.summary) {
    console.warn("Skipping record due to missing data:", record);
    return false;
  }
  return rule.summary.conditions !== undefined;
}

function extractSummaryDetails(summary) {
  return {
    performer: summary.performer || "",
    actions: summary.actions || [],
    eventText: summary.events || []
  };
}

window.currentPageDuplicates = 1;
const itemsPerPageDuplicates = 5;

function processAndDisplayDuplicates(duplicates, containerId, globalAgents) 
 {
  console.log("function processAndDisplayDuplicates called",globalAgents);

  const container = document.getElementById(containerId);
  if (!container) {
    console.error(`Container with ID "${containerId}" not found.`);
    return;
  }

  container.innerHTML = ""; // Clear container

 
  if (duplicates.length <= 1) {
    container.innerHTML = `
    <div style="
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80%;
  font-size: 24px;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin: 300px auto; /* Push it down + center horizontally */
">
 

          No duplicate rules found.
      </div>`;
return;
  }


  const groupedRules = new Map();

 duplicates.forEach((record) => {
  const rule = extractRuleFromRecord(record);
  if (!isValidRule(rule, record)) return;

  const { name, summary, position, updated_at, last_updated_by, affected_tickets_count, id } = rule;
  const { performer, actions, eventText } = extractSummaryDetails(summary);

  const { originalContent, sortedContent } = combineConditionsAndActions({
    performer,
    eventText,
    condition_set_1_summary: summary.conditions.condition_set_1,
    condition_set_2_summary: summary.conditions.condition_set_2,
    operator: summary.conditions.operator,
    condition_set_1_real: record.conditions.filter(cond => cond.name === "condition_set_1"),
    condition_set_2_real: record.conditions.filter(cond => cond.name === "condition_set_2"),
    actions_summary: summary.actions,
    actions_real: record.actions
  });

  if (!groupedRules.has(sortedContent)) {
    groupedRules.set(sortedContent, []);
  }

  groupedRules.get(sortedContent).push({
    name,
    position,
    combinedContent: originalContent,
    performer,
    eventText,
    conditions: summary.conditions,
    actions,
    updated_at,
    last_updated_by,
    affected_tickets_count,
    id,
  });
});


  const groupedRulesArray = Array.from(groupedRules.values()).filter(group => group.length > 1);

  const totalgroup = Math.ceil(groupedRulesArray.length );
  console.log(totalgroup,"*********************")
  const totalPagesDuplicates = Math.ceil(groupedRulesArray.length / itemsPerPageDuplicates);
  window.currentPageDuplicates = Math.max(1, Math.min(currentPageDuplicates, totalPagesDuplicates));

  console.log("Total Pages:", totalPagesDuplicates, "Current Page:", currentPageDuplicates);

  const startIdx = (currentPageDuplicates - 1) * itemsPerPageDuplicates;
  const paginatedRules = groupedRulesArray.slice(startIdx, startIdx + itemsPerPageDuplicates);

  console.log("Displaying Records:", paginatedRules);
  
  const arrayLength = paginatedRules.length;
  console.log("Records Length:", arrayLength);

  paginatedRules.forEach((titles) => {
    const rulesCount = titles.length;
  if (arrayLength === 0) {
  console.log("Array is empty.");
     container.innerHTML = `
    <div style="
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80%;
  font-size: 24px;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin: 300px auto; /* Push it down + center horizontally */
">
 

          No duplicate rules found.
      </div>`;
    return;
}
    // ✅ Skip the group if it contains only one rule
    if (rulesCount === 1) {
        console.log(`Skipping group with only 1 rule: ${titles[0].name}`);
        return; // Stop further execution for this group
    }
    const groupContainer = document.createElement("div");
    groupContainer.style.border = "1px solid #ccc";
    groupContainer.style.padding = "16px";
    groupContainer.style.margin = "16px";
    groupContainer.style.borderRadius = "8px";
    groupContainer.style.backgroundColor = "#f5f7f9";
    groupContainer.style.width = "87%";
  
    titles.forEach(({ name, position, combinedContent, performer, 
      eventText, conditions, actions,updated_at,
      last_updated_by,
      affected_tickets_count,id}, index) => {
      const card = document.createElement("div");
      card.style.border = "1px solid #ccc";
      card.style.padding = "16px";
      card.style.margin = "8px 0";
      card.style.fontFamily =
        "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
      card.style.borderRadius = "8px";
      card.style.backgroundColor = index === 0 ? "#fff" : "#e5f2fd";
      card.style.marginBottom = "10px";
      card.style.paddingBottom = "0";
     card.style.overflow="hidden";
  
      const cardHeader = document.createElement("div");
      cardHeader.style.display = "flex";
      cardHeader.style.justifyContent = "space-between";
      cardHeader.style.alignItems = "center";
    // Create a wrapper for the title
const cardTitle = document.createElement("h4");
cardTitle.style.margin = "0";
cardTitle.style.cursor = "pointer";
cardTitle.style.fontSize = "14px";
cardTitle.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
cardTitle.style.color = "#183247";
cardTitle.style.transition = "color 0.2s ease";
cardTitle.style.fontWeight = "600"; 

// Create the serial number (position)
if (position) {
const serialNumber = document.createElement("span");
serialNumber.textContent = position + ". ";
serialNumber.style.color = "#183247"; // Keep serial number color fixed
cardTitle.appendChild(serialNumber);
}

// Create the actual name (clickable part)
const titleText = document.createElement("span");
titleText.textContent = name;
titleText.style.color = "#183247"; 
titleText.style.transition = "color 0.2s ease";

// Add hover effect for only the name
titleText.addEventListener("mouseover", () => {
titleText.style.color = "#007bff"; // Change only name color on hover
});
titleText.addEventListener("mouseout", () => {
titleText.style.color = "#183247"; // Reset name color when not hovering
});
window.isPopupOpen = false;
titleText.addEventListener("click", () => {
titleText.style.color = "#ff5733"; // Change title color on click
  if (window.isPopupOpen) return; 
  window.isPopupOpen = true;
showPopupCard1(name, { performer: performer, 
eventText: eventText, conditions: conditions, actions: actions, });
});

// Append name to title
cardTitle.appendChild(titleText);
      // Append title and actions to the cardHeader
      cardHeader.appendChild(cardTitle);
      

      const cardContainer = document.createElement("div");

// Style the container to have a background color in the gap
cardContainer.style.backgroundColor = "#f0f0f0";  // Set the background color for the gap (change to desired color)
cardContainer.style.paddingBottom = "20px";  
cardContainer.style.marginLeft="-15px";
cardContainer.style.borderRadius = "4px";
// cardContainer.style.width="103%";
cardContainer.style.position = "relative";

cardContainer.style.width = "calc(103% + 30px)";

// Create a horizontal line after the cardBody
const horizontalLine = document.createElement("div");
horizontalLine.style.height = "1px"; // Set the height to 1px for a thin line
horizontalLine.style.backgroundColor = "#ccc"; // Set the color of the horizontal line
horizontalLine.style.marginTop = "16px"; // Add space above the line (adjust as needed)
horizontalLine.style.width = "100%"; // Ensure the line stretches the full width of the container
horizontalLine.style.marginLeft="-3px";

function truncateTextByLength(content, maxLength) {
  return content.length > maxLength ? content.slice(0, maxLength) + "..." : content;
}

function splitIntoLines(text, maxLength, lines) {
  const words = text.split(" ");
  const result = [];
  let line = "";
  let currentLine = 1;
  const maxPerLine = Math.floor(maxLength / lines);

  for (const word of words) {
    if ((line + " " + word).trim().length <= maxPerLine) {
      line += (line ? " " : "") + word;
    } else {
      result.push(line);
      line = word;
      currentLine++;
      if (currentLine > lines) break;
    }
  }

  if (currentLine <= lines && line) {
    result.push(line);
  }

  return {
    text: result.join(" "),
    truncated: currentLine > lines,
  };
}

function truncateContent(content, maxLength, lines) {
  const truncated = truncateTextByLength(content, maxLength);
  const { text, truncated: wasTruncated } = splitIntoLines(truncated, maxLength, lines);
  return text + (wasTruncated ? "..." : "");
}

      
      const lastModifiedRow = document.createElement("div");
      lastModifiedRow.style.display = "grid";
      lastModifiedRow.style.gridTemplateColumns = "repeat(auto-fit, minmax(150px, 1fr))"; // Responsive columns with minimum size 150px
      lastModifiedRow.style.alignItems = "center";
      lastModifiedRow.style.gap = "16px"; // Space between items
      lastModifiedRow.style.width = "100%"; // Ensure full width
      lastModifiedRow.style.gridTemplateRows = "auto"; // Auto row size to fit content
      
      // Function to create a label-value pair container
      function createLabelValue(labelText, valueText) {
        const container = document.createElement("div");
        container.style.display = "flex";
        container.style.flexDirection = "row"; // Make sure content is horizontal
        container.style.alignItems = "center"; // Align vertically in center
      
        const label = document.createElement("span");
        label.textContent = labelText;
        label.style.color = "#183247";
        label.style.marginTop = "10px";
        label.style.marginLeft = "15%";
        label.style.fontSize = "12px";
        label.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";

        
        const value = document.createElement("span");
        value.textContent = valueText;
        value.style.color = "#183247";
        value.style.fontWeight = "600";
        value.style.fontSize = "12px";
        value.style.marginTop = "10px";
        value.style.marginLeft = "10px";
        value.style.fontFamily ="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";

        value.style.marginLeft = "10px"; // Add space between label and value
      
        container.appendChild(label);
        container.appendChild(value);
      
        return container;
      }
      
      // Create and append content to the lastModifiedRow
      const lastModifiedText = calculateLastModified(updated_at);
      lastModifiedRow.appendChild(createLabelValue("Last Modified :", lastModifiedText));
      
      // Vertical line between sections
      const verticalLine = document.createElement("div");
      verticalLine.style.gridRow = "span 1"; // Ensuring vertical line doesn't span more than one row
      verticalLine.style.height = "20px"; 
      verticalLine.style.marginTop = "10px";
      verticalLine.style.marginLeft = "30px"; // Add gap at the top// Adjust the height as needed
      verticalLine.style.borderLeft = "2px solid #ccc";
      lastModifiedRow.appendChild(verticalLine);
      
      // Matching agent data
      const agentsid = last_updated_by;
      // console.log("********** agents (type):", typeof agents, agents);
  // console.log("********** window.globalAgents (type):",globalAgents);
      const matchingAgent = window.globalAgents.find(agent => String(agent.id) === String(agentsid));
      const agentNameText = matchingAgent ? matchingAgent.contact.name : "Unknown Agent";
      lastModifiedRow.appendChild(createLabelValue("By :", agentNameText));
      
      // Vertical line after the agent name
      const verticalLine2 = document.createElement("div");
      verticalLine2.style.gridRow = "span 1"; // Same for second vertical line
      verticalLine2.style.height = "20px";
      verticalLine2.style.marginTop = "10px"; 
      verticalLine2.style.marginLeft = "30px"; // Adjust the height as needed
      verticalLine2.style.borderLeft = "2px solid #ccc";
      lastModifiedRow.appendChild(verticalLine2);
      
      // Impacted tickets info
      const affectedTicketsText = affected_tickets_count === 0 ? "--" : affected_tickets_count;
      // lastModifiedRow.appendChild(createLabelValue("Impacted tickets (Last 7 days) :", affectedTicketsText));
      
      const impactedTickets = createLabelValue("Impacted tickets (Last 7 days) :", affectedTicketsText);
  impactedTickets.firstChild.style.marginLeft = "-50%"; // Adjust label alignment
  lastModifiedRow.appendChild(impactedTickets);




const cardBody = document.createElement("div"); // Create a container for card content and actions
cardBody.style.display = "flex"; // Flexbox to align items horizontally
cardBody.style.justifyContent = "space-between"; // Ensure there's space between content and actions
cardBody.style.alignItems = "flex-start"; // Align items to the top (optional, depending on your needs)
       

const truncatedContent = truncateContent(combinedContent, 200, 2);

const cardContent = document.createElement("pre");
cardContent.textContent = truncatedContent;

// Style the card content
cardContent.style.marginTop = "8px";
cardContent.style.padding = "8px";
cardContent.style.whiteSpace = "pre-wrap"; // Ensure text wraps
cardContent.style.overflow = "hidden"; // Hide overflow content
cardContent.style.textOverflow = "ellipsis"; // Add ellipsis for overflow
cardContent.style.maxWidth = "75%"; // Limit the card width to half the container's width
cardContent.style.fontSize="12px";
cardContent.style.color="#183247";
cardContent.style.fontweight="600";
cardContent.style.fontFamily= "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
cardContent.style.marginLeft="15px"

// Create the container for card actions
const cardActionsContainer = document.createElement("div");
cardActionsContainer.style.display = "flex"; // Display actions horizontally
cardActionsContainer.style.justifyContent = "flex-end"; // Align to the right
cardActionsContainer.style.marginTop = "10px"; // Add some spacing above the actions
cardActionsContainer.style.gap = "8px"; // Set space between the toggle and the delete icon

function popupmodal() {
  if (!document.getElementById("deleteConfirmationPopup")) {
    const modal = document.createElement("fw-modal");
    modal.setAttribute("id", "deleteConfirmationPopup");
    modal.setAttribute("title-text", "Delete Rule");
    modal.innerHTML = `
      <fw-text>Are you sure you want to delete the rule?</fw-text>
      <fw-modal-footer></fw-modal-footer>
    `;
    document.body.appendChild(modal);
  }
}
      const fwIcon = document.createElement("fw-icon");
      fwIcon.setAttribute("name", "delete");
      fwIcon.setAttribute("size", "18");
      fwIcon.style.cursor = "pointer";
      fwIcon.style.color = "red"; // Set the color to red
      // Add a pointer cursor for interactivity
      fwIcon.title = "Delete";
      fwIcon.addEventListener("click", () => {
  console.log("Delete icon clicked in ticket updation");
    

 popupmodal();

  const modal = document.getElementById("deleteConfirmationPopup");
  // const footer = modal.querySelector("fw-modal-footer");

  // Remove old listeners from modal
  const newModal = modal.cloneNode(true);
  modal.replaceWith(newModal);

  // Reassign modal after clone
  const freshModal = document.getElementById("deleteConfirmationPopup");
  const freshFooter = freshModal.querySelector("fw-modal-footer");

  // Add listeners
  freshModal.addEventListener("fwSubmit", () => {
    console.log("Delete confirmed.");
    try {
     confirmDeletions(id);
    } catch (error) {
      console.error("❌ Error in deletion process inside event listener:", error);
    }
    freshModal.removeAttribute("is-open");
  });

  freshFooter.addEventListener("fwClose", () => {
    freshModal.removeAttribute("is-open");
    console.log("Delete operation was cancelled.");
  });

  // Open modal
  freshModal.setAttribute("is-open", "true");
});
      
cardActionsContainer.appendChild(fwIcon);
card.appendChild(cardHeader);
cardBody.appendChild(cardContent);
cardBody.appendChild(cardActionsContainer);
card.appendChild(cardBody);
cardContainer.appendChild(horizontalLine);
// card.appendChild(horizontalLine);

cardContainer.appendChild(lastModifiedRow);
card.appendChild(cardContainer)
groupContainer.appendChild(card);
    });

    
    container.appendChild(groupContainer);
  });


  addFwPaginationDuplicates(containerId, duplicates,totalgroup);
}


function addFwPaginationDuplicates(containerId, duplicates, totalgroup) {
  const itemsPerPage = itemsPerPageDuplicates;
  const totalPages = Math.ceil(totalgroup / itemsPerPage);
  console.log("Adding Bootstrap pagination to container:", containerId);

  const container = document.getElementById(containerId);
  if (!container) {
    console.warn(`Container with ID "${containerId}" not found.`);
    return;
  }

  if (totalgroup <= itemsPerPage) {
    console.log("Total records are less than or equal to items per page, skipping pagination.");
    return;
  }

  const existingPagination = container.querySelector("#bootstrap-pagination-duplicates");
  if (existingPagination) existingPagination.remove();

  const paginationWrapper = document.createElement("nav");
  paginationWrapper.setAttribute("aria-label", "Page navigation");
  paginationWrapper.id = "bootstrap-pagination-duplicates";
  paginationWrapper.style.marginLeft = "40%";

  const ul = document.createElement("ul");
  ul.className = "pagination";

  const onPageChange = () => {
    processAndDisplayDuplicates(duplicates, containerId, globalAgents);
    addFwPaginationDuplicates(containerId, duplicates, totalgroup);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  ul.appendChild(createPrevNextButtonDuplicates(currentPageDuplicates, totalPages, true, onPageChange));  // Previous
  ul.appendChild(createPageNumberLinksDuplicates(totalPages, currentPageDuplicates, onPageChange));       // Numbers
  ul.appendChild(createPrevNextButtonDuplicates(currentPageDuplicates, totalPages, false, onPageChange)); // Next

  paginationWrapper.appendChild(ul);
  container.appendChild(paginationWrapper);
}
function createPaginationLinkDuplicates(text, isDisabled, onClickHandler, isActive = false) {
  const li = document.createElement("li");
  li.className = "page-item" + (isDisabled ? " disabled" : "") + (isActive ? " active" : "");

  const link = document.createElement("a");
  link.className = "page-link" + (isDisabled ? " disabled-hover" : "");
  link.href = "#";
  link.innerHTML = text;

  if (isDisabled) {
    link.setAttribute("tabindex", "-1");
    link.setAttribute("aria-disabled", "true");
  }

  link.addEventListener("click", (e) => {
    e.preventDefault();
    if (!isDisabled) onClickHandler();
  });

  li.appendChild(link);
  return li;
}

function createPrevNextButtonDuplicates(currentPage, totalPages, isPrev, onPageChange) {
  const isDisabled = isPrev ? currentPage === 1 : currentPage === totalPages;
  const text = isPrev
    ? `<span class="label-wrapper">&laquo; Previous<span class="hover-symbol" aria-hidden="true">🚫</span></span>`
    : `<span class="label-wrapper">Next &raquo;<span class="hover-symbol" aria-hidden="true">🚫</span></span>`;

  const handler = () => {
    if (isPrev) currentPageDuplicates--;
    else currentPageDuplicates++;

    onPageChange();
  };

  return createPaginationLinkDuplicates(text, isDisabled, handler);
}

function createPageNumberLinksDuplicates(totalPages, currentPage, onPageChange) {
  const fragment = document.createDocumentFragment();

  for (let i = 1; i <= totalPages; i++) {
    const handler = () => {
      if (window.currentPageDuplicates !== i) {
        window.currentPageDuplicates = i;
        onPageChange();
      }
    };

    const li = createPaginationLinkDuplicates(i, false, handler, i === currentPage);
    li.querySelector("a").textContent = i;
    fragment.appendChild(li);
  }

  return fragment;
}


async function Fetchentity1(automationTypeId, nextMarker = null, allRecords1 = []) {
  try {
    await ensureDatabaseReady();

    await showLoader();

    const queryObj = buildQueryObject1(automationTypeId, nextMarker);
    const response = await newRulePloadDB5.getAll(queryObj);

    if (!Array.isArray(response.records)) {
      console.error("❌ Invalid response format:", response);
      await hideLoader();
      return allRecords1;
    }

    console.log(`📥 Retrieved ${response.records.length} records`);
    window.allRecords1 = allRecords1.concat(response.records);

    const newNextMarker = response.links?.next?.marker || null;
    if (newNextMarker) {
      console.log(`More pages exist. Next marker: ${newNextMarker}`);
      return Fetchentity1(automationTypeId, newNextMarker, allRecords1);
    }

    console.log("✅ No more pages.");
    console.log(`📌 Total Filtered Records: ${allRecords1.length}`);
    await hideLoader();

    return handleFinalResponse(automationTypeId, window.allRecords1);
  } catch (error) {
    return handleFetchError2(error);
  }
}
async function ensureDatabaseReady() {
  if (!newRulePloadDB5) {
    console.error("Entity is not initialized yet!");
    await showLoader();
    setTimeout(() => location.reload(), 1000);
    throw new Error("DB not initialized");
  }
}
function buildQueryObject1(automationTypeId, nextMarker) {
  const query = {
    query: {
      $and: [
        { automation_type_id: automationTypeId },
        { active: "true" }
      ]
    }
  };

  if (nextMarker) {
    console.log("Next marker found:", nextMarker);
    query.next = { marker: nextMarker };
  }

  console.log("📤 Fetching records with query:", JSON.stringify(query, null, 2));
  return query;
}
function handleFinalResponse(automationTypeId, records) {
  if (automationTypeId === 4) {
    return findDuplicateRulestype4(records);
  } else {
    console.warn("⚠️ Unknown automationTypeId:", automationTypeId);
    return records;
  }
}
async function handleFetchError2(error) {
  console.error("❌ Error fetching filtered records:", error);
  await hideLoader();

  if (error.status === 429) {
    document.getElementById("Automation-page").style.display = "none";
    document.getElementById("Workflow-Automation-page").style.display = "none";
    document.getElementById("no_user3").style.display = "block";
  }

  return [];
}


async function confirmDeletions(id) {
  console.log("Deleting rule with ID:", id);

  const progressLoader = document.querySelector("#progress-container");
  if (progressLoader?.start) progressLoader.start();

  try {
    const response = await deleteRuleFromServer(id);
    if (response.status === 204) {
      showSuccessToast("Rule deleted successfully");
      removeDeletedRuleFromUI(id);

      updateDuplicatesType4(id);
      processAndDisplayDuplicates(duplicatesType4, "TicketUpdates1", globalAgents);
      await ensureEntityType4Loaded();

      const { displayId, updatedArray } = getDisplayIdByRuleId1(entitytype4, id);
      displayGroupedRules(updatedArray, "TicketUpdates");
      if (displayId) await safelyDeleteByDisplayId(displayId);
    }
  } catch (error) {
    await handleConfirmDeletionError(error);
  } finally {
  try {
    if (progressLoader?.done) await progressLoader.done();
  } catch (e) {
    console.warn("⚠️ progressLoader.done() failed in finally:", e);
  }
}

}
async function deleteRuleFromServer(id) {
  const response = await client.request.invokeTemplate("deleterule", {
    context: { automationid: 4, ruleid: id },
  });
  console.log("getdeleteruleResponse", response);
  return response;
}
function updateDuplicatesType4(id) {
  const ruleIdStr = String(id);
  const index = duplicatesType4.findIndex(rule => String(rule.id) === ruleIdStr);
  console.log("Rule index found:", index);

  if (index !== -1) {
    duplicatesType4.splice(index, 1);
    console.log("✅ Rule removed from duplicatesType4.");
  } else {
    console.warn("⚠️ Rule not found in duplicatesType4. Possible ID mismatch.");
  }

  console.log("Duplicates after deleting:", duplicatesType4);
}
async function ensureEntityType4Loaded() {
  if (!Array.isArray(window.entitytype4) || window.entitytype4.length === 0) {
        console.log("entitytype4 is empty. Fetching records...");
        window.entitytype4 = await Fetchentity1(4);
}

}
async function safelyDeleteByDisplayId(displayId) {
  try {
    console.log("Deleting record with Display ID:", displayId);
    await newRulePloadDB5.delete(displayId);
  } catch (error) {
    console.warn(`Error deleting record with Display ID ${displayId}, continuing...`);
  }
}
async function handleConfirmDeletionError(error) {
  const progressLoader = document.querySelector("#progress-container");
  if (progressLoader?.done) {
    try {
      await progressLoader.done();
    } catch (e) {
      console.warn("⚠️ progressLoader.done() failed:", e);
    }
  }

  if (error.status === 404) {
    const toast = document.getElementById("type_toast");
    toast.setAttribute("content", "Rule not found. Try refreshing the page.");
    toast.setAttribute("type", "error");
    toast.setAttribute("open", true);
  }

  console.error("❌ Error deleting rule:", error);
}

// Function to remove the deleted rule from UI
function removeDeletedRuleFromUI(ruleId) {
    const ruleCard = document.querySelector(`[data-rule-id="${ruleId}"]`);
    if (ruleCard) {
        ruleCard.remove();
    }
}
function getDisplayIdByRuleId1(entityRecords, id) {

  console.log("Checking all records for Rule ID:", id,entityRecords);

  if (!Array.isArray(entityRecords) || entityRecords.length === 0) {
    console.warn(" No records found in entity storage.");
    return { displayId: null, updatedArray: entityRecords };
  }

  const recordIndex = entityRecords.findIndex(record =>
    String(record?.data?.rule_id) === String(id)
  );

  if (recordIndex === -1) {
    console.warn(`❌ Rule ID ${id} not found in records.`);
    return { displayId: null, updatedArray: entityRecords };
  }

  const matchedRecord = entityRecords[recordIndex];
  const displayId = matchedRecord.display_id;

  // ✅ Remove the record from the original array
  entityRecords.splice(recordIndex, 1);

  console.log(`✅ Record with Rule ID ${id} and Display ID ${displayId} removed.`);

  return { displayId, updatedArray: entityRecords };
}



//new filterrecords starting
async function Filterrecords(automationTypeId, containerid, nextMarker = null, allRecords = []) {
  try {
    await ensureLoaderShown(containerid);
    
    const queryObj = buildQuery(automationTypeId, nextMarker);
    const response = await newRulePloadDB5.getAll(queryObj);

    if (!Array.isArray(response?.records)) {
      console.error("❌ Invalid response format:", response);
      return [];
    }

    const combinedRecords = allRecords.concat(response.records);
    const newNextMarker = response.links?.next?.marker || null;

    if (newNextMarker) {
      console.log(`🔄 More pages exist. Next marker: ${newNextMarker}`);
      return await Filterrecords(automationTypeId, containerid, newNextMarker, combinedRecords);
    }

    await hideLoader();
    return routeToDuplicateCheck(automationTypeId, combinedRecords);

  } catch (error) {
    await handleFilterError(error);
    return [];
  }
}
async function ensureLoaderShown(containerid) {
  if (!newRulePloadDB5) {
    console.error("❗ Entity is not initialized yet!");
    await showLoader();
  }

  if (["Ticketcreation", "TicketUpdates", "HourlyTriggers"].includes(containerid)) {
    await showLoader(containerid);
  }
}

function buildQuery(automationTypeId, nextMarker) {
  const query = {
    query: {
      $and: [
        { automation_type_id: automationTypeId },
        { active: "true" }
      ]
    }
  };

  if (nextMarker) {
    query.next = { marker: nextMarker };
  }

  console.log("📤 Fetching records with query:", JSON.stringify(query, null, 2));
  return query;
}

function routeToDuplicateCheck(automationTypeId, records) {
  console.log("📦 All records fetched:", records.length);
  records.forEach((record, index) => {
  console.log(`📄 Record ${index + 1}:`, record);
});


  if (automationTypeId === 1 || automationTypeId === 3) {
    return findDuplicateRulestype1and3(records);
  } else if (automationTypeId === 4) {
    return findDuplicateRulestype4(records);
  }

  console.warn("⚠️ Unknown automationTypeId:", automationTypeId);
  return records;
}

async function handleFilterError(error) {
  console.error("❌ Error fetching filtered records:", error);
  await hideLoader();

  if (error.status === 429) {
    document.getElementById("Automation-page").style.display = "none";
    document.getElementById("Workflow-Automation-page").style.display = "none";
    document.getElementById("no_user3").style.display = "block";
  }
}
// const findDuplicateRulestype1and3 = (records) => {
//   const seenRules = new Map();
//   const duplicateRecords = [];

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

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

//     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, "")   // remove hidden unicode
//       .replace(/[.]/g, "")                    // remove full stops
//       .replace(/\s*,\s*/g, ",")               // normalize comma spacing
//       .replace(/\s+/g, " ")                   // normalize spacing
//       .trim()
//       .toLowerCase();
//   };

//   const normalizeConditionParts = (rawConditions) => {
//     const parts = rawConditions?.split(",") || [];
//     const set1 = [];
//     const set2 = [];
//     let currentSet = null;
//     let tempClause = [];

//     const pushClause = (targetSet) => {
//       if (tempClause.length && targetSet) {
//         const joinedClause = tempClause.join(",").trim();
//         const cleaned = stripHTML4(joinedClause);
//         if (cleaned) targetSet.push(cleaned);
//         tempClause = [];
//       }
//     };

//     for (let i = 0; i < parts.length; i++) {
//       const rawPart = parts[i].trim().toLowerCase();

//       if (rawPart.includes("condition_set_1")) {
//         pushClause(currentSet);
//         currentSet = set1;
//         continue;
//       }
//       if (rawPart.includes("condition_set_2")) {
//         pushClause(currentSet);
//         currentSet = set2;
//         continue;
//       }

//       if (rawPart === "any" || rawPart === "all") {
//         pushClause(currentSet);
//         continue;
//       }

//       if (currentSet) {
//         tempClause.push(parts[i]); // preserve comma structure
//       }
//     }

//     pushClause(currentSet);
//     set1.sort();
//     set2.sort();

//     console.log("🔹 Sorted Set1:", set1);
//     console.log("🔸 Sorted Set2:", set2);

//     return { set1, set2 };
//   };

// const normalizeActions = (rawActions) => {
//   const parts = rawActions?.split("&?") || [];
//   const normalizedClauses = [];

//   for (let part of parts) {
//     const items = part.split(",").map((v) => stripHTML4(v));
//     const clause = items.sort().join(" "); // ignore order inside clause
//     if (clause.trim()) normalizedClauses.push(clause);
//   }

//   normalizedClauses.sort(); // ensure clause order doesn't matter

//   return normalizedClauses.join(" | "); // or return as array
// };
//   // const normalizeActions = (actions) => {
//   //   if (Array.isArray(actions)) {
//   //     const normalized = actions
//   //       .map((action) =>
//   //         Object.values(action)
//   //           .map((v) => stripHTML4(v))
//   //           .join(" ")
//   //       )
//   //       .sort()
//   //       .join(",");
//   //     console.log("⚙️ Normalized Actions (Array):", normalized);
//   //     return normalized;
//   //   } else if (typeof actions === "string") {
//   //     const normalized = actions
//   //       .split(",")
//   //       .map((a) => stripHTML4(a))
//   //       .filter((a) => a !== "")
//   //       .sort()
//   //       .join(",");
//   //     console.log("⚙️ Normalized Actions (String):", normalized);
//   //     return normalized;
//   //   }
//   //   console.log("⚙️ Normalized Actions: Empty");
//   //   return "";
//   // };

//   records.forEach((record, idx) => {
//     console.log(`\n📦 Processing Record #${idx + 1}`, record);

//     const { conditions, actions, operator } = record.data;

//     const { set1, set2 } = normalizeConditionParts(conditions);
//     const normalizedActions = normalizeActions(actions);
//     const normalizedOperator = operator ? stripHTML4(operator) : "";

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

//     console.log("🗝️ Key1:", key1);
//     console.log("🗝️ Key2:", key2);

//     if (seenRules.has(key1) || seenRules.has(key2)) {
//       const existing = seenRules.get(key1) || seenRules.get(key2);
//       console.warn("❗ Duplicate Detected");
//       if (!duplicateRecords.includes(existing)) {
//         console.log("➕ Adding first matched record to duplicates");
//         duplicateRecords.push(existing);
//       }
//       console.log("➕ Adding current record to duplicates");
//       duplicateRecords.push(record);
//     } else {
//       console.log("✅ Unique Rule — storing key1");
//       seenRules.set(key1, record);
//     }
//   });

//   console.log(`\n🎯 Total Duplicates Found: ${duplicateRecords.length}`);
//   return duplicateRecords;
// };
// final code 
const findDuplicateRulestype1and3 = (records) => {
  const seenRules = new Map();
  const duplicateRecords = [];
const stripHTML4 = (htmlString) => {
  if (typeof htmlString !== "string") {
    htmlString = String(htmlString || "");
  }

  const div = document.createElement("div");
  div.innerHTML = htmlString.replace(/&nbsp;/gi, " "); // Convert &nbsp; to space for safe parsing

  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, "")  // Remove hidden/unicode spaces
    .replace(/\./g, "")                   // Remove full stops
    .replace(/\s+/g, "")                  // 🔥 Remove ALL spaces
    .toLowerCase();                       // Normalize case
};

  // 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*,\s*/g, ",")
  //     .replace(/\s+/g, " ")
  //     .trim()
  //     .toLowerCase();
  // };
const normalizeConditionParts = (rawConditions) => {
  const parts = rawConditions?.split(",") || [];
  const set1 = [], set2 = [];
  let currentSet = null;
  window.tempClause = [];

  const pushClause = (targetSet, includeOperator = null) => {
    if (window.tempClause.length && targetSet) {
      const joinedClause = window.tempClause.join(",").trim();
      const cleaned = stripHTML4(joinedClause);
      if (cleaned) targetSet.push(cleaned);
      window.tempClause = [];

      if (includeOperator) {
        targetSet.push(includeOperator); // ✅ push 'all' or 'any' as part of structure
      }
    }
  };

  const isSetMarker = (part) =>
    part.includes("condition_set_1") || part.includes("condition_set_2");

  const handleSetSwitch = (rawPart) => {
    pushClause(currentSet); // push last clause before switching
    if (rawPart.includes("condition_set_1")) return set1;
    if (rawPart.includes("condition_set_2")) return set2;
    return currentSet;
  };

  const isLogicalOperator = (part) => part === "any" || part === "all";

  for (let i = 0; i < parts.length; i++) {
    const rawPart = parts[i].trim();

    if (isSetMarker(rawPart)) {
      currentSet = handleSetSwitch(rawPart);
    } else if (isLogicalOperator(rawPart.toLowerCase())) {
      // Push current clause + the logical operator into the same set
      pushClause(currentSet, rawPart.toLowerCase());
    } else if (currentSet) {
      window.tempClause.push(rawPart);
    }
  }

  pushClause(currentSet); // Push any remaining clause

  set1.sort();
  set2.sort();

  console.log("🔹 Sorted Set1:", set1);
  console.log("🔸 Sorted Set2:", set2);

  return { set1, set2 };
};



//   const normalizeConditionParts = (rawConditions) => {
//   const parts = rawConditions?.split(",") || [];
//   const set1 = [], set2 = [];
//   let currentSet = null;
//   window.tempClause = [];

//   const pushClause = (targetSet) => {
//     if (window.tempClause.length && targetSet) {
//       const joinedClause = window.tempClause.join(",").trim();
//       const cleaned = stripHTML4(joinedClause);
//       if (cleaned) targetSet.push(cleaned);
//       window.tempClause = [];
//     }
//   };

//   for (let i = 0; i < parts.length; i++) {
//     const rawPart = parts[i].trim().toLowerCase();
//     if (rawPart.includes("condition_set_1")) {
//       pushClause(currentSet);
//       currentSet = set1;
//       continue;
//     }
//     if (rawPart.includes("condition_set_2")) {
//       pushClause(currentSet);
//       currentSet = set2;
//       continue;
//     }
//     if (rawPart === "any" || rawPart === "all") {
//       pushClause(currentSet);
//       continue;
//     }
//     if (currentSet) {
//       window.tempClause.push(parts[i]);  // ✅ Fixed line
//     }
//   }

//   pushClause(currentSet);
//   set1.sort();
//   set2.sort();
//   console.log("🔹 Sorted Set1:", set1);
//   console.log("🔸 Sorted Set2:", set2);
//   return { set1, set2 };
// };


 const normalizeActions = (rawActions) => {
  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();  // Trim each clause
    if (clause) normalizedClauses.push(clause);
  }

  normalizedClauses.sort((a, b) => a.localeCompare(b));  // Lexicographic sort

  return normalizedClauses.join(" | "); // use for duplicate comparison
};


  records.forEach((record, idx) => {
    console.log(`\n📦 Processing Record #${idx + 1}`, record);
    const data = record.data || {};
    const { conditions = "", actions = "", operator = "" } = data;

    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}`;

    console.log("🗝️ Key1:", key1);
    console.log("🗝️ Key2:", key2);

    if (seenRules.has(key1) || seenRules.has(key2)) {
      const existing = seenRules.get(key1) || seenRules.get(key2);
      console.warn("❗ Duplicate Detected");
      if (!duplicateRecords.includes(existing)) {
        console.log("➕ Adding first matched record to duplicates");
        duplicateRecords.push(existing);
      }
      console.log("➕ Adding current record to duplicates");
      duplicateRecords.push(record);
    } else {
      console.log("✅ Unique Rule — storing key1");
      seenRules.set(key1, record);
    }
  });

  console.log(`\n🎯 Total Duplicates Found: ${duplicateRecords.length}`);
  return duplicateRecords;
};









// new handleduplicateruletype strating
function initializeGlobalFlags() {
  initializeBooleanFlags();
  initializeCountFlags();
  initializeEntityFlags();
  initializeDatabaseFlag();
}

function initializeBooleanFlags() {
  if (window.isFetchingType1 === undefined) window.isFetchingType1 = false;
  if (window.isFetchingType3 === undefined) window.isFetchingType3 = false;
  if (window.isFetchingType4 === undefined) window.isFetchingType4 = false;
}

function initializeCountFlags() {
  if (window.type1 === undefined) window.type1 = 0;
  if (window.type3 === undefined) window.type3 = 0;
  if (window.type4 === undefined) window.type4 = 0;
}

function initializeEntityFlags() {
  if (window.duplicateEntitiesType1 === undefined) window.duplicateEntitiesType1 = [];
  if (window.duplicateEntitiesType3 === undefined) window.duplicateEntitiesType3 = [];
  if (window.duplicateEntitiesType4 === undefined) window.duplicateEntitiesType4 = [];
}

function initializeDatabaseFlag() {
  if (window.isDatabaseInitialized === undefined) window.isDatabaseInitialized = false;
}



// ✅ Ensure DB is initialized
async function ensureDatabaseInitialized() {
  if (!window.isDatabaseInitialized) {
    console.log("⚙️ Initializing database...");
    await initializeDatabase();
    window.isDatabaseInitialized = true;
  }
}

// ✅ Rule config mapper
function getDuplicateRuleConfig(type) {
  const map = {
    1: {
      fetchFlag: "isFetchingType1",
      countVar: "type1",
      entityVar: "duplicateEntitiesType1",
      containerId: "Ticketcreation"
    },
    3: {
      fetchFlag: "isFetchingType3",
      countVar: "type3",
      entityVar: "duplicateEntitiesType3",
      containerId: "HourlyTriggers"
    },
    4: {
      fetchFlag: "isFetchingType4",
      countVar: "type4",
      entityVar: "duplicateEntitiesType4",
      containerId: "TicketUpdates"
    }
  };
  return map[type];
}

// ✅ Check if already fetching or fetched
function shouldSkipFetch(config) {
  return window[config.fetchFlag] || window[config.countVar] > 0;
}

// ✅ Core handler for fetching & displaying duplicates
async function fetchAndDisplayDuplicates(config, type) {
  window[config.fetchFlag] = true;

  console.log(`handleDuplicateRulestype called for type ${type}`);
  const duplicates = await Filterrecords(type, config.containerId);
  window[config.entityVar] = duplicates;

  console.log(`Final duplicate records of type ${type}:`, duplicates);
  displayGroupedRules(duplicates, config.containerId);

  window[config.countVar]++;
}

// ✅ Error handler
function handleDuplicateRuleError(error) {
  console.error("❌ Error fetching duplicate rules:", error);
  if (error.status === 401) {
    document.getElementById("Automation-page").style.display = "none";
    document.getElementById("Workflow-Automation-page").style.display = "none";
    document.getElementById("no_user2").style.display = "block";
  }
}

// ✅ Reset fetch flag
function resetFetchFlag(config) {
  if (config?.fetchFlag) {
    window[config.fetchFlag] = false;
  }
}

// ✅ Master function
async function handleDuplicateRulestype(data) {
  await ensureDatabaseInitialized();
  console.log("handleDuplicateRulestype called");

  const config = getDuplicateRuleConfig(data);
  if (!config) {
    console.warn("❌ Unknown type passed to handleDuplicateRulestype:", data);
    return;
  }

  if (shouldSkipFetch(config)) return;

  try {
    await fetchAndDisplayDuplicates(config, data);
  } catch (error) {
    handleDuplicateRuleError(error);
  } finally {
    hideLoader();
    resetFetchFlag(config);
  }
}


// new handleduplicateruletype ending

function stripHTML(input) {
  if (!input || typeof input !== 'string') return '';

  const tempDiv = document.createElement('div');
  tempDiv.innerHTML = input;

  const text = tempDiv.textContent || tempDiv.innerText || '';

  return text
    .replace(/\u00A0/g, ' ')   
    .replace(/&nbsp;/gi, ' ') 
    .replace(/\s+/g, ' ')      
    .trim();
}


// new popupcard added
// function showPopupCard(title, content, automation_type_id) {
//   // Set automation type ID from localStorage if not passed
//   automation_type_id = handleAutomationId(automation_type_id);
//   console.log("logPopup", automation_type_id);

//   const overlay = createOverlay();
//   const popupContainer = createPopupContainer();
//   const popupHeader = createPopupHeader(title);
//   const contentBox = createContentBox();

//   const scrollableContent = createScrollableContent();
//   const eventText = createEventText(automation_type_id);
//   const conditionText = createConditionText();
//   const conditionsList = createConditionsList(content.conditions);
//   const actionText = createActionText();
//   const actionContent = createActionContent(content.actions);

//   scrollableContent.appendChild(eventText);
//   scrollableContent.appendChild(conditionText);
//   scrollableContent.appendChild(conditionsList);
//   scrollableContent.appendChild(actionText);
//   scrollableContent.appendChild(actionContent);

//   contentBox.appendChild(createPreviewLabel());
//   contentBox.appendChild(scrollableContent);

//   const closeButton = createCloseButton(() => {
//     document.body.removeChild(popupContainer);
//     document.body.removeChild(overlay);
//     document.body.style.overflow = "";
//   });

//   popupContainer.appendChild(popupHeader);
//   popupContainer.appendChild(contentBox);
//   popupContainer.appendChild(closeButton);

//   document.body.appendChild(overlay);
//   document.body.appendChild(popupContainer);
// }

// // === Helper Functions Below ===

// function handleAutomationId(id) {
//   if (id !== undefined && id !== null) {
//     localStorage.setItem("automation_type_id", id);
//     return id;
//   }
//   return localStorage.getItem("automation_type_id") || "Unknown";
// }

// function createOverlay() {
//   const overlay = document.createElement("div");
//   Object.assign(overlay.style, {
//     position: "fixed",
//     top: "0",
//     left: "0",
//     width: "100%",
//     height: "100%",
//     backgroundColor: "rgba(0, 0, 0, 0.3)",
//     backdropFilter: "blur(5px)",
//     zIndex: "999"
//   });
//   document.body.style.overflow = "hidden";
//   return overlay;
// }

// function createPopupContainer() {
//   const container = document.createElement("div");
//   Object.assign(container.style, {
//     position: "fixed",
//     top: "50%",
//     left: "50%",
//     transform: "translate(-50%, -50%)",
//     width: "50%",
//     maxWidth: "95%",
//     backgroundColor: "#fff",
//     border: "1px solid #ccc",
//     boxShadow: "0 4px 8px rgba(0, 0, 0, 0.2)",
//     borderRadius: "12px",
//     overflow: "hidden",
//     fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
//     zIndex: "1000",
//     display: "flex",
//     flexDirection: "column",
//     height: "auto",
//     maxHeight: "80vh"
//   });
//   return container;
// }

// function createPopupHeader(title) {
//   const header = document.createElement("div");
//   header.style.padding = "16px 24px";
//   header.style.borderBottom = "1px solid #ddd";
//   header.style.backgroundColor = "#fff";
//   header.style.zIndex = "10";

//   const titleEl = document.createElement("h2");
//   titleEl.textContent = title;
//   titleEl.style.paddingLeft = "15px";
//   titleEl.style.fontSize = "20px";
//   titleEl.style.color = "#333";
//   titleEl.style.textAlign = "left";

//   header.appendChild(titleEl);
//   return header;
// }

// function createContentBox() {
//   const box = document.createElement("div");
//   Object.assign(box.style, {
//     flex: "1",
//     border: "1px solid #ddd",
//     borderRadius: "8px",
//     backgroundColor: "#f9f9f9",
//     padding: "16px",
//     margin: "16px",
//     overflow: "hidden",
//     marginBottom: "75px",
//     display: "flex",
//     flexDirection: "column"
//   });
//   return box;
// }

// function createPreviewLabel() {
//   const labelContainer = document.createElement("div");
//   labelContainer.style.position = "sticky";
//   labelContainer.style.top = "0";
//   labelContainer.style.backgroundColor = "#f9f9f9";
//   labelContainer.style.zIndex = "1";
//   labelContainer.style.padding = "8px 0";

//   const label = document.createElement("p");
//   label.textContent = "Preview";
//   label.style.fontSize = "16px";
//   label.style.fontWeight = "500";
//   label.style.color = "#92a2b1";
//   label.style.margin = "0";

//   const line = document.createElement("hr");
//   line.style.border = "none";
//   line.style.borderTop = "1px solid #ddd";
//   line.style.margin = "8px 0";

//   labelContainer.appendChild(label);
//   labelContainer.appendChild(line);
//   return labelContainer;
// }

// function createScrollableContent() {
//   const div = document.createElement("div");
//   div.style.overflowY = "auto";
//   div.style.height = "auto";
//   div.style.maxHeight = "60vh";
//   div.style.flex = "1";
//   div.style.minHeight = "0";
//   return div;
// }

// function createCloseButton(onClick) {
//   const button = document.createElement("fw-button");
//   button.setAttribute("color", "primary");
//   button.textContent = "Close";
//   Object.assign(button.style, {
//     position: "absolute",
//     bottom: "16px",
//     right: "16px",
//     padding: "8px 16px",
//     borderRadius: "4px",
//     cursor: "pointer"
//   });
//   button.addEventListener("click", onClick);
//   return button;
// }

// // Stubs for domain-specific generators (should reuse logic from your original code)
// function createEventText(automation_type_id) {
//   // Your logic for generating event section goes here
//   return document.createElement("div");
// }

// function createConditionText() {
//   const div = document.createElement("div");
//   div.textContent = "Condition";
//   div.style.marginBottom = "8px";
//   div.style.fontWeight = "bold";
//   div.style.color = "#e86f25";
//   div.style.fontSize = "16px";
//   return div;
// }

// function createConditionsList(conditions) {
//   // Your logic for formatting conditions list goes here
//   return document.createElement("ul");
// }

// function createActionText() {
//   const div = document.createElement("div");
//   div.textContent = "Action";
//   div.style.marginBottom = "8px";
//   div.style.fontWeight = "bold";
//   div.style.color = "#2c5cc5";
//   div.style.fontSize = "16px";
//   return div;
// }

// function createActionContent(actions) {
//   // Your logic for formatting actions list goes here
//   return document.createElement("ul");
// }


// new popupcard ending
function showPopupCard(title, content, automation_type_id) {
window.isPopupOpen = false;
  if (automation_type_id !== undefined && automation_type_id !== null) {
      localStorage.setItem("automation_type_id", automation_type_id); 
  } else {
      automation_type_id = localStorage.getItem("automation_type_id") || "Unknown";
  }

  console.log("logPopup", automation_type_id);



const overlay = document.createElement("div");
overlay.style.position = "fixed";


overlay.style.top = "0";
overlay.style.left = "0";
overlay.style.width = "100%";
overlay.style.height = "100%";
overlay.style.backgroundColor = "rgba(0, 0, 0, 0.3)"; // Semi-transparent dark background
overlay.style.backdropFilter = "blur(5px)"; // Apply blur effect
overlay.style.zIndex = "999"; // Ensure it appears above everything else
document.body.style.overflow = "hidden";
document.body.appendChild(overlay);
// Create popup container
const popupContainer = document.createElement("div");
popupContainer.style.position = "fixed";
popupContainer.style.top = "50%";
popupContainer.style.left = "50%";
popupContainer.style.transform = "translate(-50%, -50%)";
popupContainer.style.width = "50%"; // Increased default width
popupContainer.style.maxWidth = "95%"; // Ensure it fits on smaller screens
// popupContainer.style.height = "80%"; // Use viewport height to limit size
popupContainer.style.backgroundColor = "#fff";
popupContainer.style.border = "1px solid #ccc";
popupContainer.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)";
popupContainer.style.borderRadius = "12px"; // Increased border radius for a smoother look
popupContainer.style.overflow = "hidden"; // Prevent content overflow
popupContainer.style.fontFamily =
  "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif"; // Apply a system font
popupContainer.style.zIndex = "1000";
popupContainer.style.display = "flex";
popupContainer.style.flexDirection = "column";
popupContainer.style.height = "auto";
popupContainer.style.maxHeight = "80vh";


// Create header for title (fixed position)
const popupHeader = document.createElement("div");
popupHeader.style.padding = "16px 24px";
popupHeader.style.borderBottom = "1px solid #ddd"; // Separate the title visually
popupHeader.style.backgroundColor = "#fff";
popupHeader.style.zIndex = "10"; // Ensure it appears above the scrollable content

// Popup title
const popupTitle = document.createElement("h2");
popupTitle.textContent = title;
popupTitle.style.paddingLeft = "15px"; // Move the title slightly to the right
popupTitle.style.fontSize = "20px";
popupTitle.style.color = "#333";
popupTitle.style.textAlign = "left";
popupHeader.appendChild(popupTitle);



// Content wrapper (flex layout)
const contentWrapper = document.createElement("div");
contentWrapper.style.display = "flex";
contentWrapper.style.flexDirection = "column";
contentWrapper.style.flex = "1"; // Automatically take up available space
contentWrapper.style.overflow = "hidden"; // Prevent content overflow

// Content box (with fixed preview label)
const contentBox = document.createElement("div");
contentBox.style.flex = "1";
contentBox.style.border = "1px solid #ddd";
contentBox.style.borderRadius = "8px";
contentBox.style.backgroundColor = "#f9f9f9";
contentBox.style.padding = "16px";
contentBox.style.margin = "16px 16px"; // Add vertical spacing
contentBox.style.overflow = "hidden"; // Prevent outer scrolling
contentBox.style.marginBottom = "75px"; // Add enough space for the close button
contentBox.style.display = "flex";
contentBox.style.flexDirection = "column";

// Preview label and line (sticky inside content box)
const previewLabelContainer = document.createElement("div");
previewLabelContainer.style.position = "sticky"; // Fix inside the content box
previewLabelContainer.style.top = "0"; // Stick to the top
previewLabelContainer.style.backgroundColor = "#f9f9f9"; // Match the content box background
previewLabelContainer.style.zIndex = "1";
previewLabelContainer.style.padding = "8px 0";

const previewLabel = document.createElement("p");
previewLabel.textContent = "Preview"; // Label text
previewLabel.style.fontSize = "16px";
previewLabel.style.fontWeight = "500";
previewLabel.style.color = "#92a2b1";
previewLabel.style.margin = "0";

const lineBelowLabel = document.createElement("hr");
lineBelowLabel.style.border = "none";
lineBelowLabel.style.borderTop = "1px solid #ddd";
lineBelowLabel.style.margin = "8px 0";

previewLabelContainer.appendChild(previewLabel);
previewLabelContainer.appendChild(lineBelowLabel);

// Scrollable content area

const scrollableContent = document.createElement("div");
scrollableContent.style.overflowY = "auto"; // Enable vertical scrolling
// scrollableContent.style.height = "calc(100% - 40px)"; // Adjust to fit within the content box
scrollableContent.style.height = "auto"; // Allow dynamic growth
scrollableContent.style.maxHeight = "60vh";
scrollableContent.style.flex = "1"; // Fill vertical space in contentBox

scrollableContent.style.minHeight = "0";


  const eventText = document.createElement("div");
  eventText.style.marginBottom = "12px";
  const createCustomBullet = (text, bulletColor, highlightColor) => {
    const listItem = document.createElement("li");
    listItem.style.position = "relative"; // For positioning the custom bullet
    listItem.style.paddingLeft = "10px"; // Space for custom bullet
    listItem.style.marginLeft ="9px"
  
    // Create the custom double circular bullet using a span element
    const bullet = document.createElement("span");
    bullet.style.position = "absolute";
    bullet.style.left = "-15px"; // Bring the bullet closer to the text
    bullet.style.top = "50%"; // Center the bullet vertically
    bullet.style.transform = "translateY(-50%)"; // Center the bullet exactly
    bullet.style.width = "12px"; // Outer ring size
    bullet.style.height = "12px";
    bullet.style.border = `4px solid ${bulletColor || "#dcdfe1"}`; // Outer ring color and border size
    bullet.style.borderRadius = "50%"; // Make it a ring (circle with border)
    bullet.style.display = "inline-block";
  
    // Create the inner circle (smaller circle inside the outer ring)
    const innerBullet = document.createElement("span");
    innerBullet.style.position = "absolute";
    innerBullet.style.left = "50%";
    innerBullet.style.top = "50%";
    innerBullet.style.transform = "translate(-50%, -50%)"; // Centering the inner circle
    innerBullet.style.width = "2px"; // Inner circle size
    innerBullet.style.height = "2px";
    innerBullet.style.borderRadius = "50%"; // Inner circle rounded
    innerBullet.style.display = "inline-block";
  
    // Append the inner circle to the outer circle (bullet)
    bullet.appendChild(innerBullet);
  
    // Split the text into words
    const words = text.split(" ");
    
    // Extract specific words
    const firstWord = words.shift(); // Remove first word
    const secondWord = words.shift(); // Remove second word
    const lastWord = words.pop(); // Extract last word
    const remainingText = words.join(" "); // Remaining words (excluding first, second, and last)
  
    // Construct the innerHTML with the second word in black and the last word in highlight color
    listItem.innerHTML = `
      <span>${firstWord}</span> 
      <span style="color: black; font-weight: 500;">${secondWord}</span> 
      ${remainingText} 
      <span style="color: ${highlightColor}; font-weight: 500;">${lastWord}</span>
    `;
  
    // Append the custom double circular bullet to the list item
    listItem.insertBefore(bullet, listItem.firstChild);
  
    return listItem;
  };
  

  
  // Create the heading "Event:"
  const eventLabel = document.createElement("p");
  eventLabel.textContent = "Event";
  eventLabel.style.margin = "0";
  eventLabel.style.color = "#00a886"; // Blue color for heading
  eventLabel.style.fontWeight = "bold";
  eventLabel.style.fontSize = "16px";

  // Create the unordered list for the event details
  const eventDetail = document.createElement("ul");
  eventDetail.style.margin = "8px 0 0 -15px"; // Add margin and indentation
  eventDetail.style.color = "#333"; // Normal color for text
  eventDetail.style.listStyleType = "none"; // Remove default bullets
  eventDetail.style.fontSize = "14px";
 
  if (Number(automation_type_id) === 1){
  const eventBullet = createCustomBullet(
    "When Ticket is Created", // Text content
    "#2c5cc5", // Bullet color
    "#00a886" // Highlight color for the last word
  );
  eventDetail.appendChild(eventBullet);
  
  // Append the heading and the event detail to the container
  eventText.appendChild(eventLabel);
  eventText.appendChild(eventDetail);

  }

  const createCustomBullet1 = (text, bulletColor, highlightColor) => {
    const listItem = document.createElement("li");
    listItem.style.position = "relative"; // For positioning the custom bullet
    listItem.style.paddingLeft = "10px"; // Space for custom bullet
     listItem.style.marginLeft ="9px"
    // Create the custom double circular bullet using a span element
    const bullet = document.createElement("span");
    bullet.style.position = "absolute";
    bullet.style.left = "-15px"; // Bring the bullet closer to the text
    bullet.style.top = "50%"; // Center the bullet vertically
    bullet.style.transform = "translateY(-50%)"; // Center the bullet exactly
    bullet.style.width = "12px"; // Outer ring size
    bullet.style.height = "12px";
    bullet.style.border = `4px solid ${bulletColor || "#dcdfe1"}`; // Outer ring color and border size
    bullet.style.borderRadius = "50%"; // Make it a ring (circle with border)
    bullet.style.display = "inline-block";
  
    // Create the inner circle (smaller circle inside the outer ring)
    const innerBullet = document.createElement("span");
    innerBullet.style.position = "absolute";
    innerBullet.style.left = "50%";
    innerBullet.style.top = "50%";
    innerBullet.style.transform = "translate(-50%, -50%)"; // Centering the inner circle
    innerBullet.style.width = "2px"; // Inner circle size
    innerBullet.style.height = "2px";
    innerBullet.style.borderRadius = "50%"; // Inner circle rounded
    innerBullet.style.display = "inline-block";
  
    // Append the inner circle to the outer circle (bullet)
    bullet.appendChild(innerBullet);
  
    // Split the text into words
    const words = text.split(" ");
    
    // Extract specific words
    const firstWord = words.shift(); // Remove first word
    const secondWord = words.shift(); // Remove second word
    const lastFourWords = words.splice(-4).join(" "); // Get last four words
    const remainingText = words.join(" "); // Remaining words (excluding first, second, and last four)
  
    // Construct the innerHTML with the second word in black and the last four words in highlight color
    listItem.innerHTML = `
      <span>${firstWord}</span> 
      <span style="color: black; font-weight: 500;">${secondWord}</span> 
      ${remainingText} 
      <span style="color: ${highlightColor}; font-weight: 500;">${lastFourWords}</span>
    `;
  
    // Append the custom double circular bullet to the list item
    listItem.insertBefore(bullet, listItem.firstChild);
  
    return listItem;
  };
  

  
  if (Number(automation_type_id) === 3){
    const eventBullet = createCustomBullet1(
      "When Ticket is is checked every hour", // Text content
      "#2c5cc5", // Bullet color
      "#00a886" // Highlight color for the last word
    );
    eventDetail.appendChild(eventBullet);
    
    // Append the heading and the event detail to the container
    eventText.appendChild(eventLabel);
    eventText.appendChild(eventDetail);
  
    }
  // Create the conditions heading
  const conditionText = document.createElement("div");
  conditionText.textContent = "Condition";
  conditionText.style.marginBottom = "8px";
  conditionText.style.fontWeight = "bold";
  conditionText.style.color = "#e86f25"; // Green color for conditions heading
  conditionText.style.fontSize = "16px";
  
  // Create a container for the conditions list
  const conditionsList = document.createElement("ul");
  conditionsList.style.margin = "0 0 12px";
  conditionsList.style.padding = "8px";
  conditionsList.style.border = "1px solid #ddd";
  conditionsList.style.borderRadius = "4px";
  conditionsList.style.backgroundColor = "#fff";
  conditionsList.style.listStyleType = "none"; // Remove default bullet style
  conditionsList.style.fontSize = "14px";
  
 // Extract condition sets and operator
const conditionsArray1 = Array.isArray(content.conditions.condition_set_1)
? content.conditions.condition_set_1
: [];
const conditionsArray2 = Array.isArray(content.conditions.condition_set_2)
? content.conditions.condition_set_2
: [];
const operator = content.conditions.operator || "";




// Function to create a styled bullet point for conditions/actions
const createConditionBullet = (condition, bulletColor = "#dcdfe1") => {
  


  const listItem = document.createElement("li");
  listItem.style.position = "relative";
  listItem.style.paddingLeft = "30px"; // Space for bullet
  listItem.style.display = "flex"; // Prevents breaking lines
  listItem.style.alignItems = "center"; // Keeps elements aligned

  // Create custom bullet
  const bullet = document.createElement("span");
  bullet.style.position = "absolute";
  bullet.style.left = "0";
  bullet.style.top = "50%";
  bullet.style.transform = "translateY(-50%)";
  bullet.style.width = "12px";
  bullet.style.height = "12px";
  bullet.style.border = `4px solid ${bulletColor || "#dcdfe1"}`;
  bullet.style.borderRadius = "50%";

  // Inner circle of bullet
  const innerBullet = document.createElement("span");
  innerBullet.style.position = "absolute";
  innerBullet.style.left = "50%";
  innerBullet.style.top = "50%";
  innerBullet.style.transform = "translate(-50%, -50%)";
  innerBullet.style.width = "8px";
  innerBullet.style.height = "8px";
  innerBullet.style.borderRadius = "50%";

  bullet.appendChild(innerBullet);

  // **Formatting Condition with Colors**
  const formattedCondition = condition
    .replace(/<div/g, ' <div') // Add space before <div> tags if missing
    .replace(/<div\s+class\s*=\s*["']?SummaryKey["']?\s*>(.*?)<\/div>/gi, ' <span style="color: black; font-weight: 500;">$1</span> ') 
    .replace(/<div\s+class\s*=\s*["']?SummaryValue["']?\s*>(.*?)<\/div>/gi, ' <span style="color: #00a886; font-weight: 500;">$1</span> ') 
    .replace(/<div\s+class\s*=\s*["']?SummaryOperator["']?\s*>(.*?)<\/div>/gi, ' <span> $1 </span> ') // Ensure space around operators
    .replace(/>\s+</g, '> <')  // Ensures space between inline elements
    .replace(/\s+/g, ' ')      // Remove multiple spaces
    .trim();                   // Trim any leading/trailing spaces

 

  // // Set bullet first, then append formatted text
  listItem.appendChild(bullet);
  
  // Create a span for the condition text (for proper spacing)
  const textSpan = document.createElement("span");
  textSpan.innerHTML = formattedCondition;
  textSpan.style.marginLeft = "-5px"; // Ensure space between bullet and text
  listItem.appendChild(textSpan);

  console.log("✅ Final List Item InnerHTML:", listItem.innerHTML); // Log final output

  return listItem;
};


// Add conditions from condition_set_1
conditionsArray1.forEach((condition) => {
if (condition === "AND" || condition === "OR") {
  // Add operator as a separate text element
  const operatorItem = document.createElement("div");
  operatorItem.textContent = condition;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  conditionsList.appendChild(operatorItem);
} else {
  conditionsList.appendChild(createConditionBullet(condition, "#2c5cc5")); // Blue bullet
}
});

// Add operator between conditions (if available)
if (operator) {
const operatorItem = document.createElement("div");
operatorItem.textContent = operator;
operatorItem.style.color = "#000000";
operatorItem.style.margin = "8px 0";
operatorItem.style.fontSize = "14px";
operatorItem.style.fontweight="bold"
conditionsList.appendChild(operatorItem);
}

// Add conditions from condition_set_2
conditionsArray2.forEach((condition) => {
if (condition === "AND" || condition === "OR") {
  const operatorItem = document.createElement("div");
  operatorItem.textContent = condition;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  conditionsList.appendChild(operatorItem);
} else {
  conditionsList.appendChild(createConditionBullet(condition, "#2c5cc5")); // Blue bullet
}
});

// Create actions heading
const actionText = document.createElement("div");
actionText.textContent = "Action";
actionText.style.marginBottom = "8px";
actionText.style.fontWeight = "bold";
actionText.style.color = "#2c5cc5";
actionText.style.fontSize = "16px";

// Create actions content
const actionContent = document.createElement("ul");
actionContent.style.margin = "0";
actionContent.style.padding = "8px";
actionContent.style.border = "1px solid #ddd";
actionContent.style.borderRadius = "4px";
actionContent.style.backgroundColor = "#fff";
actionContent.style.listStyleType = "none";
actionContent.style.fontSize = "14px";

const actionsArray = Array.isArray(content.actions) ? content.actions : [];

// Add actions with custom bullets
actionsArray.forEach((action) => {
if (action === "AND" || action === "OR") {
  const operatorItem = document.createElement("div");
  operatorItem.textContent = action;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  actionContent.appendChild(operatorItem);
} else {
  actionContent.appendChild(createConditionBullet(action, "#2c5cc5")); // Blue bullet for actions
}
});
  
  // Append the label and line to the content box
  contentBox.appendChild(previewLabel);
  contentBox.appendChild(lineBelowLabel);
  
  scrollableContent.appendChild(eventText);
  scrollableContent.appendChild(conditionText);
  scrollableContent.appendChild(conditionsList);
  scrollableContent.appendChild(actionText);
  scrollableContent.appendChild(actionContent);
  
  // Append content to the scrollable wrapper
  
  contentBox.appendChild(scrollableContent);
  
  // Create fw-button element with "primary" color
  const closeButton = document.createElement("fw-button");
  closeButton.setAttribute("color", "primary");
  closeButton.textContent = "Close";
  closeButton.style.position = "absolute";
  closeButton.style.bottom = "16px"; // Distance from the bottom
  closeButton.style.right = "16px"; // Distance from the right
  closeButton.style.padding = "8px 16px"; // Padding for the button
  closeButton.style.borderRadius = "4px"; // Rounded corners
  closeButton.style.cursor = "pointer";
  
  // Close popup and remove overlay when the button is clicked
  closeButton.addEventListener("click", () => {
    document.body.removeChild(popupContainer);
    document.body.removeChild(overlay);
    document.body.style.overflow = "";
     window.isPopupOpen = false;
  });
  
  popupContainer.appendChild(popupHeader); // Fixed title
  popupContainer.appendChild(contentBox);
  
  popupContainer.appendChild(closeButton); // Close button
  
  // Append elements to the document
  document.body.appendChild(overlay);
  document.body.appendChild(popupContainer);
  
  }





window.currentPage = 1;
const itemsPerPage = 5;function stripHTML2(htmlString) {
  const div = document.createElement("div");
  div.innerHTML = htmlString;

  // Remove all tags except <img>
  [...div.querySelectorAll("*")].forEach(el => {
    if (el.tagName.toLowerCase() !== "img") {
      el.replaceWith(...el.childNodes);
    }
  });

  let text = div.textContent || div.innerText || "";

  text = text.replace(/\u00a0|&nbsp;/g, " ").replace(/\s+/g, " ").trim();
  return text;
}

function cleanTextEntities(text) {
  return text
    .replace(/\u00a0|&nbsp;/g, " ")
    .replace(/\s+/g, " ")
    .trim();
}

function normalizeText2(text) {
  return text
    .toLowerCase()
    .replace(/&nbsp;/gi, " ")           // Replace &nbsp; with space
    .replace(/[.,]/g, "")   // Remove punctuation
    .replace(/\s+/g, " ")               // Collapse multiple spaces
    .trim()
    .split(" ")                         // Split into words
    .sort()                             // Sort for consistent order
    .join(" ");                         // Rejoin into a string
}

function normalizeList(text) {
  return text
    ? text
        .split(",")
        .map((item) =>
          item
            .trim()
            .toLowerCase()
            .replace(/[.,]/g, "") // Remove periods and commas
            .replace(/\s+/g, " ") // Normalize spacing
        )
        .sort()
        .join(",")
    : "";
}

function removeImgTags(htmlString) {
  const div = document.createElement("div");
  div.innerHTML = htmlString;

  [...div.querySelectorAll("img")].forEach(img => img.remove());
  return div.textContent || div.innerText || "";
}

 async function entitypopupDeletion() {
            console.log("entity deletion called");
            
              if (!currentRuleId) return; // Ensure rule ID is available
      
              try {
                console.log("entity deletion called try");
                  console.log("Deleting rule with ID:", currentRuleId);
                  await newRulePloadDB5.delete(currentRuleId);
  
  
                  
              } catch (error) {
                console.log("entity deletion called catch");
                  console.warn(` Error deleting record with Display ID ${currentRuleId}, but continuing...`);
                  const ruleIndex = records.findIndex(record => record.display_id === currentRuleId);
                if (ruleIndex !== -1) {
              records.splice(ruleIndex, 1);
               console.log(`✅ Rule ${currentRuleId} removed from records array.`);
                } else {
                 console.warn(`⚠️ Rule with display_id ${currentRuleId} not found in records array.`);
                 }
  
                  displayGroupedRules(records, containerId)
                  
                 
       const valid = document.getElementById("type_toast");
      valid.setAttribute("content", "Rule not found. Try refreshing the page.");

      valid.setAttribute("type", "error");
      valid.setAttribute("open", true);
    
       
                   removeDeletedRuleFromUI(currentRuleId);
                  
       
                   
                 
              }
          }
function displayGroupedRules(records, containerId) {
  const container = document.getElementById(containerId);
  if (!container) {
    console.error(`Container with ID "${containerId}" not found.`);
    return;
  }

  container.innerHTML = "";

  if (records.length <= 1) {
    container.innerHTML = `
      <div style="
        display: flex;
        justify-content: center;
        align-items: center;
        width: 80%;
        font-size: 24px;
        font-weight: bold;
        color: #333;
        text-align: center;
        margin: 300px auto;
      ">
        No duplicate rules found.
      </div>`;
    return;
  }
  const groupedRules = new Map();

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

  const div = document.createElement("div");
  div.innerHTML = htmlString.replace(/&nbsp;/gi, " "); // convert &nbsp; to space for DOM parsing

  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, "") // remove hidden unicode spaces
    .replace(/\./g, "")                   // remove full stops
    .replace(/\s+/g, "")                  // 🔥 remove all whitespace
    .toLowerCase();                       // normalize to lowercase
};

// 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 + ' '; // ✅ add space after text
//       } else if (child.nodeType === Node.ELEMENT_NODE) {
//         result += walkAndClean(child) + ' '; // ✅ add space after child element
//       }
//     }
//     return result;
//   }

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

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

// ✅ Normalize performer (handles string or array)
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 "";
};

// ✅ Normalize conditions and structure into sets
const normalizeConditionParts = (rawConditions) => {
  const parts = rawConditions?.split(",") || [];
  const set1 = [], set2 = [];
  let currentSet = null;
  window.tempClause = [];

  const isSetMarker = (part) =>
    part.includes("condition_set_1") || part.includes("condition_set_2");

  const isLogicalConnector = (part) =>
    part === "any" || part === "all";

  const switchSet = (rawPart) => {
    pushClause(currentSet);
    return rawPart.includes("condition_set_1") ? set1 : set2;
  };

  const pushClause = (targetSet) => {
    if (window.tempClause.length && targetSet) {
      const clause = window.tempClause.map(stripHTML4).sort().join(",");
      targetSet.push(clause);
      window.tempClause = [];
    }
  };

  for (let i = 0; i < parts.length; i++) {
    const rawPart = parts[i];
    const normalizedPart = rawPart.trim().toLowerCase();

    if (isSetMarker(normalizedPart)) {
      currentSet = switchSet(normalizedPart);
    } else if (isLogicalConnector(normalizedPart)) {
      pushClause(currentSet);
      currentSet.push(normalizedPart);
    } else if (currentSet) {
      window.tempClause.push(rawPart);
    }
  }

  pushClause(currentSet); // Final push

  const normSet1 = [...set1].sort();
  const normSet2 = [...set2].sort();

  return {
    key1: `${normSet1.join("|")}|${normSet2.join("|")}`,
    key2: `${normSet2.join("|")}|${normSet1.join("|")}`,
    display: { set1: normSet1, set2: normSet2 }
  };
};

// ✅ Normalize actions
const normalizeActions = (rawActions) => {
  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(" | ");
};

// ✅ Main grouping logic
records.forEach((record) => {
  const { data, display_id } = record;
  const {
    name, summary, position, updated_at, last_updated_by,
    affected_tickets_count, rule_id, automation_type_id,
    conditions, actions, agentName, operator, events, performer
  } = data;

  const { key1, key2 } = normalizeConditionParts(conditions);
  const normalizedActions = normalizeActions(actions);
  const normalizedOperator = operator ? stripHTML4(operator) : "";

  // 🔁 Optional extras based on availability
  const normalizedEvents = events ? normalizeEvents(events) : "";
  const normalizedPerformer = performer ? normalizeField(performer) : "";

  const eventPart = normalizedEvents ? `|${normalizedEvents}` : "";
  const performerPart = normalizedPerformer ? `|${normalizedPerformer}` : "";

  const groupKeyBase = `${normalizedActions}|${normalizedOperator}${eventPart}${performerPart}`;
  const groupKey1 = `${key1}|${groupKeyBase}`;
  const groupKey2 = `${key2}|${groupKeyBase}`;

  const groupKey = groupedRules.has(groupKey1)
    ? groupKey1
    : groupedRules.has(groupKey2)
    ? groupKey2
    : groupKey1;

  if (!groupedRules.has(groupKey)) {
    groupedRules.set(groupKey, { rules: [] });
  }

  groupedRules.get(groupKey).rules.push({
    name,
    position,
    summary,
    updated_at,
    last_updated_by,
    affected_tickets_count,
    rule_id,
    automation_type_id,
    display_id,
    agentName
  });
});


// const groupedRules = new Map();

// // ✅ Main normalization function: strips HTML, &nbsp;, dots, etc.
// const stripHTML4 = (htmlString) => {
//   if (typeof htmlString !== "string") {
//     htmlString = String(htmlString || "");
//   }

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

//   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, "")    // invisible Unicode
//     .replace(/[.]/g, "")                    // remove full stops
//     .replace(/\s*,\s*/g, ",")               // normalize comma spacing
//     .replace(/\s+/g, " ")                   // normalize spacing
//     .trim()
//     .toLowerCase();
// };

// const normalizeConditionParts = (rawConditions) => {
//   const parts = rawConditions?.split(",") || [];
//   const set1 = [], set2 = [];
//   let currentSet = null;
// window.tempClause = [];

//   const isSetMarker = (part) =>
//     part.includes("condition_set_1") || part.includes("condition_set_2");

//   const isLogicalConnector = (part) =>
//     part === "any" || part === "all";

//   const switchSet = (rawPart) => {
//     console.log("🔁 Switching Set due to:", rawPart);
//     pushClause(currentSet);
//     return rawPart.includes("condition_set_1") ? set1 : set2;
//   };

//   const pushClause = (targetSet) => {
//     if (window.tempClause.length && targetSet) {
//       const clause = window.tempClause.map(stripHTML4).sort().join(",");
//       console.log(`🟦 Pushing Clause to Set${targetSet === set1 ? "1" : "2"}:`, clause);
//       targetSet.push(clause);
//       window.tempClause = [];
//     }
//   };

//   for (let i = 0; i < parts.length; i++) {
//     const rawPart = parts[i];
//     const normalizedPart = rawPart.trim().toLowerCase();

//     if (isSetMarker(normalizedPart)) {
//       currentSet = switchSet(normalizedPart);
//     } else if (isLogicalConnector(normalizedPart)) {
//       pushClause(currentSet);               // push current clause
//       currentSet.push(normalizedPart);      // push 'any' or 'all' as separate
//     } else if (currentSet) {
//       console.log("📌 Adding to current clause:", rawPart);
//       window.tempClause.push(rawPart);
//     }
//   }

//   pushClause(currentSet); // final push

//   const normSet1 = [...set1].sort();
//   const normSet2 = [...set2].sort();

//   console.log("✅ Final Sorted Set1:", normSet1);
//   console.log("✅ Final Sorted Set2:", normSet2);

//   return {
//     key1: `${normSet1.join("|")}|${normSet2.join("|")}`,
//     key2: `${normSet2.join("|")}|${normSet1.join("|")}`,
//     display: { set1: normSet1, set2: normSet2 }
//   };
// };


// const normalizeActions = (rawActions) => {
//   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(); // sort within each clause
//     if (clause) normalizedClauses.push(clause);
//   }

//   normalizedClauses.sort((a, b) => a.localeCompare(b)); // sort across clauses
//   return normalizedClauses.join(" | ");
// };


//   records.forEach((record) => {
//     const { data, display_id } = record;
//     const {
//       name, summary, position, updated_at, last_updated_by,
//       affected_tickets_count, rule_id, automation_type_id,
//       conditions, actions, agentName, operator
//     } = data;

//     const { key1, key2 } = normalizeConditionParts(conditions);
//     const normalizedActions = normalizeActions(actions);
//     const normalizedOperator = operator ? stripHTML4(operator) : "";

//     const groupKey1 = `${key1}|${normalizedActions}|${normalizedOperator}`;
//     const groupKey2 = `${key2}|${normalizedActions}|${normalizedOperator}`;

//    const groupKey = groupedRules.has(groupKey1)
//       ? groupKey1
//       : groupedRules.has(groupKey2)
//       ? groupKey2
//       : groupKey1;

//     if (!groupedRules.has(groupKey)) {
//       groupedRules.set(groupKey, { rules: [] });
//     }

//     groupedRules.get(groupKey).rules.push({
//       name,
//       position,
//       summary,
//       updated_at,
//       last_updated_by,
//       affected_tickets_count,
//       rule_id,
//       automation_type_id,
//       display_id,
//       agentName
//     });
//   });

  const rawGroupedArray = Array.from(groupedRules.values());

  // 2. Filter out groups with only one rule
  const groupedRulesArray = rawGroupedArray.filter(group => group.rules.length > 1);
  const totalgroup = groupedRulesArray.length;
  console.log("Filtered Group Count (rules > 1):", totalgroup, "*********************");

  // 3. Calculate pagination details
  const totalPages = Math.ceil(totalgroup / itemsPerPage);
  window.currentPage = Math.max(1, Math.min(currentPage, totalPages)); // Ensure valid page number
  console.log("Total Pages:", totalPages, "Current Page:", currentPage);

  const startIdx = (currentPage - 1) * itemsPerPage;
  const paginatedRules = groupedRulesArray.slice(startIdx, startIdx + itemsPerPage);
  console.log("Displaying Paginated Records:", paginatedRules);

  const arrayLength = paginatedRules.length;
  console.log("Records Length:", arrayLength);

    if (arrayLength === 0) {
  console.log("Array is empty.");
     container.innerHTML = `
    <div style="
  display: flex;
  justify-content: center;
  align-items: center;
  width: 80%;
  font-size: 24px;
  font-weight: bold;
  color: #333;
  text-align: center;
  margin: 300px auto; /* Push it down + center horizontally */
">
 

          No duplicate rules found.
      </div>`;
    return;
}
  paginatedRules.forEach(group => {
    console.log(`Rendering group: ${group.originalSummary}`);

    const groupContainer = document.createElement("div");
    groupContainer.style.border = "1px solid #ccc";
    groupContainer.style.padding = "16px";
    groupContainer.style.margin = "16px";
    groupContainer.style.borderRadius = "8px";
    groupContainer.style.backgroundColor = "#f5f7f9";
    groupContainer.style.width = "87%";

    

    // ✅ Correctly loop through the rules array inside the group object
    group.rules.forEach(({ name, position, summary, updated_at, affected_tickets_count, display_id, rule_id, automation_type_id,agentName }, index) => {
      const card = document.createElement("div");
      // card.className = "fw-card-1 fw-py-16 fw-flex fw-flex-column";
    card.style.border = "1px solid #ddd";
    card.style.padding = "16px";
    card.style.margin = "8px 0"
    card.style.fontFamily =
      "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
    card.style.borderRadius = "8px";
    card.style.backgroundColor = index === 0 ? "#fff" : "#e5f2fd";
    card.style.marginBottom = "10px";
    card.style.paddingBottom = "0";
    card .style.overflow ="hidden"
   
      const cardHeader = document.createElement("div");
      cardHeader.style.display = "flex";
      cardHeader.style.justifyContent = "space-between";
      cardHeader.style.alignItems = "center";
      
      // Create a wrapper for the title
const cardTitle = document.createElement("h4");
cardTitle.style.margin = "0";
cardTitle.style.cursor = "pointer";
cardTitle.style.fontSize = "14px";
cardTitle.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
cardTitle.style.color = "#183247";
cardTitle.style.transition = "color 0.2s ease";
cardTitle.style.fontWeight = "600"; 

// Create the serial number (position)
if (position) {
    const serialNumber = document.createElement("span");
    serialNumber.textContent = position + ". ";
    serialNumber.style.color = "#183247"; // Keep serial number color fixed
    cardTitle.appendChild(serialNumber);
}

// Create the actual name (clickable part)
const titleText = document.createElement("span");
titleText.textContent = name;
titleText.style.color = "#183247"; 
titleText.style.transition = "color 0.2s ease";

// Add hover effect for only the name
titleText.addEventListener("mouseover", () => {
    titleText.style.color = "#007bff"; // Change only name color on hover
});
titleText.addEventListener("mouseout", () => {
    titleText.style.color = "#183247"; // Reset name color when not hovering
});
window.isPopupOpen = false; 
titleText.addEventListener("click", () => {
   if (window.isPopupOpen) return; 
  window.isPopupOpen = true;
    titleText.style.color = "#ff5733"; // Change title color on click
   

    
    // let ruleid=rule_id;
    console.log("ruleid",rule_id);
    // let automationid= automation_type_id;
    console.log("automationtypeid",automation_type_id);
    GetRules();
    async function GetRules() {
      //  console.log('GetRules called');
       try {
           const GetRulesResponse = await client.request.invokeTemplate("getid", {
               context: 
               { 
                ruleid: rule_id ,
                automationid:automation_type_id
               },
           });
   
           const responses = GetRulesResponse.response;
           const rulesData = JSON.parse(responses);
           console.log("Rules", rulesData);
           console.log("Rules", rulesData.summary.conditions);
           console.log("Rules", rulesData.summary.actions);
           if(automation_type_id === 1||automation_type_id === 3)
        {
           showPopupCard(rulesData.name, { conditions: rulesData.summary.conditions, actions:rulesData.summary.actions },automation_type_id);
      }else{
        showPopupCard1(rulesData.name, {performer:rulesData.summary.performer,events:rulesData.summary.events, conditions: rulesData.summary.conditions, actions:rulesData.summary.actions });
      }
    }
        catch (error) {
        console.error("Error in getting rules",error);
       if(error.status === 404)
            {
       const valid = document.getElementById("type_toast");
      valid.setAttribute("content", "Rule not found. Try refreshing the page.");

      valid.setAttribute("type", "error");
      valid.setAttribute("open", true);
         try {
       window.currentRuleId = display_id;
        await entitypopupDeletion();
      } catch (error) {
        console.error(" Error in deletion process inside popup:", error);
      }
         }

         
   
          }

    }
   

});

// Append name to title
cardTitle.appendChild(titleText);




      // Append title and actions to the cardHeader
      cardHeader.appendChild(cardTitle);
      // Create a container for the horizontal line and the gap
const cardContainer = document.createElement("div");

// Style the container to have a background color in the gap
cardContainer.style.backgroundColor = "#f0f0f0";  // Set the background color for the gap (change to desired color)
cardContainer.style.paddingBottom = "20px";  
cardContainer.style.marginLeft="-15px";
cardContainer.style.borderRadius = "4px";
// cardContainer.style.width="103%";
cardContainer.style.position = "relative";

cardContainer.style.width = "calc(103% + 30px)";

// Create a horizontal line after the cardBody
const horizontalLine = document.createElement("div");
horizontalLine.style.height = "1px"; // Set the height to 1px for a thin line
horizontalLine.style.backgroundColor = "#ccc"; // Set the color of the horizontal line
horizontalLine.style.marginTop = "16px"; // Add space above the line (adjust as needed)
// horizontalLine.style.width = "100%"; // Ensure the line stretches the full width of the container
horizontalLine.style.marginLeft="-3px";
      

    function truncateTextByLength(content, maxLength) {
  return content.length > maxLength ? content.slice(0, maxLength) + "..." : content;
}

function splitIntoLines(text, maxLength, lines) {
  const words = text.split(" ");
  const result = [];
  let line = "";
  let currentLine = 1;
  const maxPerLine = Math.floor(maxLength / lines);

  for (const word of words) {
    if ((line + " " + word).trim().length <= maxPerLine) {
      line += (line ? " " : "") + word;
    } else {
      result.push(line);
      line = word;
      currentLine++;
      if (currentLine > lines) break;
    }
  }

  if (currentLine <= lines && line) {
    result.push(line);
  }

  return {
    text: result.join(" "),
    truncated: currentLine > lines,
  };
}

function truncateContent(content, maxLength, lines) {
  const truncated = truncateTextByLength(content, maxLength);
  const { text, truncated: wasTruncated } = splitIntoLines(truncated, maxLength, lines);
  return text + (wasTruncated ? "..." : "");
}

//     function calculateLastModified(updated_at) {
//   const updatedDate = new Date(updated_at);
//   const currentDate = new Date();

//   const diffInSeconds = Math.floor((currentDate - updatedDate) / 1000);

//   const timeChunks = [
//     { label: "year", seconds: 60 * 60 * 24 * 365 },
//     { label: "month", seconds: 60 * 60 * 24 * 30 },
//     { label: "day", seconds: 60 * 60 * 24 },
//     { label: "hour", seconds: 60 * 60 },
//     { label: "minute", seconds: 60 }
//   ];

//   for (const { label, seconds } of timeChunks) {
//     const amount = Math.floor(diffInSeconds / seconds);
//     if (amount > 0) {
//       return amount === 1 ? `a ${label} ago` : `${amount} ${label}s ago`;
//     }
//   }

//   return "Just now";
// }

    
    
      
      
      // console.log("updated at",calculateLastModified(updated_at));
  // Create a row for "Last Modified"
  const lastModifiedRow = document.createElement("div");
  lastModifiedRow.style.display = "grid";
  lastModifiedRow.style.gridTemplateColumns = "repeat(auto-fit, minmax(150px, 1fr))"; // Responsive columns
  lastModifiedRow.style.alignItems = "center";
  // lastModifiedRow.style.marginTop = "10px";
  lastModifiedRow.style.fontSize = "12px";
  lastModifiedRow.style.gap = "16px"; // Space between items
  lastModifiedRow.style.width = "100%"; // Full width alignment
  lastModifiedRow.style.gridTemplateRows = "auto"; // Auto row size to fit content
  
  // Function to create a label-value pair container
  function createLabelValue(labelText, valueText) {
    const container = document.createElement("div");
    container.style.display = "flex";
    container.style.flexDirection = "row"; // Horizontal alignment
    container.style.alignItems = "center"; // Vertical alignment
  
    const label = document.createElement("span");
    label.textContent = labelText;
    label.style.color = "#183247";
    label.style.marginTop = "10px";
    label.style.marginLeft = "15%";
    label.style.fontSize = "12px";
    label.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
  
    const value = document.createElement("span");
    value.textContent = valueText;
    value.style.color = "#183247";
    value.style.fontWeight = "600";
    value.style.marginTop = "10px";
    value.style.fontSize = "12px";
    value.style.marginLeft = "10px"; // Space between label and value
    value.style.fontFamily = "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
  
    container.appendChild(label);
    container.appendChild(value);
  
    return container;
  }
  
  // Create and append the "Last Modified" section to the lastModifiedRow
  const lastModifiedText = calculateLastModified(updated_at);
  lastModifiedRow.appendChild(createLabelValue("Last Modified :", lastModifiedText));
  
  // Vertical line between sections
  const verticalLine = document.createElement("div");
  verticalLine.style.height = "20px";
  verticalLine.style.marginTop = "10px";
  verticalLine.style.borderLeft = "2px solid #ccc";
  verticalLine.style.alignSelf = "stretch"; // Make it stretch vertically between items
  lastModifiedRow.appendChild(verticalLine);
  
  // Create and append the "By" (Agent) section
  const agentNameText = agentName || "Unknown Agent";
  lastModifiedRow.appendChild(createLabelValue("By :", agentNameText));
  
  // Vertical line after the agent name
  const verticalLine2 = document.createElement("div");
  verticalLine2.style.height = "20px";
  verticalLine2.style.marginTop = "10px";
  verticalLine2.style.borderLeft = "2px solid #ccc";
  verticalLine2.style.alignSelf = "stretch";
  lastModifiedRow.appendChild(verticalLine2);
  
  // Create and append the "Impacted tickets" section
  const affectedTicketsText = affected_tickets_count === 0 ? "--" : affected_tickets_count;
  // lastModifiedRow.appendChild(createLabelValue("Impacted tickets (Last 7 days):", affectedTicketsText));
  const impactedTickets = createLabelValue("Impacted tickets (Last 7 days) :", affectedTicketsText);
  impactedTickets.firstChild.style.marginLeft = "-50%"; // Adjust label alignment
  lastModifiedRow.appendChild(impactedTickets);
 
      const cardBody = document.createElement("div"); // Create a container for card content and actions
      cardBody.style.display = "flex"; // Flexbox to align items horizontally
      cardBody.style.justifyContent = "space-between"; // Ensure there's space between content and actions
      cardBody.style.alignItems = "flex-start"; // Align items to the top (optional, depending on your needs)
               

const truncatedContent = truncateContent(summary, 200, 2);

const cardContent = document.createElement("pre");
cardContent.textContent = truncatedContent;

// Style the card content
cardContent.style.marginTop = "8px";
cardContent.style.padding = "8px";
cardContent.style.color="#183247";
cardContent.style.fontweight="600";
cardContent.style.fontFamily= "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif";
cardContent.style.whiteSpace = "pre-wrap"; // Ensure text wraps
cardContent.style.overflow = "hidden"; // Hide overflow content
cardContent.style.textOverflow = "ellipsis"; // Add ellipsis for overflow
cardContent.style.maxWidth = "75%"; // Limit the card width to half the container's width
cardContent.style.fontSize="12px";
cardContent.style.marginLeft="15px";


     // Create the container for card actions
const cardActionsContainer = document.createElement("div");
cardActionsContainer.style.display = "flex"; // Display actions horizontally
cardActionsContainer.style.justifyContent = "flex-end"; // Align to the right
cardActionsContainer.style.marginTop = "10px"; // Add some spacing above the actions
cardActionsContainer.style.gap = "8px"; // Set space between the toggle and the delete icon


        // Add fw-icon
        const fwIcon = document.createElement("fw-icon");
        fwIcon.setAttribute("name", "delete");
        fwIcon.setAttribute("size", "18");
        fwIcon.style.cursor = "pointer";
        fwIcon.style.color = "red"; // Set the color to red
        // Add a pointer cursor for interactivity
        fwIcon.title = "Delete";
        fwIcon.addEventListener("click", () => {
          console.log("ruleid inside entity deletion", rule_id);
             // ✅ Create the modal dynamically
const modal = document.createElement("fw-modal");
modal.setAttribute("id", "deleteConfirmationPopup");
modal.setAttribute("title-text", "Delete Rule");
modal.setAttribute("is-open", "false");

// Modal content
const content = document.createElement("fw-text");
content.textContent = "Are you sure you want to delete the rule?";
modal.appendChild(content);

// Modal footer
const footer = document.createElement("fw-modal-footer");
modal.appendChild(footer);

// Append modal to body
document.body.appendChild(modal);

// ✅ Then use the modal
const deleteModal = document.getElementById("deleteConfirmationPopup");

if (deleteModal) {
  deleteModal.setAttribute("is-open", "true");

  deleteModal.addEventListener(
    "fwSubmit",
    async () => {
      console.log("Delete confirmed.");
      window.currentRuleId = display_id;

      try {
        await confirmDeletion1(rule_id, automation_type_id);
        await entityconfirmDeletion();
      } catch (error) {
        console.error("❌ Error in deletion process:", error);
      }

      deleteModal.removeAttribute("is-open");
    },
    { once: true }
  );

  // Handle Cancel (Close)
  const footer = deleteModal.querySelector("fw-modal-footer");
  if (footer) {
    footer.addEventListener(
      "fwClose",
      () => {
        deleteModal.removeAttribute("is-open");
        console.log("Delete operation was cancelled.");
      },
      { once: true }
    );
  }
} else {
  console.error("Modal element with ID 'deleteConfirmationPopup' not found.");
}

      
          // const modal = document.getElementById("deleteConfirmationPopup");

          // if (modal) {
          //   modal.setAttribute("is-open", "true");
        
          //   modal.addEventListener(
          //     "fwSubmit",
          //     async () => {
          //       console.log("Delete confirmed.");
          //       currentRuleId = display_id;
          //       try {
          //             await confirmDeletion1(rule_id, automation_type_id); 
          //             await entityconfirmDeletion(); 
            
          //         } catch (error) {
          //             console.error("❌ Error in deletion process:", error);
          //         }
        
                
          //       modal.removeAttribute("is-open");
          //     },
          //     { once: true }
          //   );
        
          //   // Handle Cancel (Close)
          //   modal.querySelector("fw-modal-footer").addEventListener(
          //     "fwClose",
          //     () => {
          //       modal.removeAttribute("is-open");
          //       console.log("Delete operation was cancelled.");
          //     },
          //     { once: true }
          //   );
          // } else {
          //   console.error("Modal element with ID 'composition' not found.");
          // }
        });
        function removeDeletedRuleFromUI(display_id) {
          const ruleCard = document.querySelector(`[data-rule-id="${display_id}"]`);
          if (ruleCard) {
              ruleCard.remove();
          }
      }
         async function confirmDeletion1(rule_id, automation_type_id) {
              console.log("📢 confirmDeletion1 function triggered with rule_id:", rule_id, "and automation_type_id:", automation_type_id);
      
              if (!rule_id || !automation_type_id) {
                  console.warn("⚠️ Missing rule_id or automation_type_id, aborting function.");
                  return;
              }
      
              try {
                  console.log("🚀 Sending request to delete rule...");
      
                  const getdeleteruleResponse1 = await client.request.invokeTemplate("deleterule", {
                      context: {
                          automationid: automation_type_id,
                          ruleid: rule_id,
                      },
                  });
      
                  console.log("✅ getdeleteruleResponse:", getdeleteruleResponse1);
      
                  if (getdeleteruleResponse1.status === 204) {
                      console.log("✅ Rule deleted successfully!");
                      // hideDeletePopup();
                  } else {
                      console.warn("⚠️ Unexpected response:", getdeleteruleResponse1);
                  }
      
              } catch (error) {
                  console.error("❌ Error in confirmDeletion1:", error);
              }
          }
      
          async function entityconfirmDeletion() {
            console.log("entity deletion called");
            
              if (!currentRuleId) return; // Ensure rule ID is available
      
              try {
                console.log("entity deletion called try");
                  console.log("Deleting rule with ID:", currentRuleId);
                  await newRulePloadDB5.delete(currentRuleId);
  
  
                  
              } catch (error) {
                console.log("entity deletion called catch");
                  console.warn(` Error deleting record with Display ID ${currentRuleId}, but continuing...`);
                  const ruleIndex = records.findIndex(record => record.display_id === currentRuleId);
                if (ruleIndex !== -1) {
              records.splice(ruleIndex, 1);
               console.log(`✅ Rule ${currentRuleId} removed from records array.`);
                } else {
                 console.warn(`⚠️ Rule with display_id ${currentRuleId} not found in records array.`);
                 }
  
                  displayGroupedRules(records, containerId)

                   const toast = document.getElementById('type_toast');
                   toast.setAttribute('content', 'Rule deleted successfully');
                   toast.setAttribute('type', 'success');
                   toast.setAttribute('open', true);
       
                   removeDeletedRuleFromUI(currentRuleId);
                  
       
                   
                 
              }
          }

      
  //   
      // Append fw-toggle and fw-icon to cardActions
      // cardActionsContainer.appendChild(fwToggle);

      cardActionsContainer.appendChild(fwIcon);
      card.appendChild(cardHeader);
      cardBody.appendChild(cardContent);
      cardBody.appendChild(cardActionsContainer);
      card.appendChild(cardBody);
      cardContainer.appendChild(horizontalLine);
      // card.appendChild(horizontalLine);
     
      cardContainer.appendChild(lastModifiedRow);
      card.appendChild(cardContainer)
      groupContainer.appendChild(card);
    });

    container.appendChild(groupContainer);
  });
  
  // Add pagination component
  addFwPagination(containerId,  records, totalgroup);
}


function addFwPagination(containerId, records, totalgroup) {
  const itemsPerPageLocal = itemsPerPage;
  const totalPages = Math.ceil(totalgroup / itemsPerPageLocal);

  console.log("Adding Bootstrap pagination to container:", containerId);

  const container = document.getElementById(containerId);
  if (!container) {
    console.warn(`Container with ID "${containerId}" not found.`);
    return;
  }

  if (totalgroup <= itemsPerPageLocal) {
    console.log("Total records are less than or equal to items per page, skipping pagination.");
    return;
  }

  const existingPagination = container.querySelector("#bootstrap-pagination-4");
  if (existingPagination) existingPagination.remove();

  const paginationWrapper = document.createElement("nav");
  paginationWrapper.setAttribute("aria-label", "Page navigation");
  paginationWrapper.id = "bootstrap-pagination-4";
  paginationWrapper.style.marginLeft = "40%";

  const ul = document.createElement("ul");
  ul.className = "pagination";

  ul.appendChild(createPrevNextButtons(currentPage, totalPages, records, containerId, totalgroup, true)); // Previous
  ul.appendChild(createPageNumberLinks(totalPages, currentPage, records, containerId, totalgroup)); // Page Numbers
  ul.appendChild(createPrevNextButtons(currentPage, totalPages, records, containerId, totalgroup, false)); // Next

  paginationWrapper.appendChild(ul);
  container.appendChild(paginationWrapper);
}
function createPaginationLink(text, disabled, onClickHandler, isActive = false) {
  const li = document.createElement("li");
  li.className = "page-item" + (disabled ? " disabled" : "") + (isActive ? " active" : "");

  const link = document.createElement("a");
  link.className = "page-link" + (disabled ? " disabled-hover" : "");
  link.href = "#";
  link.innerHTML = text;

  if (disabled) {
    link.setAttribute("tabindex", "-1");
    link.setAttribute("aria-disabled", "true");
  }

  link.addEventListener("click", (e) => {
    e.preventDefault();
    if (!disabled) onClickHandler();
  });

  li.appendChild(link);
  return li;
}

function createPrevNextButtons(currentPage, totalPages, records, containerId, totalgroup, isPrev) {
  const isDisabled = isPrev ? currentPage === 1 : currentPage === totalPages;
  const text = isPrev
    ? `<span class="label-wrapper">&laquo; Previous<span class="hover-symbol" aria-hidden="true">🚫</span></span>`
    : `<span class="label-wrapper">Next &raquo;<span class="hover-symbol" aria-hidden="true">🚫</span></span>`;

  const handler = () => {
    window.currentPage += isPrev ? -1 : 1;
    displayGroupedRules(records, containerId);
    addFwPagination(containerId, records, totalgroup);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  return createPaginationLink(text, isDisabled, handler);
}

function createPageNumberLinks(totalPages, currentPage, records, containerId, totalgroup) {
  const fragment = document.createDocumentFragment();

  for (let i = 1; i <= totalPages; i++) {
    const handler = () => {
      if (window.currentPage !== i) {
       window. currentPage = i;
        displayGroupedRules(records, containerId);
        addFwPagination(containerId, records, totalgroup);
        window.scrollTo({ top: 0, behavior: "smooth" });
      }
    };

    const li = createPaginationLink(i, false, handler, i === currentPage);
    li.querySelector("a").textContent = i;
    fragment.appendChild(li);
  }

  return fragment;
}



function showPopupCard1(title, content) {
  window.isPopupOpen = false;
  console.log("logPopup" ,content);
  const overlay = document.createElement("div");
  overlay.style.position = "fixed";
  overlay.style.top = "0";
  overlay.style.left = "0";
  overlay.style.width = "100%";
  overlay.style.height = "100%";
  overlay.style.backgroundColor = "rgba(0, 0, 0, 0.3)"; // Semi-transparent dark background
  overlay.style.backdropFilter = "blur(5px)"; // Apply blur effect
  overlay.style.zIndex = "999"; // Ensure it appears above everything else
  document.body.style.overflow = "hidden";
  document.body.appendChild(overlay);
  // Create popup container
  const popupContainer = document.createElement("div");
  popupContainer.style.position = "fixed";
  popupContainer.style.top = "50%";
  popupContainer.style.left = "50%";
  popupContainer.style.transform = "translate(-50%, -50%)";
  popupContainer.style.width = "50%"; // Increased default width
  popupContainer.style.maxWidth = "95%"; // Ensure it fits on smaller screens
  // popupContainer.style.height = "80%"; // Use viewport height to limit size
  popupContainer.style.backgroundColor = "#fff";
  popupContainer.style.border = "1px solid #ccc";
  popupContainer.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.2)";
  popupContainer.style.borderRadius = "12px"; // Increased border radius for a smoother look
  popupContainer.style.overflow = "hidden"; // Prevent content overflow
  popupContainer.style.fontFamily =
    "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif"; // Apply a system font
  popupContainer.style.zIndex = "1000";
  popupContainer.style.display = "flex";
  popupContainer.style.flexDirection = "column";
  popupContainer.style.height = "auto";
  popupContainer.style.maxHeight = "80vh";
  
  
  // Create header for title (fixed position)
  const popupHeader = document.createElement("div");
  popupHeader.style.padding = "16px 24px";
  popupHeader.style.borderBottom = "1px solid #ddd"; // Separate the title visually
  popupHeader.style.backgroundColor = "#fff";
  popupHeader.style.zIndex = "10"; // Ensure it appears above the scrollable content
  
  // Popup title
  const popupTitle = document.createElement("h2");
  popupTitle.textContent = title;
  popupTitle.style.paddingLeft = "15px"; // Move the title slightly to the right
  popupTitle.style.fontSize = "20px";
  popupTitle.style.color = "#333";
  popupTitle.style.textAlign = "left";
  popupHeader.appendChild(popupTitle);
  
  
  
  // Content wrapper (flex layout)
  const contentWrapper = document.createElement("div");
  contentWrapper.style.display = "flex";
  contentWrapper.style.flexDirection = "column";
  contentWrapper.style.flex = "1"; // Automatically take up available space
  contentWrapper.style.overflow = "hidden"; // Prevent content overflow
  
  // Content box (with fixed preview label)
  const contentBox = document.createElement("div");
  contentBox.style.flex = "1";
  contentBox.style.border = "1px solid #ddd";
  contentBox.style.borderRadius = "8px";
  contentBox.style.backgroundColor = "#f9f9f9";
  contentBox.style.padding = "16px";
  contentBox.style.margin = "16px 16px"; // Add vertical spacing
  contentBox.style.overflow = "hidden"; // Prevent outer scrolling
  contentBox.style.marginBottom = "75px"; // Add enough space for the close button
  contentBox.style.display = "flex";
contentBox.style.flexDirection = "column";
  
  // Preview label and line (sticky inside content box)
  const previewLabelContainer = document.createElement("div");
  previewLabelContainer.style.position = "sticky"; // Fix inside the content box
  previewLabelContainer.style.top = "0"; // Stick to the top
  previewLabelContainer.style.backgroundColor = "#f9f9f9"; // Match the content box background
  previewLabelContainer.style.zIndex = "1";
  previewLabelContainer.style.padding = "8px 0";
  
  const previewLabel = document.createElement("p");
  previewLabel.textContent = "Preview"; // Label text
  previewLabel.style.fontSize = "16px";
  previewLabel.style.fontWeight = "500";
  previewLabel.style.color = "#92a2b1";
  previewLabel.style.margin = "0";
  
  const lineBelowLabel = document.createElement("hr");
  lineBelowLabel.style.border = "none";
  lineBelowLabel.style.borderTop = "1px solid #ddd";
  lineBelowLabel.style.margin = "8px 0";
  
  previewLabelContainer.appendChild(previewLabel);
  previewLabelContainer.appendChild(lineBelowLabel);
  
  const scrollableContent = document.createElement("div");
scrollableContent.style.overflowY = "auto"; // Enable vertical scrolling
// scrollableContent.style.height = "calc(100% - 40px)"; // Adjust to fit within the content box
scrollableContent.style.height = "auto"; // Allow dynamic growth
scrollableContent.style.maxHeight = "60vh";
scrollableContent.style.flex = "1"; // Fill vertical space in contentBox

scrollableContent.style.minHeight = "0"
  
  
  
    const eventText = document.createElement("div");
    eventText.style.marginBottom = "12px";
    
    const createCustomBullet = (text, bulletColor, highlightColor) => {
      const listItem = document.createElement("li");
      listItem.style.position = "relative"; // For positioning the custom bullet
      listItem.style.paddingLeft = "10px"; // Space for custom bullet
    listItem.style.marginLeft ="9px"
      // Create the custom double circular bullet using a span element
      const bullet = document.createElement("span");
      bullet.style.position = "absolute";
      bullet.style.left = "-15px"; // Bring the bullet closer to the text (adjust this value)
      bullet.style.top = "50%"; // Center the bullet vertically
      bullet.style.transform = "translateY(-50%)"; // Center the bullet exactly
      bullet.style.width = "12px"; // Outer ring size
      bullet.style.height = "12px";
      bullet.style.border = `4px solid ${bulletColor || "#dcdfe1"}`; // Outer ring color and border size
      bullet.style.borderRadius = "50%"; // Make it a ring (circle with border)
      bullet.style.display = "inline-block";
    
      // Create the inner circle (smaller circle inside the outer ring)
      const innerBullet = document.createElement("span");
      innerBullet.style.position = "absolute";
      innerBullet.style.left = "50%";
      innerBullet.style.top = "50%";
      innerBullet.style.transform = "translate(-50%, -50%)"; // Centering the inner circle
      innerBullet.style.width = "2px"; // Inner circle size
      innerBullet.style.height = "2px";
      // innerBullet.style.backgroundColor = bulletColor || "#dcdfe1"; // Inner circle color
      innerBullet.style.borderRadius = "50%"; // Inner circle rounded
      innerBullet.style.display = "inline-block";
    
      // Append the inner circle to the outer circle (bullet)
      bullet.appendChild(innerBullet);
   // Split the text into words
   const words = text.split(" ");
      
   // Extract specific words
   const firstWord = words.shift(); // Remove first word
   const secondWord = words.shift(); // Remove second word
   const lastWord = words.pop(); // Extract last word
   const remainingText = words.join(" "); // Remaining words (excluding first, second, and last)
 
   // Construct the innerHTML with the second word in black and the last word in highlight color
   listItem.innerHTML = `
     <span>${firstWord}</span> 
     <span style="color: black; font-weight: 500;">${secondWord}</span> 
     ${remainingText} 
     <span style="color: ${highlightColor}; font-weight: 500;">${lastWord}</span>
   `;
 
   // Append the custom double circular bullet to the list item
   listItem.insertBefore(bullet, listItem.firstChild);
 
   return listItem;
  
    };
    
    // Function to remove HTML tags while preserving spaces
// const stripHTMLWithSpacing = (htmlString) => {
//   const tempElement = document.createElement("div");
//   tempElement.innerHTML = htmlString;
//   return tempElement.textContent.replace(/\s+/g, ' ').trim(); // Ensure proper spacing
// };

   // Function to create a styled bullet point for conditions/actions
const createConditionBullet = (condition, bulletColor = "#dcdfe1") => {
  // console.log("🔹 Original Condition:", condition); // Log initial condition


  const listItem = document.createElement("li");
  listItem.style.position = "relative";
  listItem.style.paddingLeft = "30px"; // Space for bullet
  listItem.style.display = "flex"; // Prevents breaking lines
  listItem.style.alignItems = "center"; // Keeps elements aligned

  // Create custom bullet
  const bullet = document.createElement("span");
  bullet.style.position = "absolute";
  bullet.style.left = "0";
  bullet.style.top = "50%";
  bullet.style.transform = "translateY(-50%)";
  bullet.style.width = "12px";
  bullet.style.height = "12px";
  bullet.style.border = `4px solid ${bulletColor || "#dcdfe1"}`;
  bullet.style.borderRadius = "50%";

  // Inner circle of bullet
  const innerBullet = document.createElement("span");
  innerBullet.style.position = "absolute";
  innerBullet.style.left = "50%";
  innerBullet.style.top = "50%";
  innerBullet.style.transform = "translate(-50%, -50%)";
  innerBullet.style.width = "8px";
  innerBullet.style.height = "8px";
  innerBullet.style.borderRadius = "50%";

  bullet.appendChild(innerBullet);

  // **Formatting Condition with Colors**
  const formattedCondition = condition
    .replace(/<div/g, ' <div') // Add space before <div> tags if missing
    .replace(/<div\s+class\s*=\s*["']?SummaryKey["']?\s*>(.*?)<\/div>/gi, ' <span style="color: black; font-weight: 500;">$1</span> ') 
    .replace(/<div\s+class\s*=\s*["']?SummaryValue["']?\s*>(.*?)<\/div>/gi, ' <span style="color: #00a886; font-weight: 500;">$1</span> ') 
    .replace(/<div\s+class\s*=\s*["']?SummaryOperator["']?\s*>(.*?)<\/div>/gi, ' <span> $1 </span> ') // Ensure space around operators
    .replace(/>\s+</g, '> <')  // Ensures space between inline elements
    .replace(/\s+/g, ' ')      // Remove multiple spaces
    .trim();                   // Trim any leading/trailing spaces

  // console.log("🟢 Formatted Condition (With Colors):", formattedCondition);

  // **Convert to Plain Text with Spaces**
  // const plainTextCondition = stripHTMLWithSpacing(formattedCondition);
  // console.log("🔹 Plain Text Condition (With Spaces):", plainTextCondition);

  // // Set bullet first, then append formatted text
  listItem.appendChild(bullet);
  
  // Create a span for the condition text (for proper spacing)
  const textSpan = document.createElement("span");
  textSpan.innerHTML = formattedCondition;
  textSpan.style.marginLeft = "-5px"; // Ensure space between bullet and text
  listItem.appendChild(textSpan);

  console.log("✅ Final List Item InnerHTML:", listItem.innerHTML); // Log final output

  return listItem;
};
 // Create the heading "Event:"
    const eventLabel = document.createElement("p");
    eventLabel.textContent = "Event";
    eventLabel.style.margin = "0";
    eventLabel.style.color = "#00a886"; // Blue color for heading
    eventLabel.style.fontWeight = "bold";
    eventLabel.style.fontSize = "16px";
  
    // Create the unordered list for the event details
    const eventDetail = document.createElement("ul");
    eventDetail.style.margin = "8px 0 0 -15px"; // Add margin and indentation
    eventDetail.style.color = "#333"; // Normal color for text
    eventDetail.style.listStyleType = "none"; // Remove default bullets
    eventDetail.style.fontSize = "14px";
    // Add event detail with the custom bullet
    const eventBullet = createCustomBullet(
      "When Ticket is Updated", // Text content
      "#2c5cc5", // Bullet color
      "#00a886" // Highlight color for the last word
    );
    eventDetail.appendChild(eventBullet);
    
    // Append the heading and the event detail to the container
    eventText.appendChild(eventLabel);
    eventText.appendChild(eventDetail);
    // Extract performer text (assuming it's a single string)
      const performerText = typeof content.performer === "string" ? stripHTML(content.performer) : "";
      
      // Add the performer to the content if it exists
      if (performerText) {
        console.log("performerText",performerText)
        const performerItem = createConditionBullet(content.performer, "#2c5cc5"); // Green bullet for performer
        performerItem.style.marginBottom = "10px";
        performerItem.style.marginTop = "10px"; // Add space after performer text
        performerItem.style.marginLeft = "10px"; 
        performerItem.style.fontSize ="14px";
        eventText.appendChild(performerItem);
      }
  // Add Event data to Event content
const eventArray = (Array.isArray(content.events) && content.events.length) 
    ? content.events 
    : (Array.isArray(content.eventText) && content.eventText.length) 
        ? content.eventText 
        : (content.events ? [content.events] : (content.eventText ? [content.eventText] : []));

eventArray.forEach(event => {
  if (event) {
    const stripped = stripHTML(event).trim().toLowerCase();

    if (stripped === "or" || stripped === "and") {
      const operatorSpan = document.createElement("div");
      operatorSpan.textContent = stripped.toUpperCase(); // Show "OR"/"AND"
      operatorSpan.style.color = "#333"; // Standard text color
      operatorSpan.style.fontWeight = "normal"; // Remove bold
      // operatorSpan.style.textAlign = "center"; // Center align
      operatorSpan.style.margin = "8px 0 5px 35px";// Add spacing like bullets
      operatorSpan.style.fontSize = "14px";

      eventText.appendChild(operatorSpan); // ✅ Plain text, centered
    } else {
      const eventItem = createConditionBullet(event, "#2c5cc5");
      eventItem.style.marginBottom = "10px";
      eventItem.style.marginTop = "10px";
      eventItem.style.marginLeft = "10px";
      eventItem.style.fontSize = "14px";
      eventText.appendChild(eventItem);
    }
  }
});
    
  // Create the conditions heading
  const conditionText = document.createElement("div");
  conditionText.textContent = "Condition";
  conditionText.style.marginBottom = "8px";
  conditionText.style.fontWeight = "bold";
  conditionText.style.color = "#e86f25"; // Green color for conditions heading
  conditionText.style.fontSize = "16px";
  
  // Create a container for the conditions list
  const conditionsList = document.createElement("ul");
  conditionsList.style.margin = "0 0 12px";
  conditionsList.style.padding = "8px";
  conditionsList.style.border = "1px solid #ddd";
  conditionsList.style.borderRadius = "4px";
  conditionsList.style.backgroundColor = "#fff";
  conditionsList.style.listStyleType = "none"; // Remove default bullet style
  conditionsList.style.fontSize = "14px";
  
 // Extract condition sets and operator
const conditionsArray1 = Array.isArray(content.conditions.condition_set_1)
? content.conditions.condition_set_1
: [];
const conditionsArray2 = Array.isArray(content.conditions.condition_set_2)
? content.conditions.condition_set_2
: [];
const operator = content.conditions.operator || "";
console.log("conditions array 1",conditionsArray1);




// // Create condition list container
// const conditionsList = document.createElement("ul");
// conditionsList.style.listStyleType = "none";
// conditionsList.style.padding = "0";

// Add conditions from condition_set_1
conditionsArray1.forEach((condition) => {
if (condition === "AND" || condition === "OR") {
  // Add operator as a separate text element
  const operatorItem = document.createElement("div");
  operatorItem.textContent = condition;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  conditionsList.appendChild(operatorItem);
} else {
  conditionsList.appendChild(createConditionBullet(condition, "#2c5cc5")); // Blue bullet
}
});

// Add operator between conditions (if available)
if (operator) {
const operatorItem = document.createElement("div");
operatorItem.textContent = operator;
operatorItem.style.color = "#000000";
operatorItem.style.margin = "8px 0";
operatorItem.style.fontSize = "14px";
operatorItem.style.fontweight = "500";
conditionsList.appendChild(operatorItem);
}

// Add conditions from condition_set_2
conditionsArray2.forEach((condition) => {
if (condition === "AND" || condition === "OR") {
  const operatorItem = document.createElement("div");
  operatorItem.textContent = condition;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  conditionsList.appendChild(operatorItem);
} else {
  conditionsList.appendChild(createConditionBullet(condition, "#2c5cc5")); // Blue bullet
}
});

// Create actions heading
const actionText = document.createElement("div");
actionText.textContent = "Action";
actionText.style.marginBottom = "8px";
actionText.style.fontWeight = "bold";
actionText.style.color = "#2c5cc5";
actionText.style.fontSize = "16px";

// Create actions content
const actionContent = document.createElement("ul");
actionContent.style.margin = "0";
actionContent.style.padding = "8px";
actionContent.style.border = "1px solid #ddd";
actionContent.style.borderRadius = "4px";
actionContent.style.backgroundColor = "#fff";
actionContent.style.listStyleType = "none";
actionContent.style.fontSize = "14px";

const actionsArray = Array.isArray(content.actions) ? content.actions : [];

// Add actions with custom bullets
actionsArray.forEach((action) => {
if (action === "AND" || action === "OR") {
  const operatorItem = document.createElement("div");
  operatorItem.textContent = action;
  operatorItem.style.color = "#6c757d";
  operatorItem.style.margin = "8px 0 5px 29px";
  actionContent.appendChild(operatorItem);
} else {
  actionContent.appendChild(createConditionBullet(action, "#2c5cc5")); // Blue bullet for actions
}
});
  
  // Append the label and line to the content box
  contentBox.appendChild(previewLabel);
  contentBox.appendChild(lineBelowLabel);
  
  scrollableContent.appendChild(eventText);
  scrollableContent.appendChild(conditionText);
  scrollableContent.appendChild(conditionsList);
  scrollableContent.appendChild(actionText);
  scrollableContent.appendChild(actionContent);
  
  // Append content to the scrollable wrapper
  
  contentBox.appendChild(scrollableContent);
  
  // Create fw-button element with "primary" color
  const closeButton = document.createElement("fw-button");
  closeButton.setAttribute("color", "primary");
  closeButton.textContent = "Close";
  closeButton.style.position = "absolute";
  closeButton.style.bottom = "16px"; // Distance from the bottom
  closeButton.style.right = "16px"; // Distance from the right
  closeButton.style.padding = "8px 16px"; // Padding for the button
  closeButton.style.borderRadius = "4px"; // Rounded corners
  closeButton.style.cursor = "pointer";
  
  // Close popup and remove overlay when the button is clicked
  closeButton.addEventListener("click", () => {
    document.body.removeChild(popupContainer);
    document.body.removeChild(overlay);
    document.body.style.overflow = "";
     window.isPopupOpen = false;
  });
  
  popupContainer.appendChild(popupHeader); // Fixed title
  popupContainer.appendChild(contentBox);
  // popupContainer.appendChild(headerContainer); // Fixed preview label and line
  // popupContainer.appendChild(wrapper); // Scrollable content
  popupContainer.appendChild(closeButton); // Close button
  
  // Append elements to the document
  document.body.appendChild(overlay);
  document.body.appendChild(popupContainer);
  
  }



// function findDuplicateRulestype4(records) {
//   const seenRules = new Map();
//   const duplicateRecords = [];

//   function 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, '')   // Remove hidden Unicode
//       .replace(/[.]/g, '')                    // Remove full stops
//       .replace(/\s*,\s*/g, ',')               // Normalize space around commas
//       .replace(/\s+/g, ' ')                   // Normalize extra spaces
//       .trim()
//       .toLowerCase();
//   }

// const normalizeConditionParts = (rawConditions) => {
//   const parts = rawConditions?.split(",") || [];
//   const set1 = [], set2 = [];
//   let currentSet = null;
//   window.tempClause = [];

//   const pushClause = (targetSet, includeOperator = null) => {
//     if (window.tempClause.length && targetSet) {
//       const joinedClause = window.tempClause.join(",").trim();
//       const cleaned = stripHTML4(joinedClause);
//       if (cleaned) targetSet.push(cleaned);
//       window.tempClause = [];

//       if (includeOperator) {
//         targetSet.push(includeOperator); // ✅ push 'all' or 'any' as part of structure
//       }
//     }
//   };

//   const isSetMarker = (part) =>
//     part.includes("condition_set_1") || part.includes("condition_set_2");

//   const handleSetSwitch = (rawPart) => {
//     pushClause(currentSet); // push last clause before switching
//     if (rawPart.includes("condition_set_1")) return set1;
//     if (rawPart.includes("condition_set_2")) return set2;
//     return currentSet;
//   };

//   const isLogicalOperator = (part) => part === "any" || part === "all";

//   for (let i = 0; i < parts.length; i++) {
//     const rawPart = parts[i].trim();

//     if (isSetMarker(rawPart)) {
//       currentSet = handleSetSwitch(rawPart);
//     } else if (isLogicalOperator(rawPart.toLowerCase())) {
//       // Push current clause + the logical operator into the same set
//       pushClause(currentSet, rawPart.toLowerCase());
//     } else if (currentSet) {
//       window.tempClause.push(rawPart);
//     }
//   }

//   pushClause(currentSet); // Push any remaining clause

//   set1.sort();
//   set2.sort();

//   console.log("🔹 Sorted Set1:", set1);
//   console.log("🔸 Sorted Set2:", set2);

//   return { set1, set2 };
// };




//   // const normalizeConditionParts = (rawConditions) => {
//   //   const parts = rawConditions?.split(",") || [];
//   //   const set1 = [];
//   //   const set2 = [];
//   //   let currentSet = null;
//   //   window.tempClause = [];

//   //   const pushClause = (targetSet) => {
//   //     if (window.tempClause.length && targetSet) {
//   //       const clause = stripHTML4(window.tempClause.join(","));
//   //       if (clause) targetSet.push(clause);
//   //       window.tempClause = [];
//   //     }
//   //   };

//   //   for (let i = 0; i < parts.length; i++) {
//   //     const part = parts[i].trim().toLowerCase();

//   //     if (part.includes("condition_set_1")) {
//   //       pushClause(currentSet);
//   //       currentSet = set1;
//   //       continue;
//   //     }
//   //     if (part.includes("condition_set_2")) {
//   //       pushClause(currentSet);
//   //       currentSet = set2;
//   //       continue;
//   //     }

//   //     if (part === "any" || part === "all") {
//   //       pushClause(currentSet);
//   //       continue;
//   //     }

//   //     if (currentSet) {
//   //       window.tempClause.push(parts[i]); // preserve formatting
//   //     }
//   //   }

//   //   pushClause(currentSet);
//   //   set1.sort();
//   //   set2.sort();

//   //   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)                     // Split on "or"
//       .map((item) => stripHTML4(item))       // Clean each part
//       .sort()
//       .join(" or ");                         // Join back in consistent order
//   };

//   const normalizeActions = (rawActions) => {
//     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(" | ");
//   };

//   records.forEach((record, index) => {
//     const { conditions, actions, operator, events, performer } = record.data;

//     const { set1, set2 } = normalizeConditionParts(conditions);
//     const normalizedActions = normalizeActions(actions);
//     const normalizedEvents = normalizeEvents(events); // ✅ New logic here
//     const normalizedPerformer = normalizeField(performer);
//     const normalizedOperator = operator ? stripHTML4(operator) : "";

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

//     console.log(`\n=== Record ${index + 1} ===`);
//     console.log("Condition Set 1:", set1);
//     console.log("Condition Set 2:", set2);
//     console.log("Actions:", normalizedActions);
//     console.log("Operator:", normalizedOperator);
//     console.log("Events:", normalizedEvents);
//     console.log("Performer:", normalizedPerformer);
//     console.log("Key 1:", key1);
//     console.log("Key 2:", key2);

//     if (seenRules.has(key1) || seenRules.has(key2)) {
//       console.log(`🔁 Duplicate found for Record ${index + 1}`);
//       const existing = seenRules.get(key1) || seenRules.get(key2);
//       if (!duplicateRecords.includes(existing)) {
//         duplicateRecords.push(existing);
//       }
//       duplicateRecords.push(record);
//     } else {
//       seenRules.set(key1, record);
//       console.log(`🆕 First time seen for Record ${index + 1}`);
//     }
//   });

//   return duplicateRecords;
// }

function findDuplicateRulestype4(records) {
  const seenRules = new Map();
  const duplicateRecords = [];

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

  const div = document.createElement("div");
  div.innerHTML = htmlString.replace(/&nbsp;/gi, " "); // Convert &nbsp; to space for safe parsing

  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, "")  // Remove hidden/unicode spaces
    .replace(/\./g, "")                   // Remove full stops
    .replace(/\s+/g, "")                  // 🔥 Remove ALL spaces
    .toLowerCase();                       // Normalize case
};

  // ✅ Updated HTML stripper to preserve word separation
  // function 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);  // 👈 preserve space between tags
  //       }
  //     }
  //     return result;
  //   }

  //   return walkAndClean(div)
  //     .replace(/\u200B|\uFEFF|\u00A0/g, '')   // Remove hidden Unicode & non-breaking spaces
  //     .replace(/[.]/g, '')                    // Remove full stops
  //     .replace(/\s*,\s*/g, ',')               // Normalize space around commas
  //     .replace(/\s+/g, ' ')                   // Collapse multiple spaces
  //     .trim()
  //     .toLowerCase();
  // }

  const normalizeConditionParts = (rawConditions) => {
    const parts = rawConditions?.split(",") || [];
    const set1 = [], set2 = [];
    let currentSet = null;
    window.tempClause = [];

    const pushClause = (targetSet, includeOperator = null) => {
      if (window.tempClause.length && targetSet) {
        const joinedClause = window.tempClause.join(",").trim();
        const cleaned = stripHTML4(joinedClause);
        if (cleaned) targetSet.push(cleaned);
        window.tempClause = [];

        if (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) => part === "any" || part === "all";

    for (let i = 0; i < parts.length; i++) {
      const rawPart = parts[i].trim();

      if (isSetMarker(rawPart)) {
        currentSet = handleSetSwitch(rawPart);
      } else if (isLogicalOperator(rawPart.toLowerCase())) {
        pushClause(currentSet, rawPart.toLowerCase());
      } else if (currentSet) {
        window.tempClause.push(rawPart);
      }
    }

    pushClause(currentSet);
    set1.sort();
    set2.sort();

    console.log("🔹 Sorted Set1:", set1);
    console.log("🔸 Sorted 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) => {
    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();  // ✅ joins with space after sorting
      if (clause) normalizedClauses.push(clause);
    }

    normalizedClauses.sort((a, b) => a.localeCompare(b));
    return normalizedClauses.join(" | ");
  };

  records.forEach((record, index) => {
    const { conditions, actions, operator, events, performer } = record.data;

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

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

    console.log(`\n=== Record ${index + 1} ===`);
    console.log("Condition Set 1:", set1);
    console.log("Condition Set 2:", set2);
    console.log("Actions:", normalizedActions);
    console.log("Operator:", normalizedOperator);
    console.log("Events:", normalizedEvents);
    console.log("Performer:", normalizedPerformer);
    console.log("Key 1:", key1);
    console.log("Key 2:", key2);

    if (seenRules.has(key1) || seenRules.has(key2)) {
      console.log(`🔁 Duplicate found for Record ${index + 1}`);
      const existing = seenRules.get(key1) || seenRules.get(key2);
      if (!duplicateRecords.includes(existing)) {
        duplicateRecords.push(existing);
      }
      duplicateRecords.push(record);
    } else {
      seenRules.set(key1, record);
      console.log(`🆕 First time seen for Record ${index + 1}`);
    }
  });

  return duplicateRecords;
}







  





  


explain this code