importScripts("contentScript.js");
importScripts("js/moment.min.js");
importScripts("js/aws.min.js");

// importScripts("offscreen.js");
importScripts("js/moment-timezone.js");
let endpointUrl = "https://api.workstatus.io/api/v1/";

let timeLogoutState = false;

// let endpointUrl = 'https://api.dev.workstatus.io/api/v1/';

// console.log("background start");
// console.log(moment.tz.guess());

async function addLog(log, time) {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onsuccess = () => {
      const db = request.result;
      const transaction = db.transaction("logger", "readwrite");
      const store = transaction.objectStore("logger");

      const addRequest = store.add({ log, time });

      addRequest.onsuccess = () => resolve("Log added successfully");
      addRequest.onerror = (event) =>
        reject("Error adding log: " + event.target.error);
    };

    request.onerror = (event) =>
      reject("Error opening database: " + event.target.error);
  });
}

function getBrowserName() {
  const userAgent = navigator.userAgent;

  if (userAgent.includes("Chrome") && !userAgent.includes("Edg") && !userAgent.includes("OPR")) {
    return "google"; // Google Chrome
  } else if (userAgent.includes("Edg")) {
    return "edge"; // Microsoft Edge
  } else if (userAgent.includes("Trident") || userAgent.includes("MSIE")) {
    return "explorer"; // Internet Explorer
  } else if (userAgent.includes("Firefox")) {
    return "firefox";
  } else if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) {
    return "safari";
  } else if (userAgent.includes("OPR")) {
    return "opera";
  } else {
    return "google";
  }
}

// ----------------------------------------------------------------------------------------

const checkHeartBeat = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("HeartBeat", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.HeartBeat || 0); // Resolve with the data or null
      }
    });
  });
};

async function checkIfRunningBeforeStart() {
  let val = await checkHeartBeat();
  if (val == 1) {
    await addLog(
      "INFO - System Restarted or Reboot",
      moment().format("YYYY-MM-DD HH:mm:ss")
    );
    chrome.storage.local.set({ stopTimer: 1 });
    // console.log("ALIVE !! Before START");
  }
}

checkIfRunningBeforeStart();

async function deleteCurrentTimerData(id) {
  return new Promise((resolve, reject) => {
    try {
      let idb = indexedDB.open("wstracker_new_db", 1);

      idb.onsuccess = () => {
        let db = idb.result;
        let tx = db.transaction("currentTimerData", "readwrite");
        let store = tx.objectStore("currentTimerData");

        // If id is provided, delete specific entry, otherwise clear all entries
        let request = id ? store.delete(id) : store.clear();

        request.onsuccess = () => {
          resolve("Data deleted successfully");
        };

        request.onerror = () => {
          reject("Failed to delete data");
        };
      };

      idb.onerror = () => {
        reject("Database connection error");
      };
    } catch (err) {
      reject("Error occurred");
    }
  });
}

const isStillBreak = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("breakstarted", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.breakstarted || null); // Resolve with the data or null
      }
    });
  });
};
async function getTotalSyncTimerData() {
  return new Promise((resolve) => {
    try {
      let idb = indexedDB.open("wstracker_new_db", 1);

      idb.onsuccess = () => {
        let db = idb.result;
        let tx = db.transaction("SyncDataTimer", "readonly");
        let store = tx.objectStore("SyncDataTimer");
        let request = store.getAll(); // Get all records
        request.onsuccess = () => {
          const allData = request.result;
          // Calculate the sum of all timeLog values, checking that item is not null
          const totalTimeLog = allData.reduce((sum, item) => {
            if (item != null && item.timeLog != null) {
              return sum + (parseInt(item.timeLog) || 0); // Add timeLog if it exists, otherwise add 0
            }
            return sum; // If item is null or timeLog is null, don't add anything
          }, 0);

          resolve(parseInt(totalTimeLog)); // Return the total sum
        };

        request.onerror = () => {
          resolve(0); // Resolve with 0 on error
        };
      };

      idb.onerror = () => {
        resolve(0); // Resolve with 0 on database connection error
      };
    } catch (err) {
      resolve(0); // Resolve with 0 on synchronous errors
    }
  });
}

async function addSyncTimerData(timeLog, projectId, todoId) {
  return new Promise((resolve, reject) => {
    try {
      let idb = indexedDB.open("wstracker_new_db", 1);

      idb.onupgradeneeded = () => {
        let db = idb.result;

        // Create object store if it doesn't exist
        if (!db.objectStoreNames.contains("SyncDataTimer")) {
          db.createObjectStore("SyncDataTimer", {
            keyPath: "id",
            autoIncrement: true,
          });
        }
      };

      idb.onsuccess = () => {
        let db = idb.result;
        let tx = db.transaction("SyncDataTimer", "readwrite");
        let store = tx.objectStore("SyncDataTimer");
        const data = {
          timeLog: timeLog,
          projectId: projectId,
          todoId: todoId,
        };

        store.add(data); // Add data without expecting any ID in return

        tx.oncomplete = () => {
          resolve("Data stored successfully"); // Just resolve success message
        };

        tx.onerror = () => {
          reject(tx.error); // Reject on error
        };
      };

      idb.onerror = () => {
        reject(idb.error); // Handle database connection error
      };
    } catch (err) {
      reject(err); // Handle synchronous errors
    }
  });
}

async function setTotalTime() {
  try {
    const totalTime = await getTotalSyncTimerData();
    if (totalTime) {
      var startTimestamp = moment().startOf("day").add(totalTime, "s");
      document.getElementById("timerData").innerHTML =
        startTimestamp.format("HH:mm:ss");
    }
  } catch (err) {
    await addLog(err, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.log(err);
  }
}

const getUserDetail = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("userDetail", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.userDetail || null); // Resolve with the data or null
      }
    });
  });
};

const syncTimerData = async () => {
  const postData = {
    date: moment().format("YYYY-MM-DD"),
    tracker: 0,
  };
  const retriveItem = await getUserDetail();
  const headers = {
    SDToken: retriveItem.sd_token,
    Authorization: `Bearer ${retriveItem.token}`,
    OrgID: retriveItem.org_id,
    "Content-Type": "application/json",
    UserID: retriveItem.id,
    deviceType: "Chrome_extension",
  };
  const syncUrl = "https://api.workstatus.io/api/v1/activity/syncTimer";

  try {
    const syncResponse = await fetch(syncUrl, {
      method: "POST",
      headers,
      body: JSON.stringify(postData),
    });

    const syncResult = await syncResponse.json();

    if (syncResult.response.code !== "200") {
      // console.log(syncResult.data);
    } else {
      // console.log(syncResult.response.message);
      await addLog(
        "INFO- :: RESPONSE= " + syncResult.response,
        moment().format("YYYY-MM-DD HH:mm:ss")
      );
      for (const item of syncResult.response.data) {
        let tmp = item.todoId == null ? 0 : item.todoId;
        await addSyncTimerData(item.timeLog, item.projectId, tmp);
      }
    }
  } catch (error) {
    await addLog(error, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.error("Error syncing timer:", error);
  }
};

async function deleteAllSyncTimerData() {
  return new Promise((resolve) => {
    try {
      let idb = indexedDB.open("wstracker_new_db", 1);

      idb.onsuccess = () => {
        let db = idb.result;
        let tx = db.transaction("SyncDataTimer", "readwrite");
        let store = tx.objectStore("SyncDataTimer");
        let clearRequest = store.clear(); // Clear all records

        clearRequest.onsuccess = () => {
          resolve(true); // Resolve with true if deletion is successful
        };

        clearRequest.onerror = () => {
          resolve(false); // Resolve with false on deletion error
        };
      };

      idb.onerror = () => {
        resolve(false); // Resolve with false on database connection error
      };
    } catch (err) {
      resolve(false); // Resolve with false on synchronous errors
    }
  });
}

// ----------------------------------------------------------------------------------------

function MakeLogout() {
  chrome.storage.local.set({ HeartBeat: 0 });
  chrome.storage.local.set({ setuserlogout: 1 });
}

async function setUserdata(tbl, value, version) {
  try {
    // console.log("calling common");
    let idb = indexedDB.open("wstracker_new_db", 1);
    // console.log("idb", idb);
    idb.onsuccess = async () => {
      let res = idb.result;
      let tx = res.transaction(tbl, "readwrite");
      let store = tx.objectStore(tbl);
      const lastinsertdata = store.put(value);
      // console.log(typeof lastinsertdata);
      res.close();
      setTimeout(() => {
        // console.log("onSuccess return --->", lastinsertdata.result);
        return lastinsertdata.result;
      }, 100);
    };
  } catch (err) {
    await addLog("Error --" + err, moment().format("YYYY-MM-DD HH:mm:ss"));
    // console.log("db error", err);
    return false;
  }
}

async function updateScreenshotInterval() {
  try {
    // console.log("getscreenshotInterval");
    const url = endpointUrl + "user/screenshotInterval";
    let retriveItem = await getUserDetail();
    const data = {
      organization_id: retriveItem.org_id,
      user_id: retriveItem.id,
    };

    const headers = {
      SDToken: retriveItem.sd_token,
      Authorization: "Bearer " + retriveItem.token,
      OrgID: retriveItem.org_id,
      "Content-Type": "application/json",
      UserID: retriveItem.id,
      deviceType: "Chrome_extension",
    };

    const response = await fetch(url, {
      method: "POST",
      headers: headers,
      body: JSON.stringify(data),
    });

    const result = await response.json();

    if (result.response.code !== "200") {
      window.location.href = "logout.html";
      // console.log("screenshot_interval", result.response.message);
    } else {
      // setLocalStorage("todoDetail", result.response.data);
      await chrome.storage.local.set({
        todoDetail: result.response.data,
      });
      await chrome.storage.local.set({
        todoDetailChrome: result.response.data,
      });
      await chrome.storage.local.set({
        SSInterval: result.response.data.timeInterval,
      });
      await chrome.storage.local.set({
        SSNotify: result.response.data.notification_status,
      });
      await chrome.storage.local.set({
        SSFrequency: result.response.data.ssfrequencystatus,
      });
      await chrome.storage.local.set({
        isSSBlur: result.response.data.screenshotblurstatus,
      });

      // console.log(result.response.data);
      await setUserdata("screenshot_interval", result.response.data, 6);
    }
  } catch (error) {
    await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
    // console.error("Error updating screenshot interval:", error);
    // window.location.href = "logout.html";
  }
}

function jsonBG(url) {
  return fetch(url).then((res) => res.json());
}

function sendIdleNotification() {
  chrome.notifications.create(
    "System Idle",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message:
        "Your timer is idle due to inactivity. Resume when you're ready!",
    },
    function (res) {
      // console.log("System Idle Popup done!", res);
    }
  );
}

setInterval(function timeChecker() {
  var oldTime = timeChecker.oldTime || new Date(),
    newTime = new Date(),
    timeDiff = newTime - oldTime;
  //console.log("oldTime - "+oldTime+' -newtime'+newTime);

  timeChecker.oldTime = newTime;
  //console.log("DEBUG-TIME-DIFF" + timeDiff);
  if (Math.abs(timeDiff) >= 600000) {
  }

  // if (Math.abs(timeDiff) >= 300000) {
  //   console.log("hii--------------->>>>>>");
  //   sendIdleNotification();
  //   chrome.storage.local.set({ isIdle: true });
  //   chrome.storage.local.set({ prevTime: oldTime.toISOString() });
  //   chrome.storage.local.set({ timeDiff: timeDiff });
  //   chrome.storage.local.set({ userIdle: "true" });
  // }
}, 5000);

var bgalive = setInterval(() => {
  // chrome.runtime.sendMessage({ keepAlive: true });
  // console.log("Background Is Still ALIVE");
}, 20000);

