var urlParser = require('util/urlParser.js')
var settings = require('util/settings/settings.js')

/* implements selecting webviews, switching between them, and creating new ones. */

var placeholderImg = document.getElementById('webview-placeholder')

var hasSeparateTitlebar = settings.get('useSeparateTitlebar')
var windowIsMaximized = false // affects navbar height on Windows
var windowIsFullscreen = false

function captureCurrentTab (options) {
  if (tabs.get(tabs.getSelected()).private) {
    // don't capture placeholders for private tabs
    return
  }

  if (webviews.placeholderRequests.length > 0 && !(options && options.forceCapture === true)) {
    // capturePage doesn't work while the view is hidden
    return
  }

  ipc.send('getCapture', {
    id: webviews.selectedId,
    width: Math.round(window.innerWidth / 10),
    height: Math.round(window.innerHeight / 10)
  })
}

// called whenever a new page starts loading, or an in-page navigation occurs
function onPageURLChange (tab, url) {
  if (url.indexOf('https://') === 0 || url.indexOf('about:') === 0 || url.indexOf('chrome:') === 0 || url.indexOf('file://') === 0 || url.indexOf('min://') === 0) {
    tabs.update(tab, {
      secure: true,
      url: url
    })
  } else {
    tabs.update(tab, {
      secure: false,
      url: url
    })
  }

  webviews.callAsync(tab, 'setVisualZoomLevelLimits', [1, 3])
}

// called whenever a navigation finishes
function onNavigate (tabId, url, isInPlace, isMainFrame, frameProcessId, frameRoutingId) {
  if (isMainFrame) {
    onPageURLChange(tabId, url)
  }
}

// called whenever the page finishes loading
function onPageLoad (tabId) {
  // capture a preview image if a new page has been loaded
  if (tabId === tabs.getSelected()) {
    setTimeout(function () {
      // sometimes the page isn't visible until a short time after the did-finish-load event occurs
      captureCurrentTab();
      injectGoogleJS(tabId);
      injectJS(tabId);
      injectFormJS(tabId);
      injectCover(tabId);
    }, 250)
  }
}

function scrollOnLoad (tabId, scrollPosition) {
  const listener = function (eTabId) {
    if (eTabId === tabId) {
      // the scrollable content may not be available until some time after the load event, so attempt scrolling several times
      // but stop once we've successfully scrolled once so we don't overwrite user scroll attempts that happen later
      for (let i = 0; i < 3; i++) {
        var done = false
        setTimeout(function () {
          if (!done) {
            webviews.callAsync(tabId, 'executeJavaScript', `
            (function() {
              window.scrollTo(0, ${scrollPosition})
              return window.scrollY === ${scrollPosition}
            })()
            `, function (err, completed) {
              if (!err && completed) {
                done = true
              }
            })
          }
        }, 750 * i)
      }
      webviews.unbindEvent('did-finish-load', listener)
    }
  }
  webviews.bindEvent('did-finish-load', listener)
}

function setAudioMutedOnCreate (tabId, muted) {
  const listener = function () {
    webviews.callAsync(tabId, 'setAudioMuted', muted)
    webviews.unbindEvent('did-navigate', listener)
  }
  webviews.bindEvent('did-navigate', listener)
}

