// ================== Constants ==================
const CPU_SCRIPT   = "/data/adb/modules/RaiRin-AI/cortex/cpu/get_freqs.sh";
const GRAPH_HEIGHT = 200; // px container
const THUNDER_FILE = "/data/adb/modules/RaiRin-AI/webroot/integrated/thunderclash";
const GAME_FILE    = "/data/adb/modules/RaiRin-AI/cortex/gamemode/status.txt";
const GAMELIST_FILE = "/data/adb/modules/RaiRin-AI/cortex/thunderclash/gamelist.txt";
const LOG_ENABLE  = "/data/adb/modules/RaiRin-AI/cortex/log/enable.sh";
const LOG_DISABLE = "/data/adb/modules/RaiRin-AI/cortex/log/disable.sh && /data/adb/modules/RaiRin-AI/cortex/tracing/distrace";
const LOG_FILE    = "/data/local/tmp/RaiRin-AI/log_option.txt";
const THERMAL_EXTREME_FILE = "/data/adb/modules/RaiRin-AI/cortex/thermal/mode.txt";
const THERMAL_LITE_FILE = "/data/adb/modules/RaiRin-AI/cortex/thermal/lite-mode.txt";

// ================== Safe Element Getter ==================
function safeGet(id) {
  const el = document.getElementById(id);
  if (!el) console.warn(`Element #${id} not found`);
  return el;
}
// ================== Wrapper exec KSU ==================
function exec(command) {
  return new Promise((resolve, reject) => {
    const cb = `exec_cb_${Date.now()}`;
    window[cb] = (errno, stdout, stderr) => {
      delete window[cb];
      if (errno !== 0) reject(new Error(stderr || stdout || "Unknown error"));
      else resolve(stdout);
    };
    try { ksu.exec(command, `window.${cb}`); } 
    catch (e) { reject(e); }
  });
}
// ================== Daemon Status ==================
async function updateDaemonStatus() {
  const elem = safeGet("daemonStatus");
  if (!elem) return;

  try {
    const out = await exec("pidof RaiRin-game");
    if (out && out.trim()) {
      elem.innerHTML = `<span class="green">Online</span> 
        <img src="assets/rairin.webp" 
             style="width:20px;height:20px;vertical-align:middle;margin-left:5px;">`;
      elem.classList.remove("status-offline");
      elem.classList.add("status-online");
    } else {
      elem.innerHTML = `<span class="red">Offline</span> 
        <img src="assets/spicy.webp" 
             style="width:20px;height:20px;vertical-align:middle;margin-left:5px;">`;
      elem.classList.remove("status-online");
      elem.classList.add("status-offline");
    }
  } catch {
    elem.innerHTML = `<span class="red">Offline</span>`;
    elem.classList.remove("status-online");
    elem.classList.add("status-offline");
  }
}

// Auto-refresh 2 detik
setInterval(updateDaemonStatus, 2000);
updateDaemonStatus();
// ================== CPU Graph ==================
const cpuGraph = document.getElementById("cpuGraph");

async function getCpuFreqs() {
  try {
    const out = await exec(`sh ${CPU_SCRIPT}`);
    return out.trim().split("\n").map(line => {
      const [cur, min, max, online] = line.split(",").map(Number);
      return { cur, min, max, online };
    });
  } catch {
    return Array(8).fill({ cur:0, min:1, max:1, online:0 });
  }
}

