//let bucket = {};
//let cup = {};
//let board = {};

// Utility Functions
function updateBoxesFromVars() {
  const bucketBox = document.getElementById("bucketBox");
  const cupBox = document.getElementById("cupBox");
  const boardBox = document.getElementById("boardBox");

  if (bucketBox) bucketBox.value = JSON.stringify(bucket, null, 2);
  if (cupBox) cupBox.value = JSON.stringify(cup, null, 2);
  if (boardBox) boardBox.value = JSON.stringify(board, null, 2);
}

function updateBoxesFromPara(data) {
  if (!data || typeof data !== "object") {
    console.warn("⚠️ updateBoxesFromVars: invalid data");
    return;
  }

  const safeJSON = (obj) => {
    try {
      return JSON.stringify(obj ?? {}, null, 2);
    } catch {
      return "{}";
    }
  };

  document.getElementById("bucketBox").value = safeJSON(data.bucket);
  document.getElementById("cupBox").value = safeJSON(data.cup);
  document.getElementById("boardBox").value = safeJSON(data.board);
  console.log("✅ Boxes updated from provided data object");
}

function updateVarsFromBoxes() {
  try {
    bucket = JSON.parse(document.getElementById("bucketBox").value);
  } catch (e) {
    bucket = {};
  }
  try {
    cup = JSON.parse(document.getElementById("cupBox").value);
  } catch (e) {
    cup = {};
  }
  try {
    board = JSON.parse(document.getElementById("boardBox").value);
  } catch (e) {
    board = {};
  }
}

// Core Data Load/Save
function loadVarsIntoBoxes() {
  updateBoxesFromVars();
  console.log("📥 Loaded variables into boxes.");
}

function loadBoxesIntoVars() {
  updateVarsFromBoxes();
  console.log("📤 Loaded boxes into variables.");
}
async function saveToServer(id) {
  return await saveToServerM(id);
}
async function saveToServerM(id) {
  if (!navigator.onLine) {
    console.warn("⚠️ Offline — cannot save to server");
    return;
  }
  if (!id) {
    console.warn("⚠️ ID is required");
    return;
  }

  const payload = { data: { id, name: id } };

  // Use in-memory variables directly
  if (typeof bucket !== "undefined")
    payload.data.bucket = JSON.stringify(bucket);
  if (typeof cup !== "undefined") payload.data.cup = JSON.stringify(cup);
  if (typeof board !== "undefined") payload.data.board = JSON.stringify(board);

  if (!payload.data.bucket && !payload.data.cup && !payload.data.board) {
    alert("❌ Nothing valid to save");
    return;
  }

  const bodyString = JSON.stringify(payload);
  const bodySize = new Blob([bodyString]).size;
  console.log(`📤 JSON body size: ${bodySize} bytes`);

  try {
    const startTime = Date.now();
    const response = await fetch("https://j.kunok.com/api62.php", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: bodyString,
    });

    const text = await response.text();
    if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);
    console.log(`✅ Save completed in ${Date.now() - startTime}ms`);
    alert("✅ Partial save success (valid parts only)");
  } catch (e) {
    console.error("❌ Save failed:", e.message);
    alert("❌ Save failed: " + e.message);
  }
}
async function saveToServer(id) {
  if (!navigator.onLine) {
    console.warn("⚠️ Offline — cannot save to server");
    return;
  }
  if (!id) {
    console.warn("⚠️ ID is required");
    return;
  }

  const payload = { data: { id, name: id } };
  const parseBox = (id, name) => {
    const val = document.getElementById(id).value;
    if (!val.trim()) {
      console.warn(`⚠️ Skipping ${name}: empty`);
      return null;
    }
    try {
      return JSON.parse(val);
    } catch (e) {
      console.warn(`⚠️ Skipping ${name}: invalid JSON`);
      return null;
    }
  };

  const parsedBucket = parseBox("bucketBox", "bucket");
  const parsedCup = parseBox("cupBox", "cup");
  const parsedBoard = parseBox("boardBox", "board");

  if (parsedBucket) payload.data.bucket = JSON.stringify(parsedBucket);
  if (parsedCup) payload.data.cup = JSON.stringify(parsedCup);
  if (parsedBoard) payload.data.board = JSON.stringify(parsedBoard);

  if (!payload.data.bucket && !payload.data.cup && !payload.data.board) {
    alert("❌ Nothing valid to save");
    return;
  }

  const bodyString = JSON.stringify(payload);
  const bodySize = new Blob([bodyString]).size;
  console.log(`📤 JSON body size: ${bodySize} bytes`);

  try {
    const startTime = Date.now();
    const response = await fetch("https://j.kunok.com/api62.php", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: bodyString,
    });

    const text = await response.text();
    if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);
    console.log(`✅ Save completed in ${Date.now() - startTime}ms`);
    alert("✅ Partial save success (valid parts only)");
  } catch (e) {
    console.error("❌ Save failed:", e.message);
    alert("❌ Save failed: " + e.message);
  }
}