setInterval(() => {
  chrome.storage.local.get(["logout"]).then((logoutres) => {
    if (logoutres.logout == 1) {
      chrome.storage.local.set({ logout: 0 });
      // chrome.runtime.reload()ß
      clearInterval(bgalive);
    }
  });
}, 5000);

////////////////////////////////////////////////////////

////////////////////////
chrome.action.onClicked.addListener((tab) => {
  if (tab.id && tab.url) {
    chrome.scripting.executeScript(
      {
        target: { tabId: tab.id },
        files: ["content.js"],
      },
      () => {
        if (chrome.runtime.lastError) {
          console.error(
            `Failed to inject content script: ${chrome.runtime.lastError.message}`
          );
        } else {
          console.log("Content script injected successfully.");
        }
      }
    );
  } else {
    console.error("Invalid tab or URL.");
  }
});

// console.log("MY BACKGROUND.JS CODE STARTS FROM HERE...");
let INTERVAL = 600;
let SSINTERVAL = 300;
let SSFreq = 1;
// console.log("------heeeeeeee-------");

function convertISTToCustomFormat(istDateString) {
  // Parse the input IST date string,
  const date = new Date(istDateString);

  // Check if the input date string is valid
  if (isNaN(date.getTime())) {
    throw new Error("Invalid date string");
  }

  // Extract the exact date and time components from the original string
  const [year, month, day] = [
    date.getFullYear(),
    (date.getMonth() + 1).toString().padStart(2, "0"), // Ensure two-digit month
    date.getDate().toString().padStart(2, "0"), // Ensure two-digit day
  ];
  const [hours, minutes, seconds] = [
    date.getHours().toString().padStart(2, "0"),
    date.getMinutes().toString().padStart(2, "0"),
    date.getSeconds().toString().padStart(2, "0"),
  ];

  // Return the formatted string as "YYYY-MM-DD HH:mm:ss"
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// console.log(convertISTToCustomFormat(new Date()));

function getStorage(key) {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get(key, function (result) {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve(result);
      }
    });
  });
}

const checkKrna = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("nhikrna", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.nhikrna || 0); // Resolve with the data or null
      }
    });
  });
};

// Utility function to promisify chrome.storage.local.set
function setStorage(data) {
  return new Promise((resolve, reject) => {
    chrome.storage.local.set(data, function () {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve();
      }
    });
  });
}

const globalActivityData = {
  keyboardEvents: [],
  mouseEvents: [],
  keyboardCount: 0,
  mouseMoveCount: 0,
  mouseClickCount: 0,
  keyboardActivityArray: new Array(INTERVAL).fill(false), // Replace `10` with your INTERVAL value
  mouseActivityArray: new Array(INTERVAL).fill(false),
  payloadsIntervals: [],
  LastIntervalEnd: null,
};

// Initializing GlobalActivityData
function initializeGlobalActivityData() {
  chrome.storage.local.get("globalActivityData", (result) => {
    if (!result.globalActivityData) {
      chrome.storage.local.set(
        { globalActivityData: globalActivityData },
        () => {
          // console.log("globalActivityData initialized with default values.");
        }
      );
    } else {
      // console.log("globalActivityData already exists.");
    }
  });
}
initializeGlobalActivityData();

function getInterval(interval) {
  // Get the current date and time
  const now = new Date();

  // Extract the current minute
  const minute = now.getMinutes();

  // Convert interval to minutes
  const intervalInMinutes = interval / 60;

  // Round down to the nearest interval
  const roundedMinute =
    Math.floor(minute / intervalInMinutes) * intervalInMinutes;

  // Create the start date with the rounded minute
  const startDate = new Date(
    now.getFullYear(),
    now.getMonth(),
    now.getDate(),
    now.getHours(),
    roundedMinute,
    0,
    0
  );

  // Calculate the end date by adding the interval
  const endDate = new Date(startDate.getTime() + interval * 1000);

  // Format the date into "YYYY-M-D HH:mm:ss"
  const formatDate = (date) => {
    const year = date.getFullYear();
    const month = date.getMonth() + 1; // Months are 0-based
    const day = date.getDate();
    const hours = date.getHours();
    const minutes = date.getMinutes().toString().padStart(2, "0");
    const seconds = date.getSeconds().toString().padStart(2, "0");
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  };

  // console.log(
  //   `Starting Date: ${formatDate(startDate)} slot: ${intervalInMinutes}`
  // );
  return {
    startTime: formatDate(startDate),
    endTime: formatDate(endDate),
  };
}

function getCurrentEndTime() {
  const now = new Date();
  // Extract components with proper zero-padding
  const year = now.getFullYear();
  const month = (now.getMonth() + 1).toString().padStart(2, "0"); // Ensure two-digit month
  const date = now.getDate().toString().padStart(2, "0"); // Ensure two-digit day
  const hours = now.getHours().toString().padStart(2, "0");
  const minutes = now.getMinutes().toString().padStart(2, "0");
  const seconds = now.getSeconds().toString().padStart(2, "0");
  // Format the date and time correctly
  return `${year}-${month}-${date} ${hours}:${minutes}:${seconds}`;
}

function getCurrentInterval(interval) {
  // Set the last minute threshold
  let lastMinute = 50;
  if (interval / 60 === 15) {
    lastMinute = 45;
  }

  const now = new Date();
  let startTime = new Date(now);
  startTime.setMilliseconds(0); // Clear milliseconds

  const seconds = startTime.getSeconds(); // Get the current seconds
  const minute = startTime.getMinutes();
  let endTime;

  if (minute < lastMinute) {
    // Calculate the next interval's end minute
    const intervalMinutes = interval / 60; // Convert interval to minutes
    const newMinute = intervalMinutes - (minute % intervalMinutes) + minute;
    endTime = new Date(startTime);
    endTime.setMinutes(newMinute);
    endTime.setSeconds(0); // Keep seconds consistent
  } else {
    // If beyond the threshold, roll over to the next hour
    endTime = new Date(startTime);
    endTime.setMinutes(0);
    endTime.setHours(startTime.getHours() + 1);
    endTime.setSeconds(0); // Keep seconds consistent
  }

  // Function to format time into "YYYY-MM-DD HH:mm:ss"
  function formatTime(date) {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    const hours = String(date.getHours()).padStart(2, "0");
    const minutes = String(date.getMinutes()).padStart(2, "0");
    const seconds = String(date.getSeconds()).padStart(2, "0");
    return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
  }

  // Log and return the formatted times
  // console.log(
  //   `Start Time: ${formatTime(startTime)}, End Time: ${formatTime(
  //     endTime
  //   )}, Slot: ${interval / 60} minutes`
  // );

  return {
    startTime: formatTime(startTime),
    endTime: formatTime(endTime),
  };
}

let activity_startTime;

function getActivityLevel(globalActivityData) {
  let currentTime = Date.now();

  // Calculate activity percentage based on mouse and keyboard activity
  let activeSeconds = 0;
  for (let i = 0; i < INTERVAL; i++) {
    if (
      globalActivityData.keyboardActivityArray[i] ||
      globalActivityData.mouseActivityArray[i]
    ) {
      activeSeconds++;
    }
  }

  let activityPercentage = (activeSeconds / INTERVAL) * 100;

  let countK = 0;
  let countM = 0;

  for (let i = 0; i < INTERVAL; i++) {
    if (globalActivityData.keyboardActivityArray[i] == true) {
      countK++;
    }
  }
  for (let i = 0; i < INTERVAL; i++) {
    if (globalActivityData.mouseActivityArray[i] == true) {
      countM++;
    }
  }

  // console.log("-------------------------------------------COUNT M AND K");
  // console.log(countK, countM);
  // Calculate weighted activity levels
  let keyboardActivity = Math.min((countK * 100) / INTERVAL, 100);
  let mouseActivity = Math.min((countM * 100) / INTERVAL, 100);

  // Calculate total activity (keyboard + mouse)
  let totalActivity =
    globalActivityData.keyboardCount +
    globalActivityData.mouseMoveCount +
    globalActivityData.mouseClickCount;

  // Log activity data
  let activityLog = {
    timestamp: new Date(currentTime).toISOString(),
    module: "ActivityMonitor",
    keyboardActivity: globalActivityData.keyboardCount,
    keyPressed: globalActivityData.keyboardEvents,
    mouseActivity: globalActivityData.mouseMoveCount,
    mouseClicks: globalActivityData.mouseClickCount,
    mouseClicked: globalActivityData.mouseEvents,
    totalActivity: totalActivity,
    activityLevelPercent: activityPercentage,
  };

  // console.log(JSON.stringify(activityLog));

  // Reset activity arrays after logging
  keyboardActivityArray = new Array(INTERVAL).fill(false);
  mouseActivityArray = new Array(INTERVAL).fill(false);

  // Reset activity counters after logging
  let previousKeyboardCount = globalActivityData.keyboardCount;
  let previousKeyboardEvents = globalActivityData.keyboardEvents;
  let previousMouseClickCount = globalActivityData.mouseClickCount;
  let previousMouseEvents = globalActivityData.mouseEvents;
  let previousMouseMoveCount = globalActivityData.mouseMoveCount;

  keyboardCount = 0;
  mouseMoveCount = 0;
  mouseClickCount = 0;
  keyboardEvents = [];
  mouseEvents = [];

  // resetTracking();
  return {
    activityLevel: {
      mouse: mouseActivity,
      average: activityPercentage,
      keyboard: keyboardActivity,
      mouseMoveCount: previousMouseMoveCount,
    },
    activityEntity: {
      keyboardCount: previousKeyboardCount,
      keyboardActivity: previousKeyboardEvents,
      mouseClickCount: previousMouseClickCount,
      mouseActivity: previousMouseEvents,
      timestamp: new Date(currentTime).toISOString(),
    },
  };
}

//-------------------  url

function convertUTCtoIST(utcTimestamp) {
  // Parse the UTC timestamp to ensure it's treated as UTC
  const utcDate =
    typeof utcTimestamp === "string"
      ? new Date(utcTimestamp.endsWith("Z") ? utcTimestamp : utcTimestamp + "Z")
      : new Date(utcTimestamp);

  if (isNaN(utcDate.getTime())) {
    throw new Error("Invalid UTC timestamp");
  }

  // Convert UTC time to IST (UTC + 5:30)
  const istOffset = 5.5 * 60 * 60 * 1000; // 5 hours 30 minutes in milliseconds
  const istDate = new Date(utcDate.getTime() + istOffset);

  // Format the date as "YYYY-MM-DD HH:MM:SS"
  const year = istDate.getUTCFullYear();
  const month = String(istDate.getUTCMonth() + 1).padStart(2, "0"); // Months are zero-based
  const day = String(istDate.getUTCDate()).padStart(2, "0");
  const hours = String(istDate.getUTCHours()).padStart(2, "0");
  const minutes = String(istDate.getUTCMinutes()).padStart(2, "0");
  const seconds = String(istDate.getUTCSeconds()).padStart(2, "0");

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

function getISTDifferenceInSeconds(datetime1, datetime2) {
  // console.log(
  //   "******************************HEHEHEHEHEH  MMMMMMM LLLLLLL ***************************************"
  // );
  // console.log(datetime1);
  // console.log(datetime2);

  // Helper function to parse input (handle both strings and Date objects)
  function parseToIST(dateInput) {
    if (typeof dateInput === "string") {
      // Convert IST datetime string to a Date object
      return new Date(dateInput.replace(" ", "T") + "+05:30");
    } else if (dateInput instanceof Date) {
      // Adjust the Date object to IST (UTC + 5:30)
      const istOffset = 5.5 * 60 * 60 * 1000;
      return new Date(dateInput.getTime() + istOffset);
    } else {
      throw new Error("Invalid input: Expected a string or Date object");
    }
  }

  // Parse the inputs to IST Date objects
  const date1 = parseToIST(datetime1);
  const date2 = parseToIST(datetime2);

  // Calculate the difference in milliseconds
  const differenceInMilliseconds = Math.abs(date2 - date1);

  // Convert the difference to seconds
  return Math.floor(differenceInMilliseconds / 1000);
}

const getIntervalFromDb = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("currentInterval", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.currentInterval.startTime || null); // Resolve with the data or null
      }
    });
  });
};