async function updateCpuGraph() {
  const freqs = await getCpuFreqs();
  cpuGraph.innerHTML = "";

  const maxOfMaxFreqs = Math.max(...freqs.filter(f => f.online).map(f => f.max || 1));

  freqs.forEach((f, i) => {
    const container = document.createElement("div");
    container.style.display = "flex";
    container.style.flexDirection = "column";
    container.style.alignItems = "center";

    // Label frekuensi / offline
    const label = document.createElement("div");
    label.style.fontSize = "10px";
    label.style.color = f.online ? "#fff" : "#888";
    label.style.marginBottom = "2px";
    label.innerText = f.online ? `${Math.round(f.cur/1000)} MHz` : "OFF";
    container.appendChild(label);

    // Bar CPU
    const bar = document.createElement("div");
    bar.className = "cpu-bar";
    const height = f.online ? Math.max(2, (f.cur / maxOfMaxFreqs) * GRAPH_HEIGHT) : 10;
    bar.style.height = `${height}px`;
    bar.style.backgroundColor = f.online ? 
      f.cur/f.max < 0.5 ? "#0f0" : f.cur/f.max < 0.8 ? "#ff0" : "#f00" 
      : "#555"; // offline → abu-abu
    bar.title = `CPU${i}: ${f.online ? Math.round(f.cur/1000) + " MHz" : "OFF"}\n(min ${Math.round(f.min/1000)} / max ${Math.round(f.max/1000)})`;
    container.appendChild(bar);

    // Label core
    const coreLabel = document.createElement("div");
    coreLabel.style.fontSize = "10px";
    coreLabel.style.color = "#aaa";
    coreLabel.style.marginTop = "2px";
    coreLabel.innerText = `${i}`;
    container.appendChild(coreLabel);

    cpuGraph.appendChild(container);
  });
}

// ================== ThunderClash ==================
async function writeThunderOption(option) {
  const outputEl = document.getElementById("thunderOutput");
  outputEl.innerHTML = `Setting ThunderClash to ${option}... <span class="blinker">_</span>`;
  try {
    await exec(`echo ${option} > ${THUNDER_FILE}`);
    outputEl.innerHTML = `<span class="green">ThunderClash set to ${option}</span>`;
  } catch (err) {
    outputEl.innerHTML = `<span class="red">Failed: ${err.message}</span>`;
  }
}

async function initThunderSwitch() {
  const thunderSwitch = document.getElementById("thunderSwitch");
  try {
    const output = await exec(`cat ${THUNDER_FILE}`);
    thunderSwitch.checked = output.trim() === "yes";
  } catch {
    thunderSwitch.checked = false;
  }

  thunderSwitch.addEventListener("change", () => {
    writeThunderOption(thunderSwitch.checked ? "yes" : "no");
  });

  // Info modal
  const thunderInfo = document.getElementById("thunderInfo");
  const thunderModal = document.getElementById("thunderModal");
  const thunderClose = thunderModal.querySelector(".closeModal");

  thunderInfo.addEventListener("click", () => thunderModal.style.display = "block");
  thunderClose.addEventListener("click", () => thunderModal.style.display = "none");
  window.addEventListener("click", (e) => { if(e.target === thunderModal) thunderModal.style.display = "none"; });
}
// ================== Thermal Disable ==================
const THERMAL_STATUS = "/data/adb/modules/RaiRin-AI/cortex/thermal/status.txt";

async function writeThermalOption(option) {
  const outputEl = document.getElementById("thermalOutput");
  outputEl.innerHTML = `Setting Thermal status to ${option}... <span class="blinker">_</span>`;
  try {
    await exec(`echo ${option} > ${THERMAL_STATUS}`);
    outputEl.innerHTML = `<span class="green">Thermal status set to ${option}</span>`;
  } catch (err) {
    outputEl.innerHTML = `<span class="red">Failed: ${err.message}</span>`;
  }
}

async function initThermalSwitch() {
  const thermalSwitch = document.getElementById("thermalSwitch");

  try {
    const output = await exec(`cat ${THERMAL_STATUS}`);
    thermalSwitch.checked = output.trim() === "on";
  } catch {
    thermalSwitch.checked = false;
  }

  thermalSwitch.addEventListener("change", () => {
    writeThermalOption(thermalSwitch.checked ? "on" : "off");
  });

  // Info modal setup
  const thermalInfo = document.getElementById("thermalInfo");
  const thermalModal = document.getElementById("thermalModal");
  const thermalClose = thermalModal.querySelector(".closeModal");

  thermalInfo.addEventListener("click", () => thermalModal.style.display = "block");
  thermalClose.addEventListener("click", () => thermalModal.style.display = "none");
  window.addEventListener("click", (e) => {
    if (e.target === thermalModal) thermalModal.style.display = "none";
  });
}