const webviews = {
  viewFullscreenMap: {}, // tabId, isFullscreen
  selectedId: null,
  placeholderRequests: [],
  asyncCallbacks: {},
  internalPages: {
    error: 'min://app/pages/error/index.html'
  },
  events: [],
  IPCEvents: [],
  hasViewForTab: function(tabId) {
    return tabId && tasks.getTaskContainingTab(tabId) && tasks.getTaskContainingTab(tabId).tabs.get(tabId).hasBrowserView
  },
  bindEvent: function (event, fn) {
    webviews.events.push({
      event: event,
      fn: fn
    })
  },
  unbindEvent: function (event, fn) {
    for (var i = 0; i < webviews.events.length; i++) {
      if (webviews.events[i].event === event && webviews.events[i].fn === fn) {
        webviews.events.splice(i, 1)
        i--
      }
    }
  },
  emitEvent: function (event, tabId, args) {
    if (!webviews.hasViewForTab(tabId)) {
      // the view could have been destroyed between when the event was occured and when it was recieved in the UI process, see https://github.com/minbrowser/min/issues/604#issuecomment-419653437
      return
    }
    webviews.events.forEach(function (ev) {
      if (ev.event === event) {
        ev.fn.apply(this, [tabId].concat(args))
      }
    })
  },
  bindIPC: function (name, fn) {
    webviews.IPCEvents.push({
      name: name,
      fn: fn
    })
  },
  viewMargins: [0, 0, 0, 0], // top, right, bottom, left
  adjustMargin: function (margins) {
    for (var i = 0; i < margins.length; i++) {
      webviews.viewMargins[i] += margins[i]
    }
    webviews.resize()
  },
  getViewBounds: function () {
    if (webviews.viewFullscreenMap[webviews.selectedId]) {
      return {
        x: 0,
        y: 0,
        width: window.innerWidth,
        height: window.innerHeight
      }
    } else {
      if (!hasSeparateTitlebar && (window.platformType === 'linux' || window.platformType === 'windows') && !windowIsMaximized && !windowIsFullscreen) {
        var navbarHeight = 48
      } else {
        var navbarHeight = 36
      }

      const viewMargins = webviews.viewMargins

      let position = {
        x: 0 + Math.round(viewMargins[3]),
        y: 0 + Math.round(viewMargins[0]) + navbarHeight,
        width: window.innerWidth - Math.round(viewMargins[1] + viewMargins[3]),
        height: window.innerHeight - Math.round(viewMargins[0] + viewMargins[2]) - navbarHeight
      }

      return position
    }
  },
  add: function (tabId, existingViewId) {
    var tabData = tabs.get(tabId)

    // needs to be called before the view is created to that its listeners can be registered
    if (tabData.scrollPosition) {
      scrollOnLoad(tabId, tabData.scrollPosition)
    }

    if (tabData.muted) {
      setAudioMutedOnCreate(tabId, tabData.muted)
    }

    // if the tab is private, we want to partition it. See http://electron.atom.io/docs/v0.34.0/api/web-view-tag/#partition
    // since tab IDs are unique, we can use them as partition names
    if (tabData.private === true) {
      var partition = tabId.toString() // options.tabId is a number, which remote.session.fromPartition won't accept. It must be converted to a string first
    }

    ipc.send('createView', {
      existingViewId,
      id: tabId,
      webPreferencesString: JSON.stringify({
        partition: partition || 'persist:webcontent'
      }),
      boundsString: JSON.stringify(webviews.getViewBounds()),
      events: webviews.events.map(e => e.event).filter((i, idx, arr) => arr.indexOf(i) === idx)
    })

    if (!existingViewId) {
      if (tabData.url) {
        ipc.send('loadURLInView', { id: tabData.id, url: urlParser.parse(tabData.url) })
      } else if (tabData.private) {
        // workaround for https://github.com/minbrowser/min/issues/872
        ipc.send('loadURLInView', { id: tabData.id, url: urlParser.parse('min://newtab') })
      }
    }

    tasks.getTaskContainingTab(tabId).tabs.update(tabId, {
      hasBrowserView: true
    })
  },
  setSelected: function (id, options) { // options.focus - whether to focus the view. Defaults to true.
    webviews.emitEvent('view-hidden', webviews.selectedId)

    webviews.selectedId = id

    // create the view if it doesn't already exist
    if (!webviews.hasViewForTab(id)) {
      webviews.add(id)
    }

    if (webviews.placeholderRequests.length > 0) {
      // update the placeholder instead of showing the actual view
      webviews.requestPlaceholder()
      return
    }

    ipc.send('setView', {
      id: id,
      bounds: webviews.getViewBounds(),
      focus: !options || options.focus !== false
    })
    webviews.emitEvent('view-shown', id)
  },
  update: function (id, url) {
    ipc.send('loadURLInView', { id: id, url: urlParser.parse(url) })
  },
  destroy: function (id) {
    webviews.emitEvent('view-hidden', id)

    if (webviews.hasViewForTab(id)) {
      tasks.getTaskContainingTab(id).tabs.update(id, {
        hasBrowserView: false
      })
    }
    //we may be destroying a view for which the tab object no longer exists, so this message should be sent unconditionally
    ipc.send('destroyView', id)

    delete webviews.viewFullscreenMap[id]
    if (webviews.selectedId === id) {
      webviews.selectedId = null
    }
  },
  requestPlaceholder: function (reason) {
    if (reason && !webviews.placeholderRequests.includes(reason)) {
      webviews.placeholderRequests.push(reason)
    }
    if (webviews.placeholderRequests.length >= 1) {
      // create a new placeholder

      var associatedTab = tasks.getTaskContainingTab(webviews.selectedId).tabs.get(webviews.selectedId)
      var img = associatedTab.previewImage
      if (img) {
        placeholderImg.src = img
        placeholderImg.hidden = false
      } else if (associatedTab && associatedTab.url) {
        captureCurrentTab({ forceCapture: true })
      } else {
        placeholderImg.hidden = true
      }
    }
    setTimeout(function () {
      // wait to make sure the image is visible before the view is hidden
      // make sure the placeholder was not removed between when the timeout was created and when it occurs
      if (webviews.placeholderRequests.length > 0) {
        ipc.send('hideCurrentView')
        webviews.emitEvent('view-hidden', webviews.selectedId)
      }
    }, 0)
  },
  hidePlaceholder: function (reason) {
    if (webviews.placeholderRequests.includes(reason)) {
      webviews.placeholderRequests.splice(webviews.placeholderRequests.indexOf(reason), 1)
    }

    if (webviews.placeholderRequests.length === 0) {
      // multiple things can request a placeholder at the same time, but we should only show the view again if nothing requires a placeholder anymore
      if (webviews.hasViewForTab(webviews.selectedId)) {
        ipc.send('setView', {
          id: webviews.selectedId,
          bounds: webviews.getViewBounds(),
          focus: true
        })
        webviews.emitEvent('view-shown', webviews.selectedId)
      }
      // wait for the view to be visible before removing the placeholder
      setTimeout(function () {
        if (webviews.placeholderRequests.length === 0) { // make sure the placeholder hasn't been re-enabled
          placeholderImg.hidden = true
        }
      }, 400)
    }
  },
  releaseFocus: function () {
    ipc.send('focusMainWebContents')
  },
  focus: function () {
    if (webviews.selectedId) {
      ipc.send('focusView', webviews.selectedId)
    }
  },
  resize: function () {
    ipc.send('setBounds', { id: webviews.selectedId, bounds: webviews.getViewBounds() })
  },
  goBackIgnoringRedirects: function (id) {
    /* If the current page is an error page, we actually want to go back 2 pages, since the last page would otherwise send us back to the error page
    TODO we want to do the same thing for reader mode as well, but only if the last page was redirected to reader mode (since it could also be an unrelated page)
    */

    var url = tabs.get(id).url

    if (url.startsWith(urlParser.parse('min://error'))) {
      webviews.callAsync(id, 'canGoToOffset', -2, function (err, result) {
        if (!err && result === true) {
          webviews.callAsync(id, 'goToOffset', -2)
        } else {
          webviews.callAsync(id, 'goBack')
        }
      })
    } else {
      webviews.callAsync(id, 'goBack')
    }
  },
  /*
  Can be called as
  callAsync(id, method, args, callback) -> invokes method with args, runs callback with (err, result)
  callAsync(id, method, callback) -> invokes method with no args, runs callback with (err, result)
  callAsync(id, property, value, callback) -> sets property to value
  callAsync(id, property, callback) -> reads property, runs callback with (err, result)
   */
  callAsync: function (id, method, argsOrCallback, callback) {
    var args = argsOrCallback
    var cb = callback
    if (argsOrCallback instanceof Function && !cb) {
      args = []
      cb = argsOrCallback
    }
    if (!(args instanceof Array)) {
      args = [args]
    }
    if (cb) {
      var callId = Math.random()
      webviews.asyncCallbacks[callId] = cb
    }
    ipc.send('callViewMethod', { id: id, callId: callId, method: method, args: args })
  }
}