async function fetchURL(urlStartTime, timeInterval) {
  const tenMinutesAgo = Date.now() - timeInterval * 60 * 1000; // 10 minutes ago

  // Wrap chrome.history.search in a Promise
  const searchHistory = () => {
    return new Promise((resolve, reject) => {
      chrome.history.search(
        { text: "", startTime: tenMinutesAgo },
        (historyItems) => {
          if (chrome.runtime.lastError) {
            reject(chrome.runtime.lastError);
          } else {
            resolve(historyItems);
          }
        }
      );
    });
  };

  try {
    const historyItems = await searchHistory();
    let prevUrlTime = urlStartTime;
    // console.log("--------------------PREVURL TIME------------------------");
    // console.log(prevUrlTime);
    const results = historyItems.map((item) => {
      let ts = new Date(item.lastVisitTime).toISOString();
      let urlTime = convertUTCtoIST(ts);
      let timeSpent = getISTDifferenceInSeconds(urlTime, prevUrlTime);
      prevUrlTime = urlTime;
      // console.log("----------------------INSIDE MAP-------------------------");
      // console.log(prevUrlTime);
      // console.log(urlTime);
      return {
        name: item.url,
        active_count: 1,
        spendTime: timeSpent,
        isApp: false,
      };
    });
    return results;
  } catch (error) {
    await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.error("Error fetching history items:", error);
  }
}

let activeTabId = null;
// let idleCount = 0;
// Listener for when a tab is activated
chrome.tabs.onActivated.addListener((activeInfo) => {
  activeTabId = activeInfo.tabId;
  // idleCount = 0;
  // console.log(`Tab Activated: ${activeTabId}`);
  try {
    chrome.tabs.sendMessage(
      activeTabId,
      { timeInterval: SSINTERVAL },
      (response) => {
        // console.log("Response from content.js:", response);
      }
    );
  } catch (e) {
    console.warn(e);
  }
});

// Listener for when a tab is updated
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  if (tabId === activeTabId && changeInfo.status === "complete") {
    // idleCount = 0;
    // console.log(`Tab Updated: ${activeTabId}`);
    try {
      chrome.tabs.sendMessage(
        activeTabId,
        { timeInterval: SSINTERVAL },
        (response) => {
          // console.log("Response from content.js:", response);
        }
      );
    } catch (e) {
      console.warn(e);
    }
  }
});

// Utility function to delay execution
function delay(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

// Function to wait for the tab to load
async function waitForTabToLoad(tabId, maxWait = 50000) {
  const interval = 500; // Check every 500ms
  const maxChecks = maxWait / interval;

  for (let i = 0; i < maxChecks; i++) {
    const tab = await new Promise((resolve, reject) => {
      chrome.tabs.get(tabId, (tab) => {
        if (chrome.runtime.lastError) {
          reject(
            `Error retrieving tab details: ${chrome.runtime.lastError.message}`
          );
        } else {
          resolve(tab);
        }
      });
    });

    if (tab.status === "complete") {
      return tab; // Tab is fully loaded
    }

    await delay(interval); // Wait before checking again
  }

  throw new Error("Tab did not finish loading within the timeout period.");
}

async function captureScreenshot(tabId) {
  try {
    // Ensure the tab is fully loaded
    const tab = await waitForTabToLoad(tabId);
    // console.log("Tab fully loaded:", tab);

    // Make sure the tab is active and focused
    await chrome.tabs.update(tabId, { active: true });

    // Capture the visible content of the tab's window
    const screenshotUrl = await new Promise((resolve, reject) => {
      chrome.tabs.captureVisibleTab(
        tab.windowId, // Capture the window where the tab resides
        { format: "png" },
        (screenshotUrl) => {
          if (chrome.runtime.lastError) {
            const errorMessage = `Error during captureVisibleTab: ${chrome.runtime.lastError.message}`;
            console.error(errorMessage);
            // Send the error message to content.js
            chrome.tabs.sendMessage(tabId, {
              type: "ERROR",
              message: errorMessage,
            });
            reject(errorMessage);
          } else if (screenshotUrl) {
            // console.log("Successfully captured screenshot.");
            resolve(screenshotUrl);
          } else {
            const errorMessage =
              "Screenshot capture failed: URL is null or undefined.";
            console.error(errorMessage);
            chrome.tabs.sendMessage(tabId, {
              type: "ERROR",
              message: errorMessage,
            });
            reject(errorMessage);
          }
        }
      );
    });

    return screenshotUrl; // Return the screenshot URL
  } catch (error) {
    console.error("Error in captureScreenshot:", error);

    // Send the error message to content.js
    chrome.tabs.sendMessage(tabId, { type: "ERROR", message: error.message });

    throw new Error(`captureScreenshot failed: ${error.message}`);
  }
}

const getBlurStatus = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("isSSBlur", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.isSSBlur || null); // Resolve with the data or null
      }
    });
  });
};

async function captureScreenshotAndSendToServer() {
  if (!activeTabId) {
    console.error("No active tab found. Cannot capture screenshot.");
    return null;
  }

  try {
    // console.log("Active tab:", activeTabId);
    let imageDataUrl = await captureScreenshot(activeTabId); // Capture clear screenshot
    console.log("Captured clear screenshot:", imageDataUrl);
    return imageDataUrl;
  } catch (error) {
    await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.error("Error in captureScreenshotAndBlur:", error);
    return null;
  }
}

let Intervals;
let imageURL = null;
let AppUrl = [];
let aws_link_id = null;
let imageArray = [];

function resetTracking() {
  imageURL = null;
  AppUrl = [];
  imageArray = [];
  aws_link_id = null;
  const newData = {
    keyboardEvents: [],
    mouseEvents: [],
    keyboardCount: 0,
    mouseMoveCount: 0,
    mouseClickCount: 0,
    keyboardActivityArray: new Array(INTERVAL).fill(false),
    mouseActivityArray: new Array(INTERVAL).fill(false),
  };
  chrome.storage.local.set({ globalActivityData: newData });
}

function finalInterval(time, flag) {
  if (flag == false) {
    Intervals = getInterval(time);
  } else {
    Intervals = getCurrentInterval(time);
  }
  chrome.storage.local.set({ currentInterval: Intervals });
}

async function getSSLinkById(id) {
  try {
    // Open the indexedDB database
    const idb = await new Promise((resolve, reject) => {
      const request = indexedDB.open("wstracker_new_db", 1);
      request.onsuccess = () => resolve(request.result);
      request.onerror = (err) =>
        reject(new Error("Error opening database: " + err));
    });

    // Open a readonly transaction and object store
    const tx = idb.transaction("AwsLink", "readonly");
    const store = tx.objectStore("AwsLink");

    const allRecords = await new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onsuccess = () => resolve(request.result);
      request.onerror = () => reject(request.error);
    });
    // console.log("All records in AwsLink:", allRecords);

    // Get the record with the specified id
    const result = await new Promise((resolve, reject) => {
      const getRequest = store.get(id);
      getRequest.onsuccess = () => {
        if (getRequest.result) {
          resolve(getRequest.result.AwsLink);
        } else {
          // Reject if the record is not found
          console.warn(`Record with ID ${id} not found.`);
          resolve(null);
        }
      };
      getRequest.onerror = (err) =>
        reject(new Error("Error fetching record: " + err));
    });

    return result;
  } catch (error) {
    await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.error("Error:", error.message);
    throw error;
  }
}

async function applyBlurInBackground(imageDataUrl) {
  return new Promise((resolve, reject) => {
    try {
      const img = new Image();
      img.onload = () => {
        const canvas = new OffscreenCanvas(img.width, img.height);
        const ctx = canvas.getContext("2d");

        ctx.filter = "blur(10px)"; // Apply blur effect
        ctx.drawImage(img, 0, 0);

        canvas
          .convertToBlob({ type: "image/png" })
          .then((blob) => {
            const reader = new FileReader();
            reader.onloadend = () => resolve(reader.result); // Return blurred image as data URL
            reader.onerror = (error) => reject(error);
            reader.readAsDataURL(blob);
          })
          .catch((err) => reject(err));
      };
      img.onerror = (err) => reject(err);
      img.src = imageDataUrl;
    } catch (error) {
      reject(error);
    }
  });
}

async function getBaseLink(id) {
  try {
    // Open the IndexedDB database
    const idb = await new Promise((resolve, reject) => {
      const request = indexedDB.open("wstracker_new_db", 1);
      request.onsuccess = () => resolve(request.result);
      request.onerror = () =>
        reject(new Error("Error opening database: " + request.error?.message));
    });

    // Open a read-only transaction and access the object store
    const tx = idb.transaction("SSLink", "readonly");
    const store = tx.objectStore("SSLink");

    // Fetch all records in the "SSLink" object store (if needed)
    const allRecords = await new Promise((resolve, reject) => {
      const request = store.getAll();
      request.onsuccess = () => resolve(request.result);
      request.onerror = () =>
        reject(
          new Error("Error fetching all records: " + request.error?.message)
        );
    });
    // console.log("All records in SSLink:", allRecords);

    // Fetch the record with the specified ID
    const result = await new Promise((resolve, reject) => {
      const getRequest = store.get(id);
      getRequest.onsuccess = async () => {
        if (getRequest.result) {
          // console.log("Record found:", getRequest.result);
          resolve(getRequest.result.SSLink);
        } else {
          console.warn(`Record with ID ${id} not found.`);
          resolve(null); // Resolve with null if the record is not found
        }
      };
      getRequest.onerror = () =>
        reject(
          new Error("Error fetching record: " + getRequest.error?.message)
        );
    });

    return result;
  } catch (error) {
    await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
    console.error("Error:", error.message);
    throw error;
  }
}

async function addDataWithCustomId(link, isBlur) {
  return new Promise((resolve, reject) => {
    try {
      let idb = indexedDB.open("wstracker_new_db", 1);

      idb.onupgradeneeded = () => {
        let db = idb.result;

        // Create object store if it doesn't exist
        if (!db.objectStoreNames.contains("SSLink")) {
          db.createObjectStore("SSLink", {
            keyPath: "id",
            autoIncrement: true,
          });
        }
      };

      idb.onsuccess = () => {
        let db = idb.result;
        let tx = db.transaction("SSLink", "readwrite");
        let store = tx.objectStore("SSLink");
        const data = {
          isBlur: isBlur, // Add the isBlur field
          SSLink: link, // Add the SSLink field
        };

        let request = store.add(data);

        request.onsuccess = () => {
          resolve(request.result); // Resolve with the auto-generated ID
        };

        request.onerror = () => {
          reject(request.error); // Reject on error
        };
      };

      idb.onerror = () => {
        reject(idb.error); // Handle database connection error
      };
    } catch (err) {
      reject(err); // Handle synchronous errors
    }
  });
}
// ---------------------------------------------------------
// Function to generate unique IDs
// Function to generate unique IDs
function generateId() {
  return Date.now(); // Simple unique ID based on timestamp
}

// Function to add a link to chrome.storage.local
async function addLink(link, isBlur = 0) {
  const result = await chrome.storage.local.get({ SSLink: [] });
  const links = result.SSLink;
  const newId = generateId();
  links.push({ id: newId, link, isBlur });

  await chrome.storage.local.set({ SSLink: links });
  // console.log("Link added successfully.");
  return newId;
}