async function loadFromServer(id) {
  if (!navigator.onLine) {
    console.warn("⚠️ Offline — cannot load from server");
    return;
  }
  if (!id) {
    console.warn("⚠️ ID is required");
    return;
  }

  const url = `https://j.kunok.com/api62.php?id=${encodeURIComponent(id)}`;
  console.log("🚀 Start: load from server");

  try {
    const startTime = Date.now();
    const response = await fetch(url);
    const text = await response.text();
    if (!response.ok) throw new Error(`HTTP ${response.status}: ${text}`);

    const json = JSON.parse(text);
    const data = json?.data;
    if (!data) {
      console.warn("⚠️ No 'data' field in response");
      return;
    }

    const tryParse = (str) => {
      try {
        return JSON.parse(str);
      } catch {
        return {};
      }
    };

    bucket = tryParse(data.bucket || "{}");
    cup = tryParse(data.cup || "{}");
    board = tryParse(data.board || "{}");

    updateBoxesFromVars();
    console.log(`✅ Load completed in ${Date.now() - startTime}ms`);
  } catch (e) {
    console.error("❌ Load failed:", e.message);
    alert("❌ Load failed: " + e.message);
  }
}
function saveToLocalStorageM() {
  try {
    localStorage.setItem("myApp_bucket", JSON.stringify(bucket));
    localStorage.setItem("myApp_cup", JSON.stringify(cup));
    localStorage.setItem("myApp_board", JSON.stringify(board));
    console.log("✅ Memory data saved to localStorage");
    alert("✅ Saved to localStorage from memory");
  } catch (e) {
    console.error("❌ Failed to save to localStorage:", e.message);
    alert("❌ Save failed: " + e.message);
  }
}

// Local Storage
function saveToLocalStorage() {
  localStorage.setItem(
    "myApp_bucket",
    document.getElementById("bucketBox").value,
  );
  localStorage.setItem("myApp_cup", document.getElementById("cupBox").value);
  localStorage.setItem(
    "myApp_board",
    document.getElementById("boardBox").value,
  );
  console.log("✅ Saved to localStorage");
  alert("✅ Saved to localStorage");
}
function loadFromLocalStorageM() {
  try {
    bucket = JSON.parse(localStorage.getItem("myApp_bucket") || "{}");
    cup = JSON.parse(localStorage.getItem("myApp_cup") || "{}");
    board = JSON.parse(localStorage.getItem("myApp_board") || "{}");
    updateBoxesFromVars(); // update UI view
    console.log("✅ Loaded memory from localStorage");
    //alert("✅ Loaded from localStorage into memory");
  } catch (e) {
    console.error("❌ Load from localStorage failed:", e.message);
    alert("❌ Load failed: " + e.message);
  }
}

function loadFromLocalStorage() {
  document.getElementById("bucketBox").value =
    localStorage.getItem("myApp_bucket") || "{}";
  document.getElementById("cupBox").value =
    localStorage.getItem("myApp_cup") || "{}";
  document.getElementById("boardBox").value =
    localStorage.getItem("myApp_board") || "{}";
  console.log("✅ Loaded from localStorage");
  alert("✅ Loaded from localStorage");
}

function clearLocalStorage() {
  localStorage.removeItem("myApp_bucket");
  localStorage.removeItem("myApp_cup");
  localStorage.removeItem("myApp_board");
  console.log("🗑️ LocalStorage cleared");
  alert("🗑️ LocalStorage cleared");
}