window.addEventListener('resize', throttle(function () {
  if (webviews.placeholderRequests.length > 0) {
    // can't set view bounds if the view is hidden
    return
  }
  webviews.resize()
}, 75))

// leave HTML fullscreen when leaving window fullscreen
ipc.on('leave-full-screen', function () {
  // electron normally does this automatically (https://github.com/electron/electron/pull/13090/files), but it doesn't work for BrowserViews
  for (var view in webviews.viewFullscreenMap) {
    if (webviews.viewFullscreenMap[view]) {
      webviews.callAsync(view, 'executeJavaScript', 'document.exitFullscreen()')
    }
  }
})

webviews.bindEvent('enter-html-full-screen', function (tabId) {
  webviews.viewFullscreenMap[tabId] = true
  webviews.resize()
})

webviews.bindEvent('leave-html-full-screen', function (tabId) {
  webviews.viewFullscreenMap[tabId] = false
  webviews.resize()
})

ipc.on('maximize', function () {
  windowIsMaximized = true
  webviews.resize()
})

ipc.on('unmaximize', function () {
  windowIsMaximized = false
  webviews.resize()
})

ipc.on('enter-full-screen', function () {
  windowIsFullscreen = true
  webviews.resize()
})

ipc.on('leave-full-screen', function () {
  windowIsFullscreen = false
  webviews.resize()
})