// ----------------------------------------------------
function sendSSNotification() {
  chrome.notifications.create(
    "Screenshot Captured",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message: "Screenshot Taken",
    },
    function (res) {
      // console.log("Screenshot Taken!", res);
    }
  );
}

const getNotifyStatus = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("SSNotify", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.SSNotify || null); // Resolve with the data or null
      }
    });
  });
};

async function ScreenshotThread() {
  imageURL = await captureScreenshotAndSendToServer();
  console.log("Screenshot Captured:", imageURL);
  let NotifySS = await getNotifyStatus();
  if (NotifySS == 1) {
    sendSSNotification();
  }

  // console.log("-------IMAGE URLLLLLLLLLLLLLLLLLLLLL------------------");
  // console.log(getCurrentEndTime());
  // console.log(imageURL);

  let blurStatus = await getBlurStatus();
  aws_link_id = await addLink(imageURL, blurStatus);
  imageArray.push(aws_link_id);
  console.log(aws_link_id);
}

const isUserDel = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("userdel", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve(result.userdel || 0);
      }
    });
  });
};

const isTZCHANGE = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("tzchange", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        resolve(result.tzchange || 0);
      }
    });
  });
};

async function trackActivity(timeInterval) {
  const getGlobalData = async () => {
    return new Promise((resolve, reject) => {
      chrome.storage.local.get("globalActivityData", (result) => {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError); // Reject if there's an error
        } else {
          resolve(result.globalActivityData || null); // Resolve with the data or null
        }
      });
    });
  };
  const globalActivityData = await getGlobalData();

  const { activityLevel } = getActivityLevel(globalActivityData);

  // console.log("------------------INTERVALS----------------------");
  // console.log(Intervals.startTime, Intervals.endTime);
  // console.log(
  //   "SENDING ACTIVITY DATA TO SERVER *******************************************"
  // );

  AppUrl = await fetchURL(Intervals.startTime, timeInterval);
  // console.log("-------------URLL URLLL AGGYE------------");
  // console.log(AppUrl);
  delay(2000);
  await preparePayload(activityLevel, Intervals, AppUrl);
  await sendActivityDataToServer();
  resetTracking(); //Data resets for chrome
}

const getGlobalData = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("globalActivityData", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.globalActivityData || null); // Resolve with the data or null
      }
    });
  });
};

let intervalId;
let intervalId2;

const getPrevTime = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("prevTime", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.prevTime || null); // Resolve with the data or null
      }
    });
  });
};

const checkIdle = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("userIdle", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.userIdle || null); // Resolve with the data or null
      }
    });
  });
};

const getTimeDiff = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("timeDiff", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.timeDiff || null); // Resolve with the data or null
      }
    });
  });
};

const getSSInterval = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("SSInterval", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.SSInterval || null); // Resolve with the data or null
      }
    });
  });
};

// breakLimit
const getBreakLimit = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("breakLimit", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.breakLimit || null); // Resolve with the data or null
      }
    });
  });
};

// breakStatus


const getSSFrequency = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("SSFrequency", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.SSFrequency || null); // Resolve with the data or null
      }
    });
  });
};
// SSFrequency
function extractSeconds(dateTimeString) {
  // Split the string into date and time parts
  const timePart = dateTimeString.split(" ")[1];
  if (!timePart) {
    throw new Error(
      "Invalid format. Please provide a string in the format 'YYYY-MM-DD HH:MM:SS'."
    );
  }

  // Split the time part into hours, minutes, and seconds
  const [hours, minutes, seconds] = timePart.split(":").map(Number);

  // Calculate total seconds
  return hours * 3600 + minutes * 60 + seconds;
}

let timestate = false;
function formatDateTime(dateTimeStr) {
  let [date, time] = dateTimeStr.split(" ");
  let [year, month, day] = date.split("-").map((num) => num.padStart(2, "0"));
  let [hour, minute, second] = time
    .split(":")
    .map((num) => num.padStart(2, "0"));

  return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
}

