console.log('BACKGROUND STARTED');

var running = false;


// Function to get data from chrome.storage
function getDataFromStorage(key) {
    return new Promise((resolve, reject) => {
        chrome.storage.local.get(key, (result) => {
            if (chrome.runtime.lastError) {
                reject(chrome.runtime.lastError);
            } else {
                resolve(result);
            }
        });
    });
}


function stopRunning() {
    running = false;
    chrome.runtime.sendMessage({message: "stop"});
}

function startRunning() {
    running = true;
	 chrome.runtime.sendMessage({message: "start"});
}

function updateRunning(msg) {
	chrome.runtime.sendMessage({message: "start", state: msg});
}

async function initializeXHAM() {
   const randomString = Math.random().toString(36).substring(2, 18);
	const url = "https://xhamsterlive.com/api/front/v3/config/initial?timezoneOffset=-120&timezone=Africa%2FJohannesburg&skipTimezoneAutoSaving=true&requestPath=%2Fearnings%2Fpaying-users&updateTag=0&disableClient=0&uniq="+randomString;
   return fetch(url);
}

async function fetchUserData(userID) {
  const randomString2 = Math.random().toString(36).substring(2, 18);
  const userurl = "https://xhamsterlive.com/api/front/v2/users/"+userID+"?uniq="+randomString2;
  return fetch(userurl);
}

