var total_balance = null;
var memory_cache = {};
var user_settings = [];
var SetIntervalIsLoggedINFallback;
var SetIntervalIsExecINFallback;
var ServiceWorkerMessagesWorking = 0;
var AutoSuncFUnctionStarted = 0;
var request = new RequestData(false);
var requestWHash = new RequestData(true);
var LoadDataPageFunc;
var InttoStrDetailsFuncs = {};
var Preloaders = {};
var ReusableUIElements = {};
var cacmemocachehe = {};
var currentNoOfPrecacheRequests = [];
var CurrentPageisLoading = false;
var ShoppingCart = false;
var DontInitialize = 0;
var PreloaderGetFileBlob_Operations = 0;
var PreloaderGetFileBlob_Intervals = [];
var devmode = true;
var currentData = null;
var DataCore = {
  'Store': {},
  'Product': {},
  'User': {},
};
const FormSchemas = {};

var PageCounterTracker=0;

initGlobal('tabledata');
initGlobal('Buttons',[]);
initGlobal('defaultbackpage');

var defaultBackOnclick = null;


if (typeof DontInitialize === 'undefined') {
  var DontInitialize = 0;
}

function logDev(...args) {
  if (devmode) {
    console.log(...args);
  }
}

/* 
const { fetch: originalFetch } = window;

window.fetch = async (...args) => {
    let [resource, config] = args;
  
if (resource.startsWith("/RequestData/File/")){
  console.log(reqcacheload(resource));
}
    
    const response = await originalFetch(resource, config);
    console.table('Response received:', response);
    return response;
}; */

InitDataPageFuncOBJ();




Preloaders.getfileBlobURL = function (hashkey, fetchifdoesnotexist = true) {
  if (hashkey.length > 72) {
    hashkey = hashkey.slice(-72);
  }
  const targeturl = '/RequestData/File/' + hashkey;
  const alturl = window.location.origin + targeturl;
  const reqload1 = reqcacheload(targeturl);
  const reqload2 = reqcacheload(alturl);


  const PreloadFileBlob = async function () {
    await Preloaders.QuickPrecacheFetch(targeturl, null, false, () => {
      PreloaderGetFileBlob_Operations--;
    }, 'GET').then(() => {

    });
  }
  PreloaderGetFileBlob_Operations++;
  const currentfetchOperation = PreloaderGetFileBlob_Operations;

  if (!hashkey) { return false; }
  if (typeof fileBlobURLList[hashkey] !== 'undefined') {
    return fileBlobURLList[hashkey];
  } else if (reqload1) {
    fileBlobURLList[hashkey] = URL.createObjectURL(reqcacheload(targeturl));
    return fileBlobURLList[hashkey];
  } else {
    PreloadFileBlob();
    return false;
  }
}

Preloaders.QuickPrecacheFetch = async function (url, obj = null, fromVarCache = false, successfunc = false, reqtype = 'POST') {
  return new Promise((resolve, reject) => {
    if (!url) {
      return reject(new Error("URL is required"));
    }

    request.url(url).success((response) => {
      if (typeof successfunc === 'function') {
        successfunc(response);
      }

      if (url.includes('/RequestData/File/') && response) {
        const fhash = url.slice(-72);
        const bloburl = URL.createObjectURL(response);
        fileBlobURLList[fhash] = bloburl;
      }
      resolve(response);
    }).data(obj).fromVarCache(fromVarCache).type(reqtype).go();
  });
};

Preloaders.ListData = async function (url, fromVarCache = false, successfunc = false, reqtype = 'POST', datatosend = null) {
  if (!url) { return false; }
  request.url(url).success((response) => { if (successfunc) { successfunc(response); } }).data(datatosend).fromVarCache(fromVarCache).type(reqtype).go();
};
Preloaders.ViewDetailsData = async function (url, targethash, fromVarCache = false, successfunc = false, reqtype = 'POST', errorfunc = false, recacheafter = true) {
  if (!url || !targethash) { return false; }
  let successfuncrun = 0;
  request.url(url).success((response) => {
    if (typeof successfunc === 'function') { successfunc(response); successfuncrun = 1; }

  }).error((response) => { if (typeof errorfunc === 'function') { errorfunc(response); } }).data({ target: targethash }).fromVarCache(fromVarCache).type(reqtype).go();

  if (recacheafter) {
    request.url(url).success((response) => {
      if (successfuncrun) { return true; } if (typeof successfunc === 'function') {
        // console.log(recacheafter);
        successfunc(response);
      }
    }).error((response) => { if (typeof errorfunc === 'function') { errorfunc(response); } }).data({ target: targethash }).fromVarCache(false).type(reqtype).go();
  }


};

