"use strict";

const test = require("node:test");
const assert = require("node:assert/strict");
const fs = require("node:fs");
const path = require("node:path");

const root = path.resolve(__dirname, "..", "..");
const app = fs.readFileSync(path.join(root, "Web", "app.js"), "utf8");

function functionSource(name, nextName) {
  const start = app.indexOf(`function ${name}(`);
  const end = app.indexOf(`function ${nextName}(`, start + 1);
  assert.ok(start >= 0 && end > start, `${name} must precede ${nextName}`);
  return app.slice(start, end).trim();
}

function recreateWith(stubs) {
  const source = functionSource(
    "recreatePlaylistEntryWithEnabled",
    "playlistEntryManualEditBlockReason");
  return new Function(
    "namedKrxThemeRestoreWorkflow",
    "namedNxtThemeRestoreWorkflow",
    "namedForeignStockRestoreWorkflow",
    "foreignIndexCandleRestoreWorkflow",
    "manualFinancialWorkflow",
    "manualListsWorkflow",
    `return (${source});`)(
      stubs.krx,
      stubs.nxt,
      stubs.foreignStock,
      stubs.foreignIndex,
      stubs.manualFinancial,
      stubs.manualLists);
}

function stubSet() {
  const recreate = label => (entry, enabled) => entry.trusted === label
    ? Object.freeze({ ...entry, enabled, retainedBrand: label })
    : null;
  return {
    krx: {
      isMaterializedEntry: entry => entry.trusted === "krx",
      withEnabled: recreate("krx")
    },
    nxt: {
      isMaterializedEntry: entry => entry.trusted === "nxt",
      withEnabled: recreate("nxt")
    },
    foreignStock: {
      source: "legacy-named-foreign-stock-workflow",
      withEnabled: recreate("foreign-stock")
    },
    foreignIndex: { withEnabled: recreate("foreign-index") },
    manualFinancial: { withEnabled: recreate("manual-financial") },
    manualLists: { withEnabled: recreate("manual-lists") }
  };
}

test("a frozen ordinary entry toggles through an immutable replacement", () => {
  const recreate = recreateWith(stubSet());
  const entry = Object.freeze({
    id: "ordinary",
    code: "5001",
    enabled: true,
    operator: Object.freeze({ source: "legacy-stock-workflow" })
  });

  const replacement = recreate(entry, false);
  assert.notEqual(replacement, entry);
  assert.equal(entry.enabled, true);
  assert.equal(replacement.enabled, false);
  assert.equal(replacement.id, entry.id);
});

test("every capability-branded entry delegates to its trust-preserving workflow", () => {
  const recreate = recreateWith(stubSet());
  const cases = [
    ["krx", { source: "legacy-theme-workflow", namedKrxRestore: {} }],
    ["nxt", { source: "legacy-theme-workflow", namedNxtRestore: {} }],
    ["foreign-stock", { source: "legacy-named-foreign-stock-workflow" }],
    ["foreign-index", { source: "legacy-foreign-index-candle-workflow" }],
    ["manual-financial", { source: "manual-financial-workflow" }],
    ["manual-lists", { source: "legacy-manual-lists-workflow" }]
  ];

  for (const [trusted, operator] of cases) {
    const entry = Object.freeze({ id: trusted, enabled: true, trusted, operator });
    const replacement = recreate(entry, false);
    assert.equal(replacement.retainedBrand, trusted);
    assert.equal(replacement.enabled, false);
    assert.equal(entry.enabled, true);
  }
});

test("a proof-shaped but unbranded named entry fails closed instead of becoming a plain clone", () => {
  const recreate = recreateWith(stubSet());
  const forgedKrx = Object.freeze({
    id: "forged-krx",
    enabled: true,
    operator: Object.freeze({
      source: "legacy-theme-workflow",
      namedKrxRestore: Object.freeze({ schemaVersion: 1 })
    })
  });
  assert.equal(recreate(forgedKrx, false), null);
});

test("checkbox, enabled-all and current-row paths never assign into playlist entries", () => {
  const render = functionSource("renderPlaylist", "selectPlaylistRow");
  const all = functionSource("toggleAllEntriesEnabled", "moveSelected");
  const current = functionSource("toggleCurrentEntryEnabled", "savePlaylist");

  assert.match(render, /replacePlaylistEntryEnabledAt\(index, checkbox\.checked\)/u);
  assert.match(render, /renderPlaylist\(\)/u);
  assert.match(all, /state\.playlist\.map\(item => recreatePlaylistEntryWithEnabled/u);
  assert.match(all, /replacements\.some\(item => !item\)/u);
  assert.match(current,
    /replacePlaylistEntryEnabledAt\(state\.currentIndex, item\.enabled === false\)/u);
  assert.doesNotMatch(`${render}\n${all}\n${current}`, /item\.enabled\s*=(?!=)/u);
});