// Function to fetch data from the API
async function requestTippersFriends() {

    startRunning();
    updateRunning("starting...");
    var initdata;
    try {
       updateRunning("getting initialization data...")
       const initresponse = await initializeXHAM()
       if (!initresponse.ok) {
            throw new Error(`HTTP error! status: ${initresponse.status}`);
       }
       initdata = await initresponse.json();
    } catch (error) {
       stopRunning();
       console.log('INITDATA RETRIVIAL FAILED', error);
    }


    updateRunning("getting  tipping users...");
    const randomString = Math.random().toString(36).substring(2, 18);
    const url = 'https://xhamsterlive.com/api/front/users/21483393/transactions/users?isOnline=&offset=0&limit=1000&username=&period=0&sort=lastPaid&order=desc&uniq='+randomString;

    try {
        const response = await fetch(url);
        
        // Check if the response is ok (status in the range 200-299)
        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        console.log(data.users);  // Log the result
 
        updateRunning("get storage saved user list");
        var friendedUsers = { 0: {id: 0, username:'fakeused', 'isDeleted': true}};
        try {
           const result = await getDataFromStorage('XhamsterLiveFriended');
           console.log('Retrieved object:', result.XhamsterLiveFriended);
           if(result.XhamsterLiveFriended) friendedUsers = result.XhamsterLiveFriended;
        } catch (error) {
           console.log('No object found, created:', friendedUsers);
        }

        console.log('FrienderUsers:', friendedUsers);

        updateRunning("remove already known users");
        const usersToFetch = [];
        const existingUserIds = new Set(Object.values(friendedUsers).map(user => user.id));
        Object.entries(data.users).forEach(([userKey, user]) => {
            if ( user.isDeleted == false ) {
               if (!existingUserIds.has(user.id)) {
            	   console.log(`NEW USER: Key: ${userKey}, User ID: ${user.id}, Username: ${user.username}`);
                  usersToFetch.push(user.id);
               }
            }
        });

       console.log("users to Fetch", usersToFetch, usersToFetch.length);
       if(usersToFetch.length < 1) {
          stopRunning();
			 return;       
	    }

       const reqdata = { csrfToken: initdata.initial.client.csrfToken, 
                         csrfTimestamp: initdata.initial.client.csrfTimestamp,
                         csrfNotifyTimestamp: initdata.initial.client.csrfNotifyTimestamp,
                         userIds: usersToFetch,
                         uniq: randomString }

        try {
           updateRunning("check which users we can friend");
           const prefres = await fetch("https://xhamsterlive.com/api/front/models/21483393/preferences", {
                                          method: 'POST', // Specify the request method
                                          headers: {
                                             'Content-Type': 'application/json' // Set the content type to JSON
                                          },
                                          body: JSON.stringify(reqdata) // Convert the request payload to a JSON string
                                       });
            if (!prefres.ok) {
               throw new Error(`HTTP error! status: ${prefres.status}`);
            }
            const prefdata = await prefres.json()
            console.log('prefdata', prefdata);
				Object.entries(prefdata.canFriend).forEach(([userid, canFriend]) => {
					if ( canFriend == false ) {
                  usersToFetch.pop(userid);
                  friendedUsers[userid] = data.users[userid];
               }
            });
            console.log('userToFriend:', usersToFetch);
            const rdata = {
					csrfToken: initdata.initial.client.csrfToken,
               csrfTimestamp: initdata.initial.client.csrfTimestamp,
               csrfNotifyTimestamp: initdata.initial.client.csrfNotifyTimestamp,
               uniq: randomString 
            }
            var index=1;
            updateRunning("sending friends requests: "+index+"/"+usersToFetch.length);


            // Rate limiting variables
            const maxConcurrentRequests = 1;
            const maxRequestsPerInterval = 1;
            const intervalDuration = 2000; // milliseconds
            let currentRequests = 0;
            let requestCount = 0;

            // Function to handle the fetching with rate limiting
            const fetchWithRateLimit = async (userId) => {
                while (currentRequests >= maxConcurrentRequests) {
                    await new Promise(resolve => setTimeout(resolve, intervalDuration)); // Wait until a slot is free
                }

                currentRequests++;
                
                try {
                    const uri = "https://xhamsterlive.com/api/front/users/"+initdata.initial.client.user.id+"/friends/"+userId;
                    console.log("sending friend request:", index+"/"+usersToFetch.length,  uri, "with data", rdata);
                    const freq = await fetch(uri, {
                                               method: "PUT",
                                               headers: {
                                                   'Content-Type': 'application/json' // Set the content type to JSON
                                               },
                                               body: JSON.stringify(rdata)
                                            });
 
                    if (!freq.ok) {
                       if(freq.status != "400") throw new Error(`HTTP error! status: ${freq.status}`);
                    }
                    if(freq.ok || freq.status=="400") friendedUsers[userId] = data.users[userId];
                    const udata = await freq.json();
                    console.log('friend requested for user:', '('+index+"/"+usersToFetch.length+")", udata);
                    index=index+1;
                    updateRunning("sending friends requests: "+index+"/"+usersToFetch.length);

                } finally {
                    currentRequests--;
                    requestCount++;

                    // Reset the request count after the interval duration
                    if (requestCount >= maxRequestsPerInterval) {
                        await new Promise(resolve => setTimeout(resolve, intervalDuration));
                        requestCount = 0;
                    }
               }
            };

            // Process users in batches
            const promises = usersToFetch.map(userId => fetchWithRateLimit(userId));
            await Promise.all(promises);

               
            updateRunning("saving processed users");
            console.log("FriendedUsers to store", friendedUsers);
				chrome.storage.local.set({"XhamsterLiveFriended": friendedUsers});

         } catch (error) {
            stopRunning();
            console.log('PREFENCE DATA RETRIVIAL FAILED', error);
         }

				


    } catch (error) {
        stopRunning();
        console.error('Error fetching data:', error);
    }
}



chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  if (request.message === "isrunning") {
     sendResponse({isrunning: running});
  }
  if (request.message === "toggle") {
    if (request.state === "run") {
      console.log('RUN!!');
       
       sendResponse({farewell: "Run!"});
		 chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
		     chrome.tabs.sendMessage(tabs[0].id, { message: "run" }, (response) => {
		          console.log(response); // Log the response from the content script
		     });
		  });
      requestTippersFriends();
      stopRunning();
    }
  }
});