Preloaders.Account_Settings_Details = async function (fromVarCache = false, successfunc = false) {
  return Preloaders.ListData('/account_settings/details', fromVarCache, successfunc, 'GET');
};


URLList.Datalist = {};


Preloaders.Datalist = {};

// Preloaders.PrecachePage = async function (url, targetidchange = '') {

//   request.url(url).type('GET').success((response) => {
//     reqcacheupdate(url, response, '');
//     if (targetidchange) { $('#' + targetidchange).html(response); CurrentPageisLoading = false; }
//     // $('#' + targetidchange).fadeIn();
//   }).go();
// };

Preloaders.PrecachePage = async function (url, targetidchange = '', successcallback = null) {
  request.url(url).type('GET').success((response) => {
    reqcacheupdate(url, response, '');

    if (targetidchange) {
      $('#' + targetidchange).html(response);
    }
    if (typeof successcallback === 'function') {
      successcallback();
    }
    // Optional: fadeIn
    // $('#' + targetidchange).fadeIn();
  }).go();
};

Preloaders.PreloadStaticPages = async function () {
  Preloaders.PrecachePage(URLList.Pages.homepage);
  Preloaders.PrecachePage(URLList.Pages.account_settings);
};

Preloaders.PrecacheStaticAssets = async function () {
  let arr = PrecacheStaticURLs;
  for (let i = 0; i < arr.length; i++) {
    Preloaders.PrecachePage(arr[i].url);
  }
};

Preloaders.ImageList = async function (targethash, phototype) {
  Preloaders.ListData('/Request/Photos/' + phototype, true, false, 'POST', { target: targethash });
};



Preloaders.Account_Settings_Details();


function CheckAndSetDarkMode() {
  if (user_settings && user_settings.darkmode) {
    UISetDarkMode();
  }
}

function PageAutoRunScript() {
  CheckAndSetDarkMode();
}


function LoginPollingFallback() {
  SetIntervalIsLoggedINFallback = setInterval(function () {
    $.get("/get/isloggedin", function (response) {
      MessageLogin(response);
    }).fail(function () { });
  }, 10000);
}


function ExecPollingFallback() {
  SetIntervalIsExecINFallback = setInterval(function () {
    $.get("/get/isExec", function (response) {
      MessageExec(response);
    }).fail(function () { });

  }, 10000);
}

function AutoSyncFunctions() {
  console.log('polling fallback');
  AutoSuncFUnctionStarted = 1;
  LoginPollingFallback();
  ExecPollingFallback();
}


function checkIfHostIsOnline() {
  const host = window.location.origin; // This includes the protocol and hostname (and port if applicable)

  return fetch(host, { method: 'HEAD', mode: 'no-cors' })
    .then(() => true)
    .catch(() => false);
}

let MessagePassingConfirmationLog = 0;

function ProcessMessage(datatype, data, callback) {
  // console.log('process message ',datatype, ' ',data);
  if (datatype != data.type) { return false; }
  if (!callback) { return false; }
  callback(data.data);
}