function clearData() {
  bucket = {};
  cup = {};
  board = {};
  console.log("🧼 Global data variables cleared");
  alert("🧼 Data variables cleared");
}

function clearBoxes() {
  document.getElementById("bucketBox").value = "";
  document.getElementById("cupBox").value = "";
  document.getElementById("boardBox").value = "";
  console.log("📦 Textboxes cleared");
  alert("📦 Boxes cleared");
}

// Export/Import via File
function downloadSessionAsFile() {
  const data = { bucket, cup, board };
  const blob = new Blob([JSON.stringify(data, null, 2)], {
    type: "application/json",
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = "session.json";
  a.click();
  URL.revokeObjectURL(url);
  console.log("💾 Session downloaded");
}

function uploadSessionFromFile(evt) {
  const file = evt.target.files[0];
  if (!file) return;

  const reader = new FileReader();
  reader.onload = function (e) {
    try {
      const json = JSON.parse(e.target.result);
      bucket = json.bucket || {};
      cup = json.cup || {};
      board = json.board || {};
      updateBoxesFromVars();
      console.log("📥 Session loaded from file");
      alert("✅ Session loaded from file");
    } catch (err) {
      console.error("❌ Failed to load file:", err.message);
      alert("❌ Invalid file: " + err.message);
    }
  };
  reader.readAsText(file);
}
function safeCompress(obj, label = "") {
  try {
    if (typeof LZString !== "undefined") {
      const json = JSON.stringify(obj || {});
      const compressed = LZString.compressToUTF16(json);
      console.log(
        `📦 Compressed ${label} (${json.length} → ${compressed.length})`,
      );
      return compressed;
    } else {
      console.warn(`⚠️ LZString not available — saving ${label} as plain JSON`);
      return JSON.stringify(obj || {});
    }
  } catch (e) {
    console.error(`❌ Compression failed for ${label}:`, e);
    return JSON.stringify(obj || {});
  }
}

function safeDecompress(str, label = "") {
  try {
    if (typeof LZString !== "undefined") {
      const json = LZString.decompressFromUTF16(str);
      return JSON.parse(json);
    } else {
      console.warn(
        `⚠️ LZString not available — reading ${label} as plain JSON`,
      );
      return JSON.parse(str);
    }
  } catch (e) {
    console.error(`❌ Decompression failed for ${label}:`, e);
    return {};
  }
}
async function saveCompressedM(id) {
  if (!navigator.onLine) {
    console.warn("⚠️ Offline — cannot save to server");
    return;
  }
  if (!id) {
    console.warn("⚠️ ID is required");
    return;
  }

  await loadLZStringScript(); // ensure LZString is loaded

  const payload = {
    data: {
      id,
      name: id,
      bucket: safeCompress(bucket, "bucket"),
      cup: safeCompress(cup, "cup"),
      board: safeCompress(board, "board"),
    },
  };

  const body = JSON.stringify(payload);
  const start = Date.now();

  try {
    const res = await fetch("https://j.kunok.com/api62.php", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body,
    });
    const text = await res.text();

    if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);
    console.log(`✅ Compressed save completed in ${Date.now() - start}ms`);
    alert("✅ Compressed data saved");
  } catch (e) {
    console.error("❌ Save failed:", e.message);
    alert("❌ Save failed: " + e.message);
  }
}

async function saveCompressed(id) {
  try {
    await loadLZStringScript();

    if (!navigator.onLine) {
      console.warn("⚠️ Offline — cannot save to server");
      return;
    }

    const payload = {
      data: {
        id,
        name: id,
        bucket: safeCompress(bucket, "bucket"),
        cup: safeCompress(cup, "cup"),
        board: safeCompress(board, "board"),
      },
    };

    const body = JSON.stringify(payload);
    console.log("🚀 Saving compressed data to server", payload);

    const start = Date.now();
    const res = await fetch("https://j.kunok.com/api62.php", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body,
    });

    const text = await res.text();
    if (!res.ok)
      throw new Error(`HTTP ${res.status}: ${text.slice(0, 100)}...`);

    const ms = Date.now() - start;
    console.log(`✅ Saved in ${ms}ms`);
    alert("✅ Compressed data saved to server");
  } catch (e) {
    console.error("❌ Save failed:", e.message);
    alert("❌ Save failed: " + e.message);
  }
}

