.pragma library

// Address helpers
var macFromDevice = (dev) => {
  if (!dev) return "";
  if (dev.address && dev.address.length > 0) return dev.address;
  if (dev.nativePath && dev.nativePath.indexOf("/dev_") !== -1)
    return dev.nativePath.split("dev_")[1].split("_").join(":");
  return "";
};

var deviceKey = (dev) => {
  if (!dev) return "";
  if (dev.address && dev.address.length > 0) return dev.address.toUpperCase();
  if (dev.nativePath && dev.nativePath.length > 0) return dev.nativePath;
  if (dev.devicePath && dev.devicePath.length > 0) return dev.devicePath;
  return (dev.name || dev.deviceName || "") + "|" + (dev.icon || "");
};

var dedupeDevices = (list) => {
  if (!list || list.length === 0) return [];
  var seen = ({});
  var out = [];
  for (var i = 0; i < list.length; ++i) {
    var d = list[i];
    if (!d) continue;
    var k = deviceKey(d);
    if (k && !seen[k]) { seen[k] = true; out.push(d); }
  }
  return out;
};

// RSSI parsing
var parseRssiOutput = (text) => {
  try {
    text = text || "";
    var mParen = text.match(/\(\s*(-?\d+)\s*(?:d?b?m?)?\s*\)/i);
    if (mParen && mParen.length > 1) return Number(mParen[1]);
    var mDec = text.match(/RSSI:\s*(-?\d+)/i);
    if (mDec && mDec.length > 1) return Number(mDec[1]);
    var mHex = text.match(/RSSI:\s*0x([0-9a-fA-F]+)/i);
    if (mHex && mHex.length > 1) {
      var v = parseInt(mHex[1], 16);
      if (v >= 0x80000000) v = v - 0x100000000; // 32-bit two's complement
      else if (v >= 0x8000) v = v - 0x10000;     // 16-bit
      else if (v >= 0x80) v = v - 0x100;         // 8-bit
      return v;
    }
  } catch (e) {}
  return null;
};

var dbmToPercent = (dbm) => {
  if (dbm === null || dbm === undefined || isNaN(dbm)) return null;
  // Clamp simple linear map roughly from -100..0 dBm to 0..100%
  var pct = Math.round((Number(dbm) + 100) * 2);
  if (isNaN(pct)) return null;
  return Math.max(0, Math.min(100, pct));
};

// Signal helpers
var signalPercent = (device, cache, _version) => {
  if (!device) return null;
  try {
    var addr = macFromDevice(device);
    if (addr && cache && cache[addr] !== undefined) {
      var cached = Number(cache[addr]) | 0;
      return Math.max(0, Math.min(100, cached));
    }
  } catch (e) {}
  var s = device && device.signalStrength;
  if (s === undefined || s <= 0) return null;
  var p = Number(s) | 0;
  return Math.max(0, Math.min(100, p));
};

var signalIcon = (p) => {
  if (p === null) return "antenna-bars-off";
  if (p >= 80) return "antenna-bars-5";
  if (p >= 60) return "antenna-bars-4";
  if (p >= 40) return "antenna-bars-3";
  if (p >= 20) return "antenna-bars-2";
  return "antenna-bars-1";
};

// Icon mapping
var deviceIcon = (name, icon) => {
  var s1 = String(name || "").toLowerCase();
  var s2 = String(icon || "").toLowerCase();

  // Prefer icon-based hints for display devices first to avoid "audio" catching TVs
  var displayHints = ["display", "tv", "monitor", "projector", "screen", "chromecast", "cast"];
  for (var dh = 0; dh < displayHints.length; dh++) {
    if (s2.indexOf(displayHints[dh]) !== -1) return "bt-device-tv";
  }

  var tests = [
    [["controller", "gamepad"], "bt-device-gamepad"],
    [["microphone"], "bt-device-microphone"],
    [["pod", "bud", "minor"], "bt-device-earbuds"],
    [["headset", "arctis", "major"], "bt-device-headset"],
    [["headphone"], "bt-device-headphones"],
    [["mouse"], "bt-device-mouse"],
    [["keyboard"], "bt-device-keyboard"],
    [["watch"], "bt-device-watch"],
    [["display", "tv", "monitor", "projector", "screen", "chromecast", "cast"], "bt-device-tv"],
    [["speaker", "audio", "sound"], "bt-device-speaker"],
    [["phone", "iphone", "android", "samsung"], "bt-device-phone"]
  ];
  for (var i = 0; i < tests.length; i++) {
    var keys = tests[i][0];
    var out = tests[i][1];
    for (var j = 0; j < keys.length; j++) {
      var k = keys[j];
      if (s1.indexOf(k) !== -1 || s2.indexOf(k) !== -1) return out;
    }
  }
  return "bt-device-generic";
};

// Battery percent helper
var batteryPercent = (device) => {
  if (!device || !device.batteryAvailable || device.battery === undefined) return null;
  var val = Math.round(Number(device.battery) * 100);
  if (isNaN(val)) return null;
  return Math.max(0, Math.min(100, val));
};