function ProcessMessagesfromServiceWorker(event) {
  if (!MessagePassingConfirmationLog) { console.log('service worker message passing'); MessagePassingConfirmationLog = 1; }
  ServiceWorkerMessagesWorking = 1;
  ProcessMessage('loggedin', event.data, MessageLogin);
  ProcessMessage('exec', event.data, MessageExec);
}
async function registerServiceWorker() {

  if ('serviceWorker' in navigator) {
    const registrations = await navigator.serviceWorker.getRegistrations();

    if (registrations.length > 0) {
      console.log('Service Worker is already registered.');
      return;
    }


    window.addEventListener('DOMContentLoaded', () => {

      const isLocalhost = ['localhost', '127.0.0.1', '::1'].includes(location.hostname);

      if (!window.isSecureContext && !isLocalhost) {
        console.info('Skipping service worker registration: insecure context', location.href);
        AutoSyncFunctions();

      } else {



        navigator.serviceWorker.register('/service-worker.js', { scope: '/' })
          .then(registration => {
            logDev('Service Worker registered Now ');
            //  console.log('Service Worker registered Now:', registration);


            if (navigator.serviceWorker.controller) {
              navigator.serviceWorker.controller.postMessage({
                type: 'INIT'
              });
            } else {
              console.log('NO navigator.serviceWorker.controller ');
              AutoSyncFunctions();
            }

            navigator.serviceWorker.ready.then((registration) => {
              if (registration.active) {
                registration.active.postMessage({
                  type: 'INIT'
                });
                navigator.serviceWorker.addEventListener('message', event => {
                  ProcessMessagesfromServiceWorker(event);
                });
              } else {

                logDev('No active service worker');

                AutoSyncFunctions();
              }
            });



          })
          .catch(error => {
            logDev('Service Worker registration Error ');

            console.log('service worker registration error ', error);
            AutoSyncFunctions();
          });


      }

    });
  }
}

async function ensureServiceWorkerReady() {
  if ('serviceWorker' in navigator) {
    await navigator.serviceWorker.ready;

    logDev('Service Worker is Ready');

  } else {
    AutoSyncFunctions();
    logDev('Service Workers are not supported in this browser');

  }
}


if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistrations().then(registrations => {
    for (let registration of registrations) {
      registration.unregister();
    }

  });
} else {
  console.warn('Service workers are not supported in this browser.');
};


/*
const originalFetch = window.fetch;
window.fetch = window.fetch = async (...args) => {

  console.log('Fetch request:', args);
 const isSTATICURL =  inPrecacheStaticURLs(args[0]);
if (isSTATICURL &&  reqcacheload(args[0])){
  //return reqcacheload(args[0]);
}

  const response = await originalFetch(...args);
  //if (isSTATICURL){reqcacheupdate(args[0],response.body);}
  console.log('Fetch response body:', response.body);

  const response = await originalFetch(...args);
  return response;
};
*/

async function InitPeriodicSync() {
  await ensureServiceWorkerReady();

  if ('periodicSync' in navigator) {
    navigator.serviceWorker.ready.then((registration) => {
      return registration.periodicSync.register('sync-dynamic-content', {
        minInterval: 15 * 60 * 1000
      });
    }).catch((error) => {
      console.error('Periodic Sync registration failed:', error);
    });
  }


}


function InitializeWebWorkerSync() {


  SyncWorker = new Worker('/webworker-sync.js');

  SyncWorker.onmessage = function (event) {
    ProcessMessage('loggedin', event.data, MessageLogin);
    ProcessMessage('exec', event.data, MessageExec);
    ProcessMessage('reqcacheupdate', event.data, MessageReqCacheUpdate);
    ProcessMessage('cachehashupdate', event.data, MessageHashCacheUpdate);
    ProcessMessage('BlobfromOPFS', event.data, MessageOPFStoBlobreqcache);

  };

  SyncWorker.onerror = function (error) {
    AutoSyncFunctions();
    console.log('worker error ', error);
  };
}

function FetchFileBlobfromOPFS(filehashkey, successfunc = false, error = false) {
  if (!filehashkey) { return false; }
  SyncWorker.postMessage({ type: 'FileblobOPFS', hash: filehashkey, 'success': successfunc, 'error': false });
}

function GetFileBlobfromOPFSHash(filehashkey) {
  if (!filehashkey) { return false; }
  SyncWorker.postMessage({ type: 'GetBlobOPFSfromHash', hash: filehashkey });
}


async function initializeApp() {

  RunFunctiononMutation('main-body', () => {
    InitializationFinished = true;
  });

  if (window.location.pathname === '/') {
    $('#SplashLogo').fadeOut(500);
    gotoPage('Home', 0);
  }



  InitializeWebWorkerSync();
  registerServiceWorker();
  ensureServiceWorkerReady();
  InitPeriodicSync();
  ShowNotes();
  InitializeUserSettings();


  var currenttarget = 0;





}