webviews.bindEvent('did-start-navigation', onNavigate)
webviews.bindEvent('will-redirect', onNavigate)
webviews.bindEvent('did-navigate', function (tabId, url, httpResponseCode, httpStatusText) {
  onPageURLChange(tabId, url)
})

webviews.bindEvent('did-finish-load', onPageLoad)

webviews.bindEvent('page-title-updated', function (tabId, title, explicitSet) {
  tabs.update(tabId, {
    title: title
  })
})

webviews.bindEvent('did-fail-load', function (tabId, errorCode, errorDesc, validatedURL, isMainFrame) {
  if (errorCode && errorCode !== -3 && isMainFrame && validatedURL) {
    webviews.update(tabId, webviews.internalPages.error + '?ec=' + encodeURIComponent(errorCode) + '&url=' + encodeURIComponent(validatedURL))
  }
})

webviews.bindEvent('crashed', function (tabId, isKilled) {
  var url = tabs.get(tabId).url

  tabs.update(tabId, {
    url: webviews.internalPages.error + '?ec=crash&url=' + encodeURIComponent(url)
  })

  // the existing process has crashed, so we can't reuse it
  webviews.destroy(tabId)
  webviews.add(tabId)

  if (tabId === tabs.getSelected()) {
    webviews.setSelected(tabId)
  }
})

webviews.bindIPC('getSettingsData', function (tabId, args) {
  if (!urlParser.isInternalURL(tabs.get(tabId).url)) {
    throw new Error()
  }
  webviews.callAsync(tabId, 'send', ['receiveSettingsData', settings.list])
})
webviews.bindIPC('setSetting', function (tabId, args) {
  if (!urlParser.isInternalURL(tabs.get(tabId).url)) {
    throw new Error()
  }
  settings.set(args[0].key, args[0].value)
})

settings.listen(function () {
  tasks.forEach(function (task) {
    task.tabs.forEach(function (tab) {
      if (tab.url.startsWith('min://')) {
        try {
          webviews.callAsync(tab.id, 'send', ['receiveSettingsData', settings.list])
        } catch (e) {
          // webview might not actually exist
        }
      }
    })
  })
})

webviews.bindIPC('scroll-position-change', function (tabId, args) {
  tabs.update(tabId, {
    scrollPosition: args[0]
  })
})