// ================== Gamelist ==================
const editBtn = document.getElementById("editGamelistBtn");
const gamelistSection = document.getElementById("gamelistSection");
const gamelistList = document.getElementById("gamelistList");
const gamelistSearch = document.getElementById("gamelistSearch");

let installedApps = [];
let gamelistLines = [];

editBtn.addEventListener("click", async () => {
  gamelistSection.style.display = gamelistSection.style.display === "block" ? "none" : "block";
  if (gamelistSection.style.display !== "block") return;

  try {
    const content = await exec(`cat ${GAMELIST_FILE}`);
    gamelistLines = content.split("\n").map(l => l.trim()).filter(l => l);

    const apps = await exec("pm list packages -3");
    installedApps = apps.split("\n").map(l => l.replace("package:", "").trim()).filter(l => l);

    renderGamelist(installedApps, gamelistLines);
  } catch {
    outputEl.innerHTML = `<span class="red">Failed to load apps or gamelist</span>`;
  }
});

function renderGamelist(apps, selected) {
  gamelistList.innerHTML = "";
  apps.forEach(pkg => {
    const div = document.createElement("div");
    const checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.value = pkg;
    checkbox.checked = selected.includes(pkg);
    checkbox.addEventListener("change", () => updateGamelistFile(pkg, checkbox.checked));
    div.appendChild(checkbox);
    const label = document.createElement("label");
    label.textContent = pkg;
    label.style.marginLeft = "6px";
    div.appendChild(label);
    gamelistList.appendChild(div);
  });
}