$(document).ready(function () {
  console.log('document ready');
  if (!DontInitialize) {
    initializeApp();
    logDev('Initializing Service Workers');
  } else {
    logDev('Did Not Initialize Service Workers');
    RunFunctiononMutation('main-body', () => {
      InitializationFinished = true;
    });
  }


});


function showNotification(title) {
  Notification.requestPermission(function (result) {
    if (result === 'granted') {
      navigator.serviceWorker.ready.then(function (registration) {
        var showNotification = registration;
        registration.showNotification('Notification with ServiceWorker');
      });
    }
  });
}


function DisWithin15MinutesBeforeCurrentTime(timeString) {
  var providedTime = new Date(timeString);
  var currentTime = new Date();
  var differenceInMilliseconds = providedTime - currentTime;
  return differenceInMilliseconds > 0 && differenceInMilliseconds >= (15 * 60 * 1000);
}


function MinutesBeforeCurrentTime(datetimestring) {
  let date1 = new Date(datetimestring);
  let date2 = new Date();
  let diff = date2.getTime() - date1.getTime();

  let msec = diff;
  let sec = msec / 1000;
  let min = Math.round(sec / 60);
  return min;
}

function fromDateToString(date/*: Date*/)/* : String*/ {
  date = new Date(+date);
  date.setTime(date.getTime() - (date.getTimezoneOffset() * 60000));
  let dateAsString = date.toISOString().substr(0, 19);
  return dateAsString;
}
function DateRightNow() {
  return fromDateToString(new Date());
}


function isWithin15MinutesBeforeCurrentTime(givenTime) {

  return MinutesBeforeCurrentTime(givenTime) < -14;
}







function ButtonGo(page, targetdata = 0, nohistory = 0, redundantpage = 0) {
  if (page === historylist[historylist.length - 1]) {
    return false;
  }
  gotoPage(page, targetdata, nohistory, redundantpage);
  return false;
}




$(document).ready(function () {


  //   $("#Homebottombar").on("click", function() {   gotoPage('Home',0);  }); 


});

function MessageOPFStoBlobreqcache(data) {
  console.log(data);
  const hashcontent = data.hash;
  const blobcontent = data.blob;
  reqcacheupdate(window.location.origin + '/RequestData/File/' + hashcontent, blobcontent);
  reqcacheupdate('/RequestData/File/' + hashcontent, blobcontent);
}



function MessageLogin(data) {
  if (data === false) {
    reqcache = {};
    window.location.href = '/';
  }
}
function MessageExec(data) {
  if (data) {

    try {
      eval(data);
    } catch (error) {

    }
  }
}
function MessageReqCacheUpdate(data) {
  const url = data.url;
  const datastring = data.datavalue;
  const dataobject = data.object;
  const content = data.content;
  reqcacheupdate(url, content, datastring, dataobject);
}

function MessageHashCacheUpdate(data) {
  const hashkey = data.hash;
  const content = data.data;
  CacheHash.Update(hashkey, content);
}



function EraseNote() { $.get('/user/note/dismiss'); }

function ShowNotes(forced = false) {

  function ShowNoteModal(response) {
    if (response) {
      ModalContinueCancel('NotesContentModal', 'Notes', response, "EraseNote();hidemodal('NotesContentModal');", cancelbuttontext = 'Close', continuebuttontext = 'Delete Note', continuebuttoncss = 'btn btn-danger', cancelbuttoncss = 'btn btn-default');
    } else {
      if (forced) { ModalQuickDismiss('No Notes', 'No Notes Found'); }
    }
  }

  AjaxDo('/user/note/content', null, ShowNoteModal, null, 'GET', false);
}

function InitializeUserSettings() {
  let request = new RequestData(false);
  request
    .url('/User/Settings/Details')
    .type('POST')
    .data(null)
    .success((response) => {
      user_settings = response;
    })
    .error((err) => {

    })
    .go();

  request
    .url('/User/Settings/Run/Scripts')
    .type('POST')
    .data(null)
    .success((response) => {

      eval(response);
    })
    .error((err) => {

    })
    .go();

}

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.onmessage = function (event) {
    if (event.data.action === 'logout') {
      logoutnow();
    }
  };
}



function PageSettingsScript() {
  CheckAndSetDarkMode();
}

RunFunctiononMutation('body-global', () => {
  PageSettingsScript();
});