async function loadCompressed(id) {
  try {
    await loadLZStringScript();

    if (!navigator.onLine) {
      console.warn("⚠️ Offline — cannot load from server");
      return;
    }

    const url = `https://j.kunok.com/api62.php?id=${encodeURIComponent(id)}`;
    console.log(`🚀 Loading from: ${url}`);

    const start = Date.now();
    const res = await fetch(url);
    const text = await res.text();

    if (!res.ok)
      throw new Error(`HTTP ${res.status}: ${text.slice(0, 100)}...`);

    const json = JSON.parse(text);
    const data = json?.data;
    if (!data) throw new Error("Missing 'data' field in response");

    bucket = safeDecompress(data.bucket || "{}", "bucket");
    cup = safeDecompress(data.cup || "{}", "cup");
    board = safeDecompress(data.board || "{}", "board");

    updateBoxesFromVars();

    const ms = Date.now() - start;
    console.log(`✅ Loaded and decompressed in ${ms}ms`);
    alert("✅ Compressed data loaded");
  } catch (e) {
    console.error("❌ Load failed:", e.message);
    alert("❌ Load failed: " + e.message);
  }
}

function loadLZStringScript() {
  return new Promise((resolve, reject) => {
    if (typeof LZString !== "undefined") {
      return resolve(); // Already loaded
    }
    const script = document.createElement("script");
    script.src =
      "https://cdn.jsdelivr.net/npm/lz-string@1.4.4/libs/lz-string.min.js";
    script.onload = () => {
      console.log("✅ LZString loaded");
      resolve();
    };
    script.onerror = () => reject(new Error("❌ Failed to load LZString"));
    document.head.appendChild(script);
  });
}
function logDataSizes({ bucket, cup, board }, label = "📦 Data Sizes") {
  const rawBucket = JSON.stringify(bucket || {});
  const rawCup = JSON.stringify(cup || {});
  const rawBoard = JSON.stringify(board || {});

  const compressedBucket =
    typeof LZString !== "undefined"
      ? LZString.compressToUTF16(rawBucket)
      : rawBucket;
  const compressedCup =
    typeof LZString !== "undefined" ? LZString.compressToUTF16(rawCup) : rawCup;
  const compressedBoard =
    typeof LZString !== "undefined"
      ? LZString.compressToUTF16(rawBoard)
      : rawBoard;

  const getByteLength = (str) => new Blob([str]).size;

  const rawTotal = rawBucket.length + rawCup.length + rawBoard.length;
  const compressedTotal =
    compressedBucket.length + compressedCup.length + compressedBoard.length;

  console.log(`\n=== ${label} ===`);
  console.log(
    `📦 bucket:    raw=${getByteLength(rawBucket)}B, compressed=${getByteLength(compressedBucket)}B`,
  );
  console.log(
    `🥤 cup:       raw=${getByteLength(rawCup)}B, compressed=${getByteLength(compressedCup)}B`,
  );
  console.log(
    `🧩 board:     raw=${getByteLength(rawBoard)}B, compressed=${getByteLength(compressedBoard)}B`,
  );
  console.log(
    `📊 total raw:        ${getByteLength(rawBucket + rawCup + rawBoard)} bytes`,
  );
  console.log(
    `📉 total compressed: ${getByteLength(compressedBucket + compressedCup + compressedBoard)} bytes`,
  );
}

// Debug
function consoleData(data) {
  console.log("📦 Console Data:", data);
}

function logDataSizes({ bucket, cup, board }, label = "📦 Data Sizes") {
  const rawBucket = JSON.stringify(bucket || {});
  const rawCup = JSON.stringify(cup || {});
  const rawBoard = JSON.stringify(board || {});

  const getByteLength = (str) => new Blob([str]).size;

  console.log(`\n=== ${label} ===`);
  console.log(`📦 bucket: ${getByteLength(rawBucket)}B`);
  console.log(`🥤 cup: ${getByteLength(rawCup)}B`);
  console.log(`🧩 board: ${getByteLength(rawBoard)}B`);
  console.log(
    `📊 total raw: ${getByteLength(rawBucket + rawCup + rawBoard)} bytes`,
  );
}

// Run init
document.addEventListener("DOMContentLoaded", updateBoxesFromVars);