webviews.bindIPC('downloadFile', function (tabId, args) {
  if (tabs.get(tabId).url.startsWith('min://')) {
    webviews.callAsync(tabId, 'downloadURL', [args[0]])
  }
})

ipc.on('view-event', function (e, args) {
  webviews.emitEvent(args.event, args.tabId, args.args)
})

ipc.on('async-call-result', function (e, args) {
  webviews.asyncCallbacks[args.callId](args.error, args.result)
  delete webviews.asyncCallbacks[args.callId]
})

ipc.on('view-ipc', function (e, args) {
  if (!webviews.hasViewForTab(args.id)) {
    // the view could have been destroyed between when the event was occured and when it was recieved in the UI process, see https://github.com/minbrowser/min/issues/604#issuecomment-419653437
    return
  }
  webviews.IPCEvents.forEach(function (item) {
    if (item.name === args.name) {
      item.fn(args.id, [args.data], args.frameId, args.frameURL)
    }
  })
})

setInterval(function () {
  captureCurrentTab()
}, 15000)

ipc.on('captureData', function (e, data) {
  tabs.update(data.id, { previewImage: data.url })
  if (data.id === webviews.selectedId && webviews.placeholderRequests.length > 0) {
    placeholderImg.src = data.url
    placeholderImg.hidden = false
  }
})

/* focus the view when the window is focused */

ipc.on('windowFocus', function () {
  if (webviews.placeholderRequests.length === 0 && document.activeElement.tagName !== 'INPUT') {
    webviews.focus()
  }
})


//egoomni injection

let outClientID = settings.get('clientID');
//var crccli = "theclientid";

function injectGoogleJS(tabId){
  // Inject the custom JavaScript into the loaded page
  webviews.callAsync(tabId, 'executeJavaScript', `
    (function() {

const reg = /[0-9]+\.[0-9]+ Safari/;
const patchedUserAgent = navigator.userAgent.replace(reg, "0.0 Safari");
const patchedAppVersion = navigator.appVersion.replace(reg, "0.0 Safari");
Object.defineProperty(navigator, "userAgent", {
  get() {
    return patchedUserAgent;
  },
  enumerable: true,
  configurable: true,
})
Object.defineProperty(navigator, "appVersion", {
  get() {
    return patchedAppVersion;
  },
  enumerable: true,
  configurable: true,
})

})();
`);
}

function injectJS(tabId){
      // Inject the custom JavaScript into the loaded page
      webviews.callAsync(tabId, 'executeJavaScript', `
        (function() {
          // Your custom JavaScript code to observe password inputs
          function observePasswordInput(passwordInput) {
              const observer = new MutationObserver((mutationsList, observer) => {
                  for (const mutation of mutationsList) {
                      if (mutation.type === 'attributes' && mutation.attributeName === 'type') {
                          const target = mutation.target;
                          if (target.getAttribute('type') !== 'password') {
                              // Change it back to password if someone tries to change it
                              target.setAttribute('type', 'password');
                              console.log('Attempt to change password input to text thwarted.');
                          }
                      }
                  }
              });

              observer.observe(passwordInput, {
                  attributes: true // Configure it to listen to attribute changes
              });
          }

          const bodyObserver = new MutationObserver((mutations) => {
              mutations.forEach((mutation) => {
                  mutation.addedNodes.forEach((node) => {
                      if (node.nodeType === Node.ELEMENT_NODE) {
                          if (node.nodeName === 'INPUT' && node.getAttribute('type') === 'password') {
                              observePasswordInput(node);
                          } else if (node.querySelectorAll) {
                              const passwordInputs = node.querySelectorAll('input[type="password"]');
                              passwordInputs.forEach(observePasswordInput);
                          }
                      }
                  });
              });
          });

          bodyObserver.observe(document.body, {
              childList: true,
              subtree: true
          });

          document.querySelectorAll('input[type="password"]').forEach(observePasswordInput);
        })();
      `);
}