async function checkIfUser() {
  const userData = await getUserData();
  const ipAddress = await globalIPAddress();

  const deviceType = getOsType();
  const osVersion = userData.osVersion;
  const deviceId = userData.deviceId;
  const authorizationToken = userData.sd_token;
  const sdToken = userData.sd_token;
  const orgId = userData.org_id;
  const userId = userData.user_id;
  const ProjectID = await getProjectID();
  const TaskID = await getTaskID();
  const url = "https://api.workstatus.io/api/v1/activity/log";

  let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  if (localTimezone === "Asia/Calcutta") {
    // console.log("Change Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }

  if (isInternetStatus()) {
    const payload = [
      {
        time_type: "1",
        os_type: "extension",
        browser_type: getBrowserName(),
        org_id: orgId,
        deviceType: deviceType,
        break_id: null,
        user_timezone_gmt: "GMT+05:30",
        stop: null,
        selfi_id: null,
        ip_address: ipAddress,
        projectId: ProjectID,
        source_type: "4",
        intervals: [],
        deviceId: deviceId,
        os_version: osVersion,
        selfiVerification: "true",
        start: activity_startTime.startTime,
        todo_id: TaskID,
        timezone: localTimezone,
        interval_time: INTERVAL / 60,
      },
    ];

    await addLog(
      "INFO - API: https://api.workstatus.io/api/v1/activity/log ::: PAYLOAD ::: " +
        JSON.stringify(payload),
      moment().format("YYYY-MM-DD HH:mm:ss")
    );
    fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${authorizationToken}`,
        SDToken: sdToken,
        OrgID: orgId,
        UserID: userId,
      },
      body: JSON.stringify(payload),
    })
      .then((response) => {
        if (!response.ok) {
          console.error(
            "Failed to submit data:",
            response.status,
            response.statusText
          );
          return response.text();
        }
        return response.json();
      })
      .then(async (data) => {
        if (
          data.response.code == 1001 ||
          data.response.isdeactivated == 1 ||
          data.response.isdeleted == 1 ||
          data.response.planStatus != "active"
        ) {
          // console.log("User is Deactivated");
          senddeleteNotification();
          clearInterval(intervalId);
          clearInterval(intervalId2);
          timeLogoutState = true;
          await addLog(
            "INFO - User is Deactivated/Deleted or Org is Expired/Deleted. Logging out---->",
            moment().format("YYYY-MM-DD HH:mm:ss")
          );
          MakeLogout();
          chrome.storage.local.set({ userdel: 1 });
          chrome.storage.local.set({ time_changed: 1 });
        } else if (data) {
          // console.log("Success:", data);
        }
      })
      .catch(async (error) => {
        await addLog(
          "Error - : API: https://api.workstatus.io/api/v1/activity/log :::: Checking if User active" +
            error,
          moment().format("YYYY-MM-DD HH:mm:ss")
        );
        console.error("Error during fetch:", error);
      });
  }
}

function getTimeIntervalsISTWhenStop(
  startTime,
  endTime,
  intervalSeconds = 300
) {
  // Convert strings to Date objects
  const start =
    startTime instanceof Date ? startTime : new Date(`${startTime} GMT+0530`);
  const end =
    endTime instanceof Date ? endTime : new Date(`${endTime} GMT+0530`);

  if (start > end) {
    throw new Error("Start time must be earlier than end time.");
  }

  const intervals = [];
  let current = new Date(start);

  // Get the next nearest 5-minute mark
  const nextFiveMinuteMark = new Date(
    Math.ceil(current.getTime() / (intervalSeconds * 1000)) *
      (intervalSeconds * 1000)
  );

  // If start time is not exactly on a 5-minute mark, create an initial partial interval
  if (current < nextFiveMinuteMark && nextFiveMinuteMark <= end) {
    intervals.push({
      start: new Date(current),
      end: new Date(nextFiveMinuteMark),
    });
    current = nextFiveMinuteMark;
  }

  // Generate fixed 5-minute intervals
  while (current < end) {
    const next = new Date(current.getTime() + intervalSeconds * 1000);
    intervals.push({
      start: new Date(current),
      end: next > end ? new Date(end) : new Date(next),
    });
    current = next;
  }

  return intervals;
}

function sendStartNotification() {
  chrome.notifications.create(
    "Timer Started",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message:
        "Your timer has started successfully. Stay focused and productive!",
    },
    function (res) {
      // console.log("Timer start notification displayed!", res);
    }
  );
}

function sendStopNotification() {
  chrome.notifications.create(
    "Timer Stopped",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message:
        "Your timer has stopped. Take a break or start again when ready!",
    },
    function (res) {
      // console.log("Timer stop notification displayed!", res);
    }
  );
}

async function handleSleepCase(prevvTime, afterTime) {
  // console.log("---->>>>>>TIME CONFLICTS", prevvTime, afterTime);
  prevvTime = formatDateTime(prevvTime);
  afterTime = formatDateTime(afterTime);

  let userdel = await isUserDel();
  let usertz = await isTZCHANGE();
  // console.log(userdel);
  // console.log(usertz);

  let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  if (localTimezone === "Asia/Calcutta") {
    // console.log("Change Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }

  if (prevvTime != afterTime && usertz == 0) {
    const userData = await getUserData();
    const ipAddress = await globalIPAddress();

    // Retrieve the visited URLs from chrome storage

    const deviceType = getOsType();
    const osVersion = userData.osVersion;
    const deviceId = userData.deviceId;
    const lat = userData.lat;
    const lng = userData.lng;

    let empty_interval = [];
    const emptyIntervals = getTimeIntervalsIST(prevvTime, afterTime, INTERVAL);
    if (emptyIntervals) {
      emptyIntervals.forEach((interval) => {
        let start = convertISTToCustomFormat(interval.start);
        let end = convertISTToCustomFormat(interval.end);
        empty_interval.push({
          screenUrl: [],
          deviceId: deviceId,
          to: end, // Use the end time of the current interval
          deviceType: deviceType,
          ip_address: ipAddress,
          break_id: null,
          activityLevel: {
            keyboard: 0,
            mouse: 0,
            average: 0,
          },
          os_version: osVersion,
          os_type: "extension",
          browser_type: getBrowserName(),
          from: start, // Use the start time of the current interval
          appAndUrls: [],
          interval_time_db: INTERVAL / 60,
          note: null,
          location: {
            long: lng,
            lat: lat,
            ipAddress: ipAddress,
          },
          timezone: localTimezone,
        });
      });
      // console.log(empty_interval);
      // await setPayloadIntervals(emptyIntervals);
      // console.log(emptyIntervals);

      let idleLength = await getIdleIntervalsCount();
      if (idleLength >= 1) {
        // console.log("----HA ISME AAYA DATA AAAYA---");
        for (const obj of empty_interval) {
          // await setIdleIntervals(obj);
          await storeIdleActivityIntervals(obj.from, obj.to, obj);
        }
        idleLength = await getIdleIntervalsCount();
        startIdleTimer(idleLength, INTERVAL);
      } else {
        for (const obj of empty_interval) {
          // await setPayloadIntervals(obj);
          await storeActivityIntervals(obj.from, obj.to, obj);
        }
      }
    }
  }
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  // Handle async operations
  (async () => {
    try {
      if (request.action === "triggerFunction") {
        // -----------------------------------------------------------------------------------------------CHECK TIMEZONE ON START
        sendStartNotification();
        const userData = await getUserData();
        const sdToken = userData.sd_token;
        const orgId = userData.org_id;

        if (isInternetStatus()) {
          let stopApp = await suggestMeAName(userData.timezone, sdToken, orgId);
          // console.log(stopApp);
          if (stopApp == false) {
            if (intervalId) {
              clearInterval(intervalId);
            }
            if (intervalId2) {
              clearInterval(intervalId2);
            }
            sendTimeZoneNotification();
            // chrome.storage.local.set({ time_changed: 1 });
            // chrome.storage.local.set({ tzchange: 1 });
            timeLogoutState = true;
            await addLog(
              "INFO - User Timezone Changed.Logging Out---->",
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
            MakeLogout();
          }
        }

        // ----------------------------------------------------------------------------------------------------------------
        timestate = true;
        timeLogoutState = false;
        chrome.storage.local.set({ userIdle: "false" });
        chrome.storage.local.set({ HeartBeat: 1 });

        // SSINTERVAL = SSFreq;

        activity_startTime = getCurrentInterval(INTERVAL);
        chrome.storage.local.set({ activityStartTime: activity_startTime });

        // Perform async operations if needed
        resetTracking();

        // SSINTERVAL = 60;
        // INTERVAL = 60;

        let timeInterval = parseInt(await getSSInterval());
        SSINTERVAL = timeInterval * 60;
        SSFreq = await getSSFrequency();
        SSFreq = SSFreq == null ? 0 : SSFreq;
        INTERVAL = SSINTERVAL;
        finalInterval(INTERVAL, true);

        async function updatedIntervals() {
          clearInterval(intervalId);
          clearInterval(intervalId2);
          await updateScreenshotInterval();
          timeInterval = parseInt(await getSSInterval());
          SSINTERVAL = timeInterval * 60;
          SSFreq = await getSSFrequency();
          SSFreq = SSFreq == null ? 0 : SSFreq;
          INTERVAL = SSINTERVAL;
          // console.log(SSINTERVAL);
          // console.log(INTERVAL);
          // console.log(SSFreq);
          try {
            chrome.tabs.sendMessage(
              activeTabId,
              { timeInterval: SSINTERVAL },
              (response) => {
                // console.log("Response from content.js:", response);
              }
            );
          } catch (e) {
            console.warn(e);
          }
          await startAllIntervals(INTERVAL, SSFreq);
        }

        async function startAllIntervals(time_interval, SSFreq) {
          if (SSFreq != 0) {
            intervalId2 = setInterval(async () => {
              // console.log("SCREENSHOT THREAD RUNS");
              await ScreenshotThread(); // Ensure this is asynchronous if needed
            }, (time_interval / SSFreq) * 1000);
          }

          intervalId = setInterval(async () => {
            await trackActivity(timeInterval);
            if (timeLogoutState == false) {
              let prevvTime = Intervals.endTime;
              await updatedIntervals();
              finalInterval(INTERVAL, false);
              let afterTime = Intervals.startTime;
              handleSleepCase(prevvTime, afterTime);
            }
          }, time_interval * 1000);
        }
        await startAllIntervals(INTERVAL, SSFreq);

        sendResponse({ message: "Function triggered successfully!" });
      } else if (request.action === "stopInterval") {
        debugger;
        console.log("------------> YES IT ENTERS");
        chrome.storage.local.set({ HeartBeat: 0 });
        // Clear the interval using the stored ID
        sendStopNotification();
        timestate = false;

        if (intervalId2) {
          clearInterval(intervalId2);
          intervalId2 = null;
        }
        if (intervalId) {
          clearInterval(intervalId);
          intervalId = null; // Clear the ID after stopping
          // console.log("************Interval stopped.**************************");

          // Perform async operations if needed

          const globalActivityData = await getGlobalData();
          const idleStatus = await checkIdle();
          // const abc = await gethhi();
          const prevTime = await getPrevTime();
          const timediff = await getTimeDiff();
          const { activityLevel } = getActivityLevel(globalActivityData);

          let lastTimee = getCurrentEndTime();
          let startTimee = Intervals.startTime;

          // console.log(prevTime);
          // // console.log();
          // console.log(idleStatus);
          // console.log(timediff);

          if (idleStatus == "true") {
            lastTimee = convertISTToCustomFormat(prevTime);
            chrome.storage.local.set({ userIdle: "false" });
          }

          // console.log(lastTimee);
          let a = extractSeconds(startTimee);
          let b = extractSeconds(lastTimee);

          if (a > b) {
            let temp = startTimee;
            startTimee = lastTimee;
            lastTimee = temp;
          }

          startTimee = formatDateTime(startTimee);
          lastTimee = formatDateTime(lastTimee);

          // let intervalArray=getTimeIntervalsISTWhenStop(startTimee,lastTimee,INTERVAL)
          // intervalArray.forEach(async (interval) => {
          //   let start = convertISTToCustomFormat(interval.start);
          //   let end = convertISTToCustomFormat(interval.end);
          //   let minIntervals = { startTime: start, endTime: end };
          //   await preparePayload(activityLevel, minIntervals, AppUrl);
          // })

          // const promises = intervalArray.map(async (interval) => {
          //   let start = convertISTToCustomFormat(interval.start);
          //   let end = convertISTToCustomFormat(interval.end);

          // });

          let checkVal = await checkKrna();

          if (checkVal != 1) {
            let minIntervals = { startTime: startTimee, endTime: lastTimee };
            await preparePayload(activityLevel, minIntervals, AppUrl);
          }
          await sendActivityDataToServer();
          console.log("----------> Step 1 completed");
          await deleteAllSyncTimerData();
          // await deleteCurrentTimerData();
          await syncTimerData();
          console.log("----------> Step 2 completed");
          // Send message to timer.js to call setTotalTime()
          chrome.runtime.sendMessage({ action: "setTotalTime" }, (response) => {
            if (chrome.runtime.lastError) {
              console.log(
                "Could not send message to timer.js:",
                chrome.runtime.lastError.message
              );
            }
          });

          sendResponse({ message: "Interval stopped successfully!" });
        } else {
          sendResponse({ message: "No active interval to stop." });
        }
      } else if (request.action === "break") {
        const { isStartOrStop, breakId } = request;
        try {
          console.log(
            `Starting break action: ${isStartOrStop} for breakId: ${breakId}`
          );
          await sendBreakDataToServer(isStartOrStop, breakId);
          chrome.storage.local.set({ breakStatusForStop: isStartOrStop });
          console.log(`Break action completed: ${isStartOrStop}`);
          sendResponse({
            message: "Break action executed",
            status: isStartOrStop,
            breakId,
          });
        } catch (e) {
          console.error("Error handling break action:", e);
          sendResponse({
            message: "Break action failed",
            error: e?.message || String(e),
          });
        }
      }
    } catch (error) {
      console.error("Error in message listener:", error);
      sendResponse({ message: "An error occurred.", error: error.message });
    }
  })();

  // Return true immediately to keep the message channel open for async operations
  return true;
});

// For Sync Button
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === "executeFunction") {
    // console.log("Triggering the function from background.js");

    // Make the function awaitable by wrapping it in a Promise
    (async () => {
      try {
        await sendActivityDataToServer();
        sendResponse({ status: "Function executed successfully" });
      } catch (error) {
        console.error("Error executing the function:", error);
        sendResponse({
          status: "Function execution failed",
          error: error.message,
        });
      }
    })();

    // Return true to indicate the response will be sent asynchronously
    return true;
  }
});

const getProjectID = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("ProjectID", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.ProjectID || null); // Resolve with the data or null
      }
    });
  });
};

const getPayloadIntervals = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("payloadsIntervals", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.payloadsIntervals || []); // Resolve with the data or null
      }
    });
  });
};

async function getIdleIntervalsCount() {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });

  const transaction = db.transaction("idleIntervals", "readonly");
  const objectStore = transaction.objectStore("idleIntervals");

  const countRequest = objectStore.count();

  const count = await new Promise((resolve, reject) => {
    countRequest.onsuccess = function () {
      resolve(countRequest.result);
    };

    countRequest.onerror = function (event) {
      reject("Error counting entries: " + event.target.error);
    };
  });

  // console.log("Total Idle Intervals Count:", count);
  return count;
}

const getIdleIntervals = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("idleIntervals", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.idleIntervals || []); // Resolve with the data or null
      }
    });
  });
};

const setPayloadIntervals = async (intervalObj) => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("payloadsIntervals", (result) => {
      if (chrome.runtime.lastError) {
        return reject(chrome.runtime.lastError); // Reject if there's an error
      }

      let temp = result.payloadsIntervals || [];
      temp.push(intervalObj);

      chrome.storage.local.set({ payloadsIntervals: temp }, () => {
        if (chrome.runtime.lastError) {
          return reject(chrome.runtime.lastError);
        }

        // console.log("Updated Activity payload", temp);
        resolve(temp); // Resolve after `set` completes
      });
    });
  });
};
const setIdleIntervals = async (intervalObj) => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("idleIntervals", (result) => {
      if (chrome.runtime.lastError) {
        return reject(chrome.runtime.lastError); // Reject on error
      }

      let temp = result.idleIntervals || [];
      temp.push(intervalObj);

      chrome.storage.local.set({ idleIntervals: temp }, () => {
        if (chrome.runtime.lastError) {
          return reject(chrome.runtime.lastError);
        }

        // console.log("Updated Idle payload", temp);
        resolve(temp); // Resolve after `set` completes
      });
    });
  });
};

const getTaskID = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("TaskID", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.TaskID || null); // Resolve with the data or null
      }
    });
  });
};

const getLastIntervalEnd = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("LastIntervalEnd", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.LastIntervalEnd || null); // Resolve with the data or null
      }
    });
  });
};

const getCheckedValue = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("isChecked", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.isChecked || 0); // Resolve with the data or null
      }
    });
  });
};

const getUserData = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("userDetailChrome", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.userDetailChrome || null); // Resolve with the data or null
      }
    });
  });
};

const globalIPAddress = async () => {
  try {
    const response = await fetch("https://api.ipify.org?format=json");
    const data = await response.json();
    return data.ip; // Return the fetched IP address
  } catch (error) {
    console.error("Error fetching IP address:", error);
    return null;
  }
};

const getAwsLink = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("awsIMG", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.awsIMG || null); // Resolve with the data or null
      }
    });
  });
};

const getOsType = () => {
  const userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.includes("cros")) return "Linux";
  if (userAgent.includes("win")) return "Windows";
  if (userAgent.includes("mac")) return "Mac";
  if (userAgent.includes("linux")) return "Linux";
  if (userAgent.includes("android")) return "Android";
  if (userAgent.includes("iphone") || userAgent.includes("ipad")) return "iOS";
  return "Linux";
};
// Use async/await to fetch and log the data

//   -----------screenshot

function isInternetStatus() {
  if (navigator.onLine) {
    return true;
  } else {
    return false;
  }
}

function getTimeIntervalsIST(startTime, endTime, intervalSeconds = 10) {
  // Check if startTime and endTime are Date objects; otherwise, convert strings to Date
  const start =
    startTime instanceof Date ? startTime : new Date(`${startTime} GMT+0530`);
  const end =
    endTime instanceof Date ? endTime : new Date(`${endTime} GMT+0530`);

  // Ensure start is before end
  if (start > end) {
    throw new Error("Start time must be earlier than end time.");
  }

  const intervals = [];
  let current = new Date(start);

  while (current < end) {
    const next = new Date(current.getTime() + intervalSeconds * 1000);
    intervals.push({
      start: new Date(current),
      end: next > end ? new Date(end) : new Date(next),
    });
    current = next;
  }

  return intervals;
}

// Helper function to format Date in IST as "YYYY-MM-DD HH:mm:ss"
function formatIST(date) {
  let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  if (localTimezone === "Asia/Calcutta") {
    // console.log("Change Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }
  const options = {
    timeZone: localTimezone,
    year: "numeric",
    month: "2-digit",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
    second: "2-digit",
    hour12: false,
  };

  return new Intl.DateTimeFormat("en-GB", options)
    .format(date)
    .replace(",", "")
    .replace(" ", "T")
    .replace("T", " ")
    .replace("/", "-")
    .replace("/", "-");
}

async function fetchSingleEntry(key) {
  try {
    // Get the 'aws' data from storage
    const result = await getStorage("aws");

    if (result.aws) {
      const awsData = result.aws;

      // Find the entry with the given key
      const entry = awsData.find((obj) => obj.hasOwnProperty(key));

      if (entry) {
        const link = entry[key]; // Get the value associated with the key
        // console.log("Found link:", link);
        return link;
      } else {
        // console.log("Entry not found with key:", key);
        return null;
      }
    } else {
      // console.log("No 'aws' data found");
      return null;
    }
  } catch (error) {
    console.error("Error fetching entry:", error);
  }
}

// Delete a single entry from chrome.storage.local by key
async function deleteSingleEntry(key) {
  try {
    // Get the 'aws' data from storage
    const result = await getStorage("aws");

    if (result.aws) {
      let awsData = result.aws;

      // Filter out the entry with the given key
      awsData = awsData.filter((obj) => !obj.hasOwnProperty(key));

      // Save the updated array back to chrome.storage.local
      await setStorage({ aws: awsData });
      // console.log("Entry deleted with key:", key);
    } else {
      // console.log("No 'aws' data found to delete from");
    }
  } catch (error) {
    console.error("Error deleting entry:", error);
  }
}

// async function processIntervals(intervals) {
//   const updatedIntervals = await Promise.all(
//     intervals.map(async (interval) => {
//       const id = interval.screenUrl[0]; // Assuming screenUrl is an array with one element
//       console.log("-------id----------------------------");
//       console.log(id);
//       let processedValue = await getSSLinkById(id);
//       if (!processedValue) {
//         processedValue = await fetchSingleEntry(id);
//       }
//       await deleteSingleEntry(id);
//       return {
//         ...interval,
//         screenUrl: [processedValue], // Replace the id with the processed value
//       };
//     })
//   );
//   return updatedIntervals;
// }

async function fetchAwsLinkByIdAndDelete(id) {
  const result = await chrome.storage.local.get({ awsLink: [] });
  const awsLinks = result.awsLink;
  const index = awsLinks.findIndex((item) => item.id === id);

  if (index !== -1) {
    const awsLinkObject = awsLinks.splice(index, 1)[0]; // Remove the object and get it
    await chrome.storage.local.set({ awsLink: awsLinks });
    // console.log("AWS Link fetched and deleted successfully:", awsLinkObject);
    return awsLinkObject;
  } else {
    console.warn("ID not found in awsLink.");
    return -1; // Indicate failure
  }
}
// async function processIntervals(intervals) {
//   const updatedIntervals = await Promise.all(
//     intervals.map(async (interval) => {
//       let processedScreenUrls = await Promise.all(
//         interval.screenUrl.map(async (id) => {
//           console.log("-------id----------------------------");
//           console.log(id);
//           // let processedValue = await getSSLinkById(id);
//           // if (!processedValue) {
//           //   await delay(4000);
//           //   // processedValue = await fetchSingleEntry(id);
//           //   processedValue = await getBaseLink(id);
//           // }
//           // await deleteSingleEntry(id);
//           let processedValue = await fetchAwsLinkByIdAndDelete(id);
//           if (processedValue == null) {
//           }
//           console.log(processedValue);
//           return processedValue.link.Location; // Replace the id with the processed value
//         })
//       );
//       processedScreenUrls =
//         processedScreenUrls.length == 0 ? [] : processedScreenUrls;
//       return {
//         ...interval,
//         screenUrl: processedScreenUrls, // Replace the screenUrl array with processed values
//       };
//     })
//   );
//   return updatedIntervals;
// }

// async function processIntervals(intervals) {
//   const updatedIntervals = await Promise.all(
//     intervals.map(async (interval) => {
//       let processedScreenUrls = await Promise.all(
//         interval.screenUrl.map(async (id) => {
//           console.log("-------id----------------------------");
//           console.log(id);

//           let processedValue = -1; // Initialize processedValue
//           while (processedValue === -1) {
//             processedValue = await fetchAwsLinkByIdAndDelete(id); // Try fetching the result
//             if (processedValue === -1) {
//               console.log(`Retrying for id ${id}...`);
//               await delay(5000); // Wait for 5 seconds before retrying
//             }
//           }

//           if (!processedValue || !processedValue.link) {
//             console.log(`No valid result for id ${id}`);
//             return null;
//           }

//           console.log(processedValue);
//           return processedValue.link.Location; // Replace the id with the processed value
//         })
//       );

//       processedScreenUrls =
//         processedScreenUrls.length === 0 ? [] : processedScreenUrls;

//       return {
//         ...interval,
//         screenUrl: processedScreenUrls, // Replace the screenUrl array with processed values
//       };
//     })
//   );
//   return updatedIntervals;
// }

async function processIntervals(intervals) {
  const maxRetries = 12; // Maximum retry attempts
  const retryDelay = 5000; // 5 seconds delay between retries

  const updatedIntervals = await Promise.all(
    intervals.map(async (interval) => {
      const processedScreenUrls = await Promise.all(
        interval.screenUrl.map(async (id) => {
          // console.log(`Processing ID: ${id}`);

          let retries = 0;
          let processedValue = -1; // Assume ID is not found initially

          while (retries < maxRetries) {
            processedValue = await fetchAwsLinkByIdAndDelete(id);

            if (processedValue !== -1) {
              // If a valid value is found, break the loop
              break;
            }

            retries++;
            // console.log(`Retry ${retries}/${maxRetries} for ID: ${id}`);

            if (retries < maxRetries) {
              await new Promise((resolve) => setTimeout(resolve, retryDelay)); // Wait before retrying
            }
          }

          if (processedValue === -1) {
            console.warn(`ID not found: ${id} after ${maxRetries} retries`);
            return null; // Return null if ID is never found
          }

          if (!processedValue || !processedValue.link?.Location) {
            return null;
          }

          // console.log(`Success for ID: ${id}:`, processedValue.link.Location);
          return processedValue.link.Location; // Return the link if found
        })
      );

      let finalScreenUrls = processedScreenUrls.filter(Boolean);
      let freqDiff = Math.abs(SSFreq - finalScreenUrls.length);
      // console.log(finalScreenUrls.length);
      // console.log(freqDiff);
      if (freqDiff > 0 && finalScreenUrls.length > 0) {
        while (freqDiff != 0) {
          finalScreenUrls.push(finalScreenUrls[finalScreenUrls.length - 1]);
          freqDiff--;
        }
      }

      return {
        ...interval,
        screenUrl: finalScreenUrls, // Remove null values
      };
    })
  );

  return updatedIntervals;
}

let idleTimrerID;

function startIdleTimer(idleLength, INTERVAL) {
  sendIdleNotification();
  chrome.storage.local.set({ idlepopup: 1 });
  let start = (idleLength * INTERVAL) / 60;
  chrome.storage.local.set({ IdleTimeCount: start });

  if (idleTimrerID) {
    clearInterval(idleTimrerID);
    idleTimrerID = null;
  }
  idleTimrerID = setInterval(() => {
    start++;
    chrome.storage.local.set({ IdleTimeCount: start });
  }, 60000);
}

const getPopupStatus = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("idlepopup", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.idlepopup || 0); // Resolve with the data or null
      }
    });
  });
};

const getActivityStartTime = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("activityStartTime", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.activityStartTime || new Date().toISOString()); // Resolve with the data or null
      }
    });
  });
};

async function mergeIntervals() {
  try {
    const result = await new Promise((resolve) => {
      chrome.storage.local.get(["idleIntervals", "payloadsIntervals"], resolve);
    });

    let idleIntervals = result.idleIntervals || [];
    let payloadsIntervals = result.payloadsIntervals || [];

    // Merge idleIntervals into payloadsIntervals
    let mergedIntervals = [...payloadsIntervals, ...idleIntervals];

    // Update storage with merged result and clear idleIntervals
    await new Promise((resolve) => {
      chrome.storage.local.set(
        {
          payloadsIntervals: mergedIntervals,
          idleIntervals: [],
        },
        resolve
      );
    });

    // console.log("Merged Intervals", mergedIntervals);
  } catch (error) {
    console.error("Error merging intervals:", error);
  }
}

async function storeActivityIntervals(startTime, endTime, objectData) {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onupgradeneeded = function (event) {
      const db = event.target.result;
      if (!db.objectStoreNames.contains("activityIntervals")) {
        const objectStore = db.createObjectStore("activityIntervals", {
          keyPath: "id",
          autoIncrement: true,
        });
        objectStore.createIndex("startTime", "startTime", { unique: false });
        objectStore.createIndex("endTime", "endTime", { unique: false });
      }
    };

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });
  const transaction = db.transaction("activityIntervals", "readwrite");
  const objectStore = transaction.objectStore("activityIntervals");

  const data = {
    startTime: startTime,
    endTime: endTime,
    data: objectData,
  };

  await new Promise((resolve, reject) => {
    const addRequest = objectStore.add(data);

    addRequest.onsuccess = function () {
      // console.log("Data stored successfully!");
      resolve();
    };

    addRequest.onerror = function (event) {
      reject("Error storing data: " + event.target.error);
    };
  });
}

async function storeIdleActivityIntervals(startTime, endTime, objectData) {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onupgradeneeded = function (event) {
      const db = event.target.result;
      if (!db.objectStoreNames.contains("idleIntervals")) {
        const objectStore = db.createObjectStore("idleIntervals", {
          keyPath: "id",
          autoIncrement: true,
        });
        objectStore.createIndex("startTime", "startTime", { unique: false });
        objectStore.createIndex("endTime", "endTime", { unique: false });
      }
    };

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });
  const transaction = db.transaction("idleIntervals", "readwrite");
  const objectStore = transaction.objectStore("idleIntervals");

  const data = {
    startTime: startTime,
    endTime: endTime,
    data: objectData,
  };

  await new Promise((resolve, reject) => {
    const addRequest = objectStore.add(data);

    addRequest.onsuccess = function () {
      // console.log("Data stored successfully!");
      resolve();
    };

    addRequest.onerror = function (event) {
      reject("Error storing data: " + event.target.error);
    };
  });
}

async function transferAllIdleToActivityIntervals() {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });

  const transaction = db.transaction(
    ["idleIntervals", "activityIntervals"],
    "readwrite"
  );
  const idleStore = transaction.objectStore("idleIntervals");
  const activityStore = transaction.objectStore("activityIntervals");

  // Get all data from idleIntervals
  const idleData = await new Promise((resolve, reject) => {
    const getAllRequest = idleStore.getAll();

    getAllRequest.onsuccess = function () {
      resolve(getAllRequest.result);
    };

    getAllRequest.onerror = function (event) {
      reject("Error retrieving idleIntervals: " + event.target.error);
    };
  });

  // Loop through each entry and move to activityIntervals
  for (const data of idleData) {
    const newData = {
      startTime: data.startTime,
      endTime: data.endTime,
      data: data.data,
    };

    // Add data to activityIntervals
    await new Promise((resolve, reject) => {
      const addRequest = activityStore.add(newData);

      addRequest.onsuccess = function () {
        // console.log("Transferred data:", newData);
        resolve();
      };

      addRequest.onerror = function (event) {
        reject("Error transferring data: " + event.target.error);
      };
    });
  }

  // Clear all data from idleIntervals
  await new Promise((resolve, reject) => {
    const clearRequest = idleStore.clear();

    clearRequest.onsuccess = function () {
      // console.log("All data cleared from idleIntervals.");
      resolve();
    };

    clearRequest.onerror = function (event) {
      reject("Error clearing idleIntervals: " + event.target.error);
    };
  });

  // console.log(
  //   "All idleIntervals data transferred to activityIntervals and cleared successfully."
  // );
}

async function preparePayload(activityLevel, Intervals, AppUrl) {
  // await checkIfUser();
  await delay(2000);

  // console.log(AppUrl);
  const userData = await getUserData();
  const ipAddress = await globalIPAddress();

  // Retrieve the visited URLs from chrome storage

  const deviceType = getOsType();
  const osVersion = userData.osVersion;
  const deviceId = userData.deviceId;
  const lat = userData.lat;
  const lng = userData.lng;
  const UsertimeZone = userData.timezone;
  const sdToken = userData.sd_token;
  const orgId = userData.org_id; // Replace with actual Org ID

  let stopApp = true;
  if (isInternetStatus()) {
    stopApp = await suggestMeAName(userData.timezone, sdToken, orgId);
    // console.log(stopApp);
    if (stopApp == false) {
      clearInterval(intervalId);
      clearInterval(intervalId2);
      sendTimeZoneNotification();
      // await sendActivityDataToServer()
      // chrome.storage.local.set({ time_changed: 1 });
      // chrome.storage.local.set({ tzchange: 1 });
      timeLogoutState = true;
      await addLog(
        "INFO - User Timezone Changed. Logging out---->",
        moment().format("YYYY-MM-DD HH:mm:ss")
      );
      MakeLogout();
    }
  }
  // Storing Intervals End Time.....

  if (stopApp == true) {
    const intervalObj = {
      screenUrl: imageArray,
      deviceId: deviceId,
      to: Intervals.endTime,
      deviceType: deviceType,
      ip_address: ipAddress,
      break_id: null,
      activityLevel: {
        keyboard: activityLevel.keyboard,
        mouse: activityLevel.mouse,
        average: activityLevel.average,
      },
      os_version: osVersion,
      os_type: "extension",
      browser_type: getBrowserName(),
      from: Intervals.startTime,
      appAndUrls: AppUrl,
      interval_time_db: INTERVAL / 60,
      note: null,
      location: {
        long: lng,
        lat: lat,
        ipAddress: ipAddress,
      },
      timezone: UsertimeZone,
    };
    // let isUserIdle = await getPopupStatus();
    // console.log("-----------------INTERVAL OBJECT---------------");
    // console.log("Interval Object:", JSON.stringify(intervalObj));

    // let idleIntervalsArray = await getIdleIntervals();

    let idleLength = await getIdleIntervalsCount();
    let idleThreshold = (INTERVAL / 60) * 2;
    // console.log(idleLength);
    if (
      (activityLevel.average == 0 && activityLevel.mouseMoveCount == 0) ||
      (idleLength * INTERVAL) / 60 >= idleThreshold
    ) {
      // await setIdleIntervals(intervalObj);
      await storeIdleActivityIntervals(
        Intervals.startTime,
        Intervals.endTime,
        intervalObj
      );
    } else {
      // await mergeIntervals();
      await transferAllIdleToActivityIntervals();
      // await setPayloadIntervals(intervalObj);
      await storeActivityIntervals(
        Intervals.startTime,
        Intervals.endTime,
        intervalObj
      );

      if (idleTimrerID) {
        clearInterval(idleTimrerID);
        idleTimrerID = null;
      }
    }

    // idleIntervalsArray = await getIdleIntervals();
    idleLength = await getIdleIntervalsCount();

    // console.log(idleThreshold);
    // console.log(idleLength);
    if ((idleLength * INTERVAL) / 60 >= idleThreshold) {
      startIdleTimer(idleLength, INTERVAL);
    }
  }
  resetTracking();
}

function senddeleteNotification() {
  chrome.notifications.create(
    "System-Idle",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message: "Plan inactive/User Deleted/User Deactivated",
    },
    function (res) {
      // console.log("Plan inactive case pop", res);
    }
  );
}

async function updateActivityPayload(temp) {
  return new Promise((resolve, reject) => {
    chrome.storage.local.set({ payloadsIntervals: temp }, () => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
      } else {
        // console.log("Updated Activitypayload After Sent", temp);
        resolve();
      }
    });
  });
}

async function checkUserTimeZone(localTimezone, sdToken, orgId) {
  // console.log(localTimezone, sdToken, orgId);
  const url = "https://api.workstatus.io/api/v2/time/convert";
  const headers = {
    Authorization: `Bearer ${sdToken}`,
    "Content-Type": "application/json",
    OrgID: orgId,
  };

  if (localTimezone === "Asia/Calcutta") {
    console.warn("Changing Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }

  const body = JSON.stringify({
    dst: false,
    timezone: localTimezone,
  });
  await addLog(
    "INFO - API: https://api.workstatus.io/api/v2/time/convert ::: PAYLOAD ::: " +
      body,
    moment().format("YYYY-MM-DD HH:mm:ss")
  );

  try {
    const response = await fetch(url, {
      method: "POST",
      headers,
      body,
    });

    const apiResponse = await response.json();
    // console.log("Full API Response:", apiResponse); // Log entire response for debugging

    if (!response.ok) {
      console.error(`API Error: ${response.status}`, apiResponse);
      if (apiResponse.code === 1001) {
        console.warn("Invalid SD Token or Org ID");
      }
      return true;
    }

    // Try different ways of accessing the datetime value
    const apiDatetimeStr =
      apiResponse?.response?.data || // Current assumption
      apiResponse?.data || // If response.data is returned directly
      apiResponse?.timestamp; // If there's a timestamp field

    if (!apiDatetimeStr) {
      console.warn("Invalid API response format: Missing datetime data");
      return true;
    }

    const apiDatetime = new Date(apiDatetimeStr);
    if (isNaN(apiDatetime.getTime())) {
      console.warn("Invalid datetime received from API");
      return true;
    }

    const serverDatetimeSeconds = Math.floor(apiDatetime.getTime() / 1000);
    const currentDatetimeSeconds = Math.floor(Date.now() / 1000);
    const timeDifference = Math.abs(
      currentDatetimeSeconds - serverDatetimeSeconds
    );

    return timeDifference <= 70;
    // return true;
  } catch (error) {
    await addLog(
      "ERROR - API: https://api.workstatus.io/api/v2/time/convert ::: " +
        error.message,
      moment().format("YYYY-MM-DD HH:mm:ss")
    );
    console.warn("An error occurred:", error.message);
    // return null;
    return true;
  }
}

function sendTimeZoneNotification() {
  chrome.notifications.create(
    "TimeZone Changed",
    {
      type: "basic",
      iconUrl: "images/32.png",
      title: "WorkStatus",
      message: "User Timezone Changed",
    },
    function (res) {
      // console.log("User Timezone Changed");
    }
  );
}

async function suggestMeAName(user_timezone, sd_token, orgId) {
  let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  if (localTimezone === "Asia/Calcutta") {
    // console.log("Change Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }

  const isTimezoneMatched = await checkUserTimeZone(
    localTimezone,
    sd_token,
    orgId
  );
  // console.log(isTimezoneMatched);
  if (!isTimezoneMatched || localTimezone !== user_timezone) {
    // console.log(
    // "False Timezone---------------- False Timezone --------------------- False Timezone"
    // );
    return false;
  }
  return true;
}

async function getFirst100ActivityData() {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });

  const transaction = db.transaction("activityIntervals", "readonly");
  const objectStore = transaction.objectStore("activityIntervals");

  const dataArray = await new Promise((resolve, reject) => {
    const dataObjects = [];
    const request = objectStore.openCursor();

    request.onsuccess = function (event) {
      const cursor = event.target.result;
      if (cursor) {
        if (cursor.value.data !== null && cursor.value.data !== undefined) {
          dataObjects.push(cursor.value.data); // Only push valid data
        }
        if (dataObjects.length < 100) {
          cursor.continue();
        } else {
          resolve(dataObjects);
        }
      } else {
        resolve(dataObjects);
      }
    };

    request.onerror = function (event) {
      reject("Error retrieving data: " + event.target.error);
    };
  });

  return dataArray;
}

async function deleteFirstNActivityData(n) {
  const db = await new Promise((resolve, reject) => {
    const request = indexedDB.open("wstracker_new_db", 1);

    request.onsuccess = function (event) {
      resolve(event.target.result);
    };

    request.onerror = function (event) {
      reject("Error opening IndexedDB: " + event.target.error);
    };
  });

  const transaction = db.transaction("activityIntervals", "readwrite");
  const objectStore = transaction.objectStore("activityIntervals");

  await new Promise((resolve, reject) => {
    const keysToDelete = [];

    const cursorRequest = objectStore.openCursor();

    cursorRequest.onsuccess = function (event) {
      const cursor = event.target.result;
      if (cursor && keysToDelete.length < n) {
        keysToDelete.push(cursor.key); // Store the key for deletion
        cursor.continue();
      } else {
        // Start deleting the collected keys
        const deletePromises = keysToDelete.map((key) => {
          return new Promise((resolveDelete, rejectDelete) => {
            const deleteRequest = objectStore.delete(key);

            deleteRequest.onsuccess = function () {
              resolveDelete();
            };

            deleteRequest.onerror = function (event) {
              rejectDelete("Error deleting data: " + event.target.error);
            };
          });
        });

        Promise.all(deletePromises)
          .then(() => {
            // console.log(
            //   "Deleted " + keysToDelete.length + " entries successfully."
            // );
            resolve();
          })
          .catch(reject);
      }
    };

    cursorRequest.onerror = function (event) {
      reject("Error retrieving data: " + event.target.error);
    };
  });
}





async function sendActivityDataToServer() {
  // console.log("Sending Data To Server-------");

  const activityStartTime = await getActivityStartTime();

  const userData = await getUserData();
  const ipAddress = await globalIPAddress();
  const deviceType = getOsType();
  const osVersion = userData.osVersion;
  const deviceId = userData.deviceId;
  const authorizationToken = userData.sd_token;
  const sdToken = userData.sd_token;
  const orgId = userData.org_id;
  const userId = userData.user_id;
  const ProjectID = await getProjectID();
  const TaskID = await getTaskID();
  const url = "https://api.workstatus.io/api/v1/activity/log";

  if (timestate == false) {
    await mergeIntervals();
    await transferAllIdleToActivityIntervals();
  }

  let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
  if (localTimezone === "Asia/Calcutta") {
    // console.log("Change Timezone to Asia/Kolkata from Asia/Calcutta");
    localTimezone = "Asia/Kolkata";
  }

  if (isInternetStatus()) {
    try {
      chrome.tabs.sendMessage(
        activeTabId,
        { message: "awsTrigger" },
        (response) => {
          // console.log("Response from content.js:", response);
        }
      );
    } catch (e) {
      console.warn(e);
    }

    let intervalsToSend = await getFirst100ActivityData();
    // console.log(intervalsToSend);

    const processedIntervals = await processIntervals(intervalsToSend);
    let dataLength = intervalsToSend.length;

    const payload = [
      {
        time_type: "1",
        browser_type: getBrowserName(),
        os_type: "extension",
        org_id: orgId,
        deviceType: deviceType,
        break_id: null,
        user_timezone_gmt: "GMT+05:30",
        stop: null,
        selfi_id: null,
        ip_address: ipAddress,
        projectId: ProjectID,
        source_type: "4",
        intervals: processedIntervals,
        deviceId: deviceId,
        os_version: osVersion,
        selfiVerification: "true",
        start: activityStartTime.startTime,
        todo_id: TaskID,
        timezone: localTimezone,
        interval_time: INTERVAL / 60,
      },
    ];

    console.log("Final Payload", payload);
    await addLog(
      "INFO - API: https://api.workstatus.io/api/v1/activity/log ::: PAYLOAD " +
        payload,
      moment().format("YYYY-MM-DD HH:mm:ss")
    );

    try {
      const response = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${authorizationToken}`,
          SDToken: sdToken,
          OrgID: orgId,
          UserID: userId,
        },
        body: JSON.stringify(payload),
      });

      if (!response.ok) {
        console.error(
          "Failed to submit data:",
          response.status,
          response.statusText
        );
        const errorText = await response.text();
        console.error("Error message:", errorText);
        await addLog(
          "Error - Failed to submit data: " + errorText,
          moment().format("YYYY-MM-DD HH:mm:ss")
        );
        return;
      }
      const data = await response.json();
      if (data) {
        if (
          data.response.code == 1001 ||
          data.response.isdeactivated == 1 ||
          data.response.isdeleted == 1 ||
          data.response.planStatus != "active"
        ) {
          // console.log("User is Deactivated");
          senddeleteNotification();
          clearInterval(intervalId);
          clearInterval(intervalId2);
          timeLogoutState = true;
          await addLog(
            "INFO - User is Deactivated/Deleted or Org is Expired/Deleted. Logging out---->",
            moment().format("YYYY-MM-DD HH:mm:ss")
          );
          MakeLogout();
          chrome.storage.local.set({ userdel: 1 });
          chrome.storage.local.set({ time_changed: 1 });
        } else {
          // console.log("Success:", data);
          await addLog(
            "INFO - API: https://api.workstatus.io/api/v1/activity/log " + data,
            moment().format("YYYY-MM-DD HH:mm:ss")
          );
          await deleteFirstNActivityData(dataLength);
          let last_synced = moment().format("YYYY-MM-DD HH:mm:ss");
          await chrome.storage.local.set({ last_synced });
          let breakStartTime = moment().format("YYYY-MM-DD HH:mm:ss");
          chrome.storage.local.set({ breakStartTime });
        }
      }
    } catch (error) {
      await addLog("Error -" + error, moment().format("YYYY-MM-DD HH:mm:ss"));
      console.error("Error during fetch:", error);
    }
  }
}