async function updateGamelistFile(pkg, checked) {
  if (checked && !gamelistLines.includes(pkg)) gamelistLines.push(pkg);
  else if (!checked) gamelistLines = gamelistLines.filter(p => p !== pkg);

  const content = gamelistLines.join("\n");
  const escaped = content.replace(/(["\\`$])/g, '\\$1');
  const command = `su -c 'cat > ${GAMELIST_FILE} <<EOF\n${escaped}\nEOF'`;
  try {
    await exec(command);
    outputEl.innerHTML = `<span class="green">Gamelist updated</span>`;
  } catch {
    outputEl.innerHTML = `<span class="red">Failed to update gamelist</span>`;
  }
}

gamelistSearch.addEventListener("input", () => {
  const query = gamelistSearch.value.toLowerCase();
  const filtered = installedApps.filter(pkg => pkg.toLowerCase().includes(query));
  renderGamelist(filtered, gamelistLines);
});

// Info pop-up Gamelist
const gamelistInfo = document.getElementById("gamelistInfo");
const infoModal = document.getElementById("infoModal");
const closeModal = infoModal.querySelector(".closeModal");

gamelistInfo.addEventListener("click", () => {
  infoModal.style.display = "block";
});

closeModal.addEventListener("click", () => {
  infoModal.style.display = "none";
});

// Klik di luar modal tutup
window.addEventListener("click", (e) => {
  if (e.target === infoModal) {
    infoModal.style.display = "none";
  }
});
const WHITELIST_FILE = "/data/adb/modules/RaiRin-AI/cortex/thunderclash/whitelist.txt";

// ================== Whitelist ==================
const whitelistBtn = document.getElementById("editWhitelistBtn");
const whitelistSection = document.getElementById("whitelistSection");
const whitelistList = document.getElementById("whitelistList");
const whitelistSearch = document.getElementById("whitelistSearch");

let installedAppsWL = [];
let whitelistLines = [];

whitelistBtn.addEventListener("click", async () => {
  whitelistSection.style.display = whitelistSection.style.display === "block" ? "none" : "block";
  if (whitelistSection.style.display !== "block") return;

  try {
    const content = await exec(`cat ${WHITELIST_FILE}`);
    whitelistLines = content.split("\n").map(l => l.trim()).filter(l => l);

    const apps = await exec("pm list packages -3");
    installedAppsWL = apps.split("\n").map(l => l.replace("package:", "").trim()).filter(l => l);

    renderWhitelist(installedAppsWL, whitelistLines);
  } catch {
    outputEl.innerHTML = `<span class="red">Failed to load apps or whitelist</span>`;
  }
});

function renderWhitelist(apps, selected) {
  whitelistList.innerHTML = "";
  apps.forEach(pkg => {
    const div = document.createElement("div");
    const checkbox = document.createElement("input");
    checkbox.type = "checkbox";
    checkbox.value = pkg;
    checkbox.checked = selected.includes(pkg);
    checkbox.addEventListener("change", () => updateWhitelistFile(pkg, checkbox.checked));
    div.appendChild(checkbox);
    const label = document.createElement("label");
    label.textContent = pkg;
    label.style.marginLeft = "6px";
    div.appendChild(label);
    whitelistList.appendChild(div);
  });
}

async function updateWhitelistFile(pkg, checked) {
  if (checked && !whitelistLines.includes(pkg)) whitelistLines.push(pkg);
  else if (!checked) whitelistLines = whitelistLines.filter(p => p !== pkg);

  const content = whitelistLines.join("\n");
  const escaped = content.replace(/(["\\`$])/g, '\\$1');
  const command = `su -c 'cat > ${WHITELIST_FILE} <<EOF\n${escaped}\nEOF'`;
  try {
    await exec(command);
    outputEl.innerHTML = `<span class="green">Whitelist updated</span>`;
  } catch {
    outputEl.innerHTML = `<span class="red">Failed to update whitelist</span>`;
  }
}

whitelistSearch.addEventListener("input", () => {
  const query = whitelistSearch.value.toLowerCase();
  const filtered = installedAppsWL.filter(pkg => pkg.toLowerCase().includes(query));
  renderWhitelist(filtered, whitelistLines);
});
const whitelistInfo = document.getElementById("whitelistInfo");
const whitelistModal = document.getElementById("whitelistModal");
const whitelistClose = whitelistModal.querySelector(".closeModal");

whitelistInfo.addEventListener("click", () => whitelistModal.style.display = "block");
whitelistClose.addEventListener("click", () => whitelistModal.style.display = "none");
window.addEventListener("click", (e) => { if(e.target === whitelistModal) whitelistModal.style.display = "none"; });


// ================== Game Mode ==================

const gameEnableBtn = document.getElementById("gameEnableBtn");
const gameDisableBtn = document.getElementById("gameDisableBtn");
const gameCurrent = document.getElementById("gameCurrent");
const gameOutput = document.getElementById("gameOutput");

function updateGameUI(state) {
  const enabled = state === "enabled";
  gameCurrent.innerText = `Current: ${state}`;
  gameCurrent.className = enabled ? "current green" : "current red";

  // Efek tombol nyala persistent
  gameEnableBtn.classList.toggle("active", enabled);
  gameDisableBtn.classList.toggle("active", !enabled);
}

async function writeGameOption(option) {
  gameOutput.innerHTML = `Setting Game Mode to ${option}... <span class='blinker'>_</span>`;
  try {
    const value = option === "enabled" ? "on" : "off";
    await exec(`echo ${value} > ${GAME_FILE}`);
    updateGameUI(option);
    gameOutput.innerHTML = `<span class='green'>Game Mode ${option}</span>`;
  } catch (err) {
    gameOutput.innerHTML = `<span class='red'>Failed: ${err.message}</span>`;
  }
}

async function initGameButtons() {
  let current = "disabled";

  try {
    const out = await exec(`cat ${GAME_FILE} 2>/dev/null || echo off`);
    current = out.trim() === "on" ? "enabled" : "disabled";
  } catch {
    current = "disabled";
  }

  // Set tampilan awal sesuai file
  updateGameUI(current);

  // Event klik
  gameEnableBtn.addEventListener("click", async () => {
    await writeGameOption("enabled");
  });

  gameDisableBtn.addEventListener("click", async () => {
    await writeGameOption("disabled");
  });

  // Info modal
  const gameModeInfo = document.getElementById("gameModeInfo");
  const gameModeModal = document.getElementById("gameModeModal");
  const gameModeClose = gameModeModal.querySelector(".closeModal");

  gameModeInfo.addEventListener("click", () => gameModeModal.style.display = "block");
  gameModeClose.addEventListener("click", () => gameModeModal.style.display = "none");
  window.addEventListener("click", (e) => {
    if (e.target === gameModeModal) gameModeModal.style.display = "none";
  });
}

const CPU_CONTROL_SCRIPT = "/data/adb/modules/RaiRin-AI/cortex/cpu/cpu-control.sh";
const cpuControlContainer = document.getElementById("cpuControlButtons");
const NUM_CPU = 8; // CPU 0-7

async function getCpuOnlineStatus() {
  try {
    const out = await exec(`cat /sys/devices/system/cpu/cpu*/online 2>/dev/null || echo 1`);
    return out.trim().split("\n").map(n => Number(n));
  } catch {
    return Array(NUM_CPU).fill(1);
  }
}

async function updateCpuControlButtons() {
  const status = await getCpuOnlineStatus();
  cpuControlContainer.innerHTML = "";

  for (let i = 0; i < NUM_CPU; i++) {
    const btn = document.createElement("button");
    btn.className = "btn cpu-control-btn";
    btn.innerText = `CPU ${i}`;
    btn.style.flex = "1 1 60px";
    btn.style.backgroundColor = status[i] === 1 ? "#0f0" : "#555";

    btn.addEventListener("click", async () => {
      btn.disabled = true;
      try {
        await exec(`sh ${CPU_CONTROL_SCRIPT} ${i}`);
      } catch (err) {
        console.error(err);
      }
      btn.disabled = false;
      updateCpuControlButtons(); 
    });

    cpuControlContainer.appendChild(btn);
  }
}
// ================== CPU Control Info ==================
const cpuControlInfo = document.getElementById("cpuControlInfo");
const cpuControlModal = document.getElementById("cpuControlModal");
const cpuControlClose = cpuControlModal.querySelector(".closeModal");

cpuControlInfo.addEventListener("click", () => cpuControlModal.style.display = "block");
cpuControlClose.addEventListener("click", () => cpuControlModal.style.display = "none");
window.addEventListener("click", (e) => {
  if (e.target === cpuControlModal) cpuControlModal.style.display = "none";
});

// ================== Default Governor ==================
const DEFAULT_GOV_FILE = "/data/adb/modules/RaiRin-AI/cortex/cpu/default-gov.txt";
const defaultGovernorSelect = document.getElementById("defaultGovernorSelect");
const defaultGovernorOutput = document.getElementById("defaultGovernorOutput");

async function loadAvailableGovernors() {
  try {
    // Ambil list governor dari cpu0
    const out = await exec("cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors");
    return out.trim().split(" ");
  } catch {
    return ["performance","powersave","schedutil"];
  }
}

async function loadDefaultGovernor() {
  try {
    const out = await exec(`cat ${DEFAULT_GOV_FILE}`);
    return out.trim();
  } catch {
    return "";
  }
}

async function writeDefaultGovernor(gov) {
  defaultGovernorOutput.innerHTML = `Setting default governor to ${gov}... <span class="blinker">_</span>`;
  try {
    await exec(`echo ${gov} > ${DEFAULT_GOV_FILE}`);
    defaultGovernorOutput.innerHTML = `<span class="green">Default governor set to ${gov}</span>`;
  } catch (err) {
    defaultGovernorOutput.innerHTML = `<span class="red">Failed: ${err.message}</span>`;
  }
}

async function initDefaultGovernor() {
  const governors = await loadAvailableGovernors();
  const currentDefault = await loadDefaultGovernor();

  defaultGovernorSelect.innerHTML = "";
  governors.forEach(gov => {
    const opt = document.createElement("option");
    opt.value = gov;
    opt.innerText = gov;
    if (gov === currentDefault) opt.selected = true;
    defaultGovernorSelect.appendChild(opt);
  });

  defaultGovernorSelect.addEventListener("change", () => {
    writeDefaultGovernor(defaultGovernorSelect.value);
  });

  // Info modal
  const defaultGovernorInfo = document.getElementById("defaultGovernorInfo");
  const defaultGovernorModal = document.getElementById("defaultGovernorModal");
  const defaultGovernorClose = defaultGovernorModal.querySelector(".closeModal");

  defaultGovernorInfo.addEventListener("click", () => defaultGovernorModal.style.display = "block");
  defaultGovernorClose.addEventListener("click", () => defaultGovernorModal.style.display = "none");
  window.addEventListener("click", (e) => { if(e.target === defaultGovernorModal) defaultGovernorModal.style.display = "none"; });
}

// ================== Thermal Extreme ==================
async function writeThermalExtreme(option) {
  const outputEl = safeGet("thermalOutput");
  outputEl.innerHTML = `Setting Thermal Extreme to ${option}... <span class="blinker">_</span>`;
  try {
    await exec(`echo ${option} > ${THERMAL_EXTREME_FILE}`);
    outputEl.innerHTML = `<span class="green">Thermal Extreme set to ${option}</span>`;
  } catch (err) {
    outputEl.innerHTML = `<span class="red">Failed: ${err.message}</span>`;
  }
}

async function initThermalExtremeSwitch() {
  const switchEl = safeGet("thermalSwitch");
  const infoIcon = safeGet("thermalInfo");
  const modal = safeGet("thermalModal");
  const closeBtn = modal.querySelector(".closeModal");

  try {
    const output = await exec(`cat ${THERMAL_EXTREME_FILE}`);
    switchEl.checked = output.trim() === "on";
  } catch {
    switchEl.checked = false;
  }

  switchEl.addEventListener("change", () => {
    writeThermalExtreme(switchEl.checked ? "on" : "off");
  });

  infoIcon.addEventListener("click", () => modal.style.display = "block");
  closeBtn.addEventListener("click", () => modal.style.display = "none");
  window.addEventListener("click", (e) => { if (e.target === modal) modal.style.display = "none"; });
}

// ================== Thermal Lite ==================
async function writeThermalLite(option) {
  const outputEl = safeGet("thermaliteOutput");
  outputEl.innerHTML = `Setting Thermal Lite to ${option}... <span class="blinker">_</span>`;
  try {
    await exec(`echo ${option} > ${THERMAL_LITE_FILE}`);
    outputEl.innerHTML = `<span class="green">Thermal Lite set to ${option}</span>`;
  } catch (err) {
    outputEl.innerHTML = `<span class="red">Failed: ${err.message}</span>`;
  }
}

async function initThermalLiteSwitch() {
  const switchEl = safeGet("thermaliteSwitch");
  const infoIcon = safeGet("thermaliteInfo");
  const modal = safeGet("thermaliteModal");
  const closeBtn = modal.querySelector(".closeModal");

  try {
    const output = await exec(`cat ${THERMAL_LITE_FILE}`);
    switchEl.checked = output.trim() === "on";
  } catch {
    switchEl.checked = false;
  }

  switchEl.addEventListener("change", () => {
    writeThermalLite(switchEl.checked ? "on" : "off");
  });

  infoIcon.addEventListener("click", () => modal.style.display = "block");
  closeBtn.addEventListener("click", () => modal.style.display = "none");
  window.addEventListener("click", (e) => { if (e.target === modal) modal.style.display = "none"; });
}


// Tombol 

// Auto update 2 detik
setInterval(updateCpuControlButtons, 1000);
updateCpuControlButtons();

// ================== Init ==================
document.addEventListener("DOMContentLoaded", () => {
  updateDaemonStatus();
  setInterval(updateDaemonStatus, 2000);

  initThunderSwitch();
  initThermalExtremeSwitch();
  initThermalLiteSwitch();
  initGameButtons();
  initDefaultGovernor();

  setInterval(updateCpuGraph, 500);
  updateCpuGraph();
  setInterval(updateCpuControlButtons, 1000);
  updateCpuControlButtons();
});