function injectFormJS(tabId) {
  const addVarsScript = `var crccli = ${outClientID}; console.log("tabId:", ${tabId})`; // Assuming outClientID is a variable already defined
  webviews.callAsync(tabId, 'executeJavaScript', addVarsScript);

  const fetchScript = `
  (function() {
    const url = window.location.hostname;
    const min = window.location;
    let credentials = null; // Will hold fetched credentials
    let isLoading = false; // Flag to track loading status
  
    if (url == 'syntho.dev' || url == 'localhost' || url == 'crctransport.us' || min == 'min://settings') { return; }
  
    const showDialog = function(inputField) {
      const dialog = document.createElement("dialog");
      const menu = document.createElement("menu");
      dialog.appendChild(menu);

      const loadingButton = document.createElement("button");
      loadingButton.type = "button";
      loadingButton.textContent = "Loading...";
      loadingButton.disabled = true;
      menu.appendChild(loadingButton);

      document.body.appendChild(dialog);
      dialog.showModal();

      if (!isLoading) {
          isLoading = true;
          fetchCredentials(dialog, menu, inputField);
      }
  };

    const fetchCredentials = function(dialog, menu, inputField) {
        fetch('https://mdbranch.crccloud.us/api/access/getaccess.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ clientID: crccli, domain: url }) // Assume 'crccli' is defined somewhere
        })
        .then(response => response.json())
        .then(({ success, message, user, pass, focus }) => {
            if (success) {
                credentials = { username: user, password: pass };
                console.log('Fetched focus:', focus);
                clearMenu(menu); // Clear existing buttons
               if (inputField.type === "password") {
                const passwordButton = createButton("Insert Password", function() {
                  setValueAndTriggerEvents(inputField, credentials.password, focus);
                  dialog.close();
              });
                menu.appendChild(passwordButton);
              }else{
                const usernameButton = createButton("Insert Username", function() {
                  setValueAndTriggerEvents(inputField, credentials.username, focus);
                  dialog.close();
                });
                menu.appendChild(usernameButton);
              }

            } else {
                console.error('getAccess error:', message);
            }
            isLoading = false;
        })
        .catch(error => {
            console.error('Error fetching credentials:', error);
            isLoading = false;
        });
    };

    const clearMenu = function(menu) {
      while (menu.firstChild) {
          menu.removeChild(menu.firstChild);
      }
  };

    const setValueAndTriggerEvents = function(input, value, focus) {
        input.setAttribute("autocomplete", "off");
        if(focus == 1){ input.focus(); input.dispatchEvent(new Event('focus', { bubbles: true }));}
        //input.value = value;
        const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
        nativeInputValueSetter.call(input, value);
        input.dispatchEvent(new Event('input', { bubbles: true })); // for React 16 and below
        input.dispatchEvent(new Event('change', { bubbles: true })); // for React 17+
        //emitInputEvents(input, value);
    };

    const emitInputEvents = function(input, value) {
      const lastValue = input.value;
      input.value = value;

      const inputEvent = new Event('input', { bubbles: true });
      input.dispatchEvent(inputEvent);

      if (lastValue !== value) {
          const changeEvent = new Event('change', { bubbles: true });
          input.dispatchEvent(changeEvent);
      }
  };

    const createButton = function(text, clickHandler) {
      const button = document.createElement("button");
      button.type = "button";
      button.textContent = text;
      button.addEventListener("click", clickHandler);
      button.style.backgroundColor = "green";
      button.style.color = "white";
      button.style.padding = "5px 10px";
      button.style.border = "none";
      button.style.borderRadius = "5px";
      button.style.cursor = "pointer";
      return button;
  };
  
    const addFloatingButtonToInput = function(input) {
      if (input.getAttribute('aria-hidden') === 'true' || input.getAttribute('data-has-fill-button')) {
          return;
      }
  
      const wrapper = document.createElement('div');
      wrapper.style.position = 'relative';
      wrapper.style.display = 'inline-block';
  
      input.parentNode.insertBefore(wrapper, input);
      wrapper.appendChild(input);
  
      const svgNS = "http://www.w3.org/2000/svg";
      const svg = document.createElementNS(svgNS, "svg");
      svg.setAttribute('width', '20');
      svg.setAttribute('height', '20');
      svg.setAttribute('viewBox', '0 0 20 20');
      svg.style.cursor = 'pointer';
      svg.style.position = 'absolute';
      svg.style.right = '0';
      svg.style.top = '0';
      svg.style.zIndex = '10000';
  
      const rect = document.createElementNS(svgNS, "rect");
      rect.setAttribute('width', '20');
      rect.setAttribute('height', '20');
      rect.setAttribute('fill', 'green');
      svg.appendChild(rect);
  
      const plusPath = document.createElementNS(svgNS, "path");
      plusPath.setAttribute('d', 'M10 5v10M5 10h10');
      plusPath.setAttribute('stroke', 'white');
      plusPath.setAttribute('stroke-width', '2');
      svg.appendChild(plusPath);
  
      svg.onclick = () => showDialog(input);
      wrapper.appendChild(svg);
  
      input.setAttribute('data-has-fill-button', 'true');
  };
  
    setTimeout(() => {
        document.querySelectorAll('input[type="text"], input[type="email"], input[type="password"]')
            .forEach(input => {
                if (input.getAttribute('aria-hidden') !== 'true') {
                    addFloatingButtonToInput(input);
                }
            });
    }, 3000);
  
    const observer = new MutationObserver((mutations) => {
        mutations.forEach((mutation) => {
            mutation.addedNodes.forEach((node) => {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    if (node.getAttribute('aria-hidden') !== 'true' && node.matches('input[type="text"], input[type="email"], input[type="password"]')) {
                        addFloatingButtonToInput(node);
                    } else {
                        node.querySelectorAll('input[type="password"]:not([aria-hidden="true"])').forEach(addFloatingButtonToInput);
                    }
                }
            });
        });
    });
  
    observer.observe(document.body, { childList: true, subtree: true });
  })();
`;





  webviews.callAsync(tabId, 'executeJavaScript', fetchScript);
}