const getBreakStartTime = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("breakStartTime", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.breakStartTime || null); // Resolve with the data or null
      }
    });
  });
};

const isBreakTimeExceeded = async () => {
  return new Promise((resolve, reject) => {
    chrome.storage.local.get("isBreakTimeExceeded2", (result) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError); // Reject if there's an error
      } else {
        resolve(result.isBreakTimeExceeded2 || null); // Resolve with the data or null
      }
    });
  });
};
let breakIntervalId;

async function startBreakInterval() {
  let breakLimit = parseInt(await getBreakLimit());
  console.log(breakLimit);
  console.log(breakLimit * 60 * 1000);
  breakIntervalId = setTimeout(async () => {
    chrome.storage.local.set({ isBreakTimeExceeded: true });
    console.log("isRinging");
  }, breakLimit * 60 * 1000);
}

async function stopBreakInterval() {
  clearTimeout(breakIntervalId);
  chrome.storage.local.set({ isBreakTimeExceeded: false });
}

//  chrome.storage.local.set({ isBreakTimeExceeded: true });
async function sendBreakDataToServer(isStartOrStop, breakId) {
  try {
    const userData = await getUserData();
    console.log(userData);
    if (!userData) throw new Error("User data not found");

    const ipAddress = await globalIPAddress();
    const deviceType = getOsType();
    const osVersion = userData.osVersion;
    const deviceId = userData.deviceId;
    const authorizationToken = userData.sd_token;
    const sdToken = userData.sd_token;
    const orgId = userData.org_id;
    const userId = userData.id;
    const ProjectID = await getProjectID();
    const TaskID = await getTaskID();
    const url = "https://api.workstatus.io/api/v1/timesheet/add/break";

    console.log("----------->", userId);
    console.log("orgId:", orgId, "type:", typeof orgId);
    console.log("userId:", userId, "type:", typeof userId);

    if (!orgId || orgId === null || orgId === undefined || orgId === "") {
      throw new Error("Organization ID is missing or invalid");
    }

    if (!userId || userId === null || userId === undefined || userId === "") {
      throw new Error("User ID is missing or invalid");
    }

    const lat = userData.lat;
    const lng = userData.lng;

    let breakStartTime = null;
    let breakEndTime = null;

    if (isStartOrStop === "start") {
      let val = await isBreakTimeExceeded();
      if (val == true) {
        // Send message to timer.js when break time is exceeded
        chrome.runtime.sendMessage(
          { action: "breakTimeExceeded" },
          (response) => {
            if (chrome.runtime.lastError) {
              console.log(
                "Could not send breakTimeExceeded message to timer.js:",
                chrome.runtime.lastError
              );
            } else {
              console.log(
                "Break time exceeded message sent to timer.js successfully"
              );
            }
          }
        );
      }
      chrome.storage.local.set({ isIdle: true });
      startBreakInterval();
      return;
    } else {
      breakStartTime = await getBreakStartTime();
      breakEndTime = moment().format("YYYY-MM-DD HH:mm:ss");
      chrome.storage.local.set({ isStoppedFromBreak: true });
      stopBreakInterval();
    }

    let date1 = breakStartTime.split(" ")[0];
    let date2 = breakEndTime.split(" ")[0];

    if (date1 != date2) {
      if (isInternetStatus()) {
        const payload = {
          date: date1.split(" ")[0],
          deviceId: deviceId,
          deviceType: deviceType,
          from: breakStartTime,
          ip_address: ipAddress,
          member_id: parseInt(userId),
          organization_id: parseInt(orgId),
          project_id: parseInt(ProjectID) || 0,
          source_type: 3,
          time_type: 4,
          to: date1.split(" ")[0] + " 23:59:00",
          break_id: parseInt(breakId),
          todo_id: TaskID ? String(TaskID) : "",
        };

        console.log("Final Payload", payload);
        await addLog(
          "INFO - API: https://api.workstatus.io/api/v1/timesheet/add/break ::: PAYLOAD " +
            JSON.stringify(payload),
          moment().format("YYYY-MM-DD HH:mm:ss")
        );

        try {
          const headers = {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authorizationToken}`,
            SDToken: sdToken,
            OrgID: String(orgId),
            UserID: String(userId),
            Accept: "application/json",
            deviceType: "Web App",
            "User-Agent":
              "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
          };

          console.log("Headers being sent:", headers);
          console.log(
            "OrgID value:",
            String(orgId),
            "type:",
            typeof String(orgId)
          );

          const response = await fetch(url, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload),
          });

          if (!response.ok) {
            const errorText = await response.text();
            console.error("Failed to submit data:", response.status, errorText);
            await addLog(
              "Error - Failed to submit data: " + errorText,
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
            return;
          }

          const data = await response.json();
          if (data) {
            console.log("Success:", data);
            await addLog(
              "INFO - API: https://api.workstatus.io/api/v1/add/break " +
                JSON.stringify(data),
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
          }
          const records = data.response.data;
          const lastItem = records[records.length - 1];
          const breakExceeded = lastItem?.break_exceeded;
          if (breakExceeded === 1) {
            console.log("Break exceeded in the last record!");
            chrome.storage.local.set({ isBreakTimeExceeded2: true });
          }
          await delay(2000);

          const payload2 = {
            date: date2.split(" ")[0],
            deviceId: deviceId,
            deviceType: deviceType,
            from: date2.split(" ")[0] + " 00:00:00",
            ip_address: ipAddress,
            member_id: parseInt(userId),
            organization_id: parseInt(orgId),
            project_id: parseInt(ProjectID) || 0,
            source_type: 3,
            time_type: 4,
            to: breakEndTime,
            break_id: parseInt(breakId),
            todo_id: TaskID ? String(TaskID) : "",
          };

          console.log("Final Payload", payload2);
          await addLog(
            "INFO - API: https://api.workstatus.io/api/v1/timesheet/add/break ::: PAYLOAD " +
              JSON.stringify(payload2),
            moment().format("YYYY-MM-DD HH:mm:ss")
          );

          const response2 = await fetch(url, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload2),
          });

          if (!response2.ok) {
            const errorText = await response2.text();
            console.error(
              "Failed to submit data:",
              response2.status,
              errorText
            );
            await addLog(
              "Error - Failed to submit data: " + errorText,
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
            return;
          }

          const data2 = await response2.json();
          if (data2) {
            console.log("Success:", data2);
            await addLog(
              "INFO - API: https://api.workstatus.io/api/v1/add/break " +
                JSON.stringify(data2),
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
          }
          const records2 = data2.response.data;
          const lastItem2 = records2[records2.length - 1];
          const breakExceeded2 = lastItem2?.break_exceeded;
          if (breakExceeded2 === 1) {
            console.log("Break exceeded in the last record!");
            chrome.storage.local.set({ isBreakTimeExceeded2: true });
          }
        } catch (error) {
          await addLog(
            "Error -" + error,
            moment().format("YYYY-MM-DD HH:mm:ss")
          );
          console.error("Error during fetch:", error);
          throw error;
        }
      }
    } else {
      const date = moment().format("YYYY-MM-DD");
      let localTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
      if (localTimezone === "Asia/Calcutta") {
        localTimezone = "Asia/Kolkata";
      }

      if (isInternetStatus()) {
        const payload = {
          date: date,
          deviceId: deviceId,
          deviceType: deviceType,
          from: breakStartTime,
          ip_address: ipAddress,
          member_id: parseInt(userId),
          organization_id: parseInt(orgId),
          project_id: parseInt(ProjectID) || 0,
          source_type: 3,
          time_type: 4,
          to: breakEndTime,
          break_id: parseInt(breakId),
          todo_id: TaskID ? String(TaskID) : "",
        };

        console.log("Final Payload", payload);
        await addLog(
          "INFO - API: https://api.workstatus.io/api/v1/timesheet/add/break ::: PAYLOAD " +
            JSON.stringify(payload),
          moment().format("YYYY-MM-DD HH:mm:ss")
        );

        try {
          const headers = {
            "Content-Type": "application/json",
            Authorization: `Bearer ${authorizationToken}`,
            SDToken: sdToken,
            OrgID: String(orgId),
            UserID: String(userId),
            Accept: "application/json",
            deviceType: "Web App",
            "User-Agent":
              "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
          };

          console.log("Headers being sent:", headers);
          console.log(
            "OrgID value:",
            String(orgId),
            "type:",
            typeof String(orgId)
          );

          const response = await fetch(url, {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload),
          });

          if (!response.ok) {
            const errorText = await response.text();
            console.error("Failed to submit data:", response.status, errorText);
            await addLog(
              "Error - Failed to submit data: " + errorText,
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
            return;
          }

          const data = await response.json();
          if (data) {
            console.log("Success:", data);
            await addLog(
              "INFO - API: https://api.workstatus.io/api/v1/add/break " +
                JSON.stringify(data),
              moment().format("YYYY-MM-DD HH:mm:ss")
            );
          }
          const records = data.response.data;
          const lastItem = records[records.length - 1];
          const breakExceeded = lastItem?.break_exceeded;
          if (breakExceeded === 1) {
            console.log("Break exceeded in the last record!");
            chrome.storage.local.set({ isBreakTimeExceeded2: true });
          }
        } catch (error) {
          await addLog(
            "Error -" + error,
            moment().format("YYYY-MM-DD HH:mm:ss")
          );
          console.error("Error during fetch:", error);
          throw error;
        }
      } else {
        console.log("No internet connection, skipping break data submission");
      }
    }
  } catch (error) {
    console.error("Error in sendBreakDataToServer:", error);
    await addLog(
      "Error in sendBreakDataToServer: " + error.message,
      moment().format("YYYY-MM-DD HH:mm:ss")
    );
    throw error;
  }
}