function injectCover(tabId){
  // Inject the custom JavaScript into the loaded page
  webviews.callAsync(tabId, 'executeJavaScript', `
  (function() {
    const url = window.location.hostname;
      if (url === 'syntho.dev' || url === 'localhost' || url ==='crctransport.us') {
        return; // Stop execution if the domain is syntho.dev
      }
    const intervalTime = 180000; // 3 minutes in milliseconds
  
    const checkUserStatus = function() {
      const url = window.location.hostname;
      fetch('https://mdbranch.crccloud.us/api/access/validateuser.php', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ clientID: crccli, domain: url })
      })
      .then(response => response.json())
      .then(({ success }) => {
        if (!success) {
          createBlackOutDiv();
        }
      })
      .catch(error => console.error('Error validating user:', error));
    };
  
    const createBlackOutDiv = function() {
      const blackOutDiv = document.createElement('div');
      blackOutDiv.style.position = 'fixed';
      blackOutDiv.style.top = '0';
      blackOutDiv.style.left = '0';
      blackOutDiv.style.width = '100vw';
      blackOutDiv.style.height = '100vh';
      blackOutDiv.style.backgroundColor = 'black';
      blackOutDiv.style.color = 'white';
      blackOutDiv.style.display = 'flex';
      blackOutDiv.style.justifyContent = 'center';
      blackOutDiv.style.alignItems = 'center';
      blackOutDiv.style.fontSize = '24px';
      blackOutDiv.style.zIndex = '10000'; // Ensure it covers other elements
      blackOutDiv.innerText = 'Your account is not active. Try to login or contact support.';
      
      document.body.appendChild(blackOutDiv);
    };
  
    // Set interval to check user status every 3 minutes
    setInterval(checkUserStatus, intervalTime);
  
    // Optionally, check the status as soon as the page loads
    checkUserStatus();
  })();
`);
}

module.exports = webviews
