import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import path from "node:path";

const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const detailSource = readFileSync(
  path.resolve(scriptDir, "../src/pages/instances/InstanceDetailPage.tsx"),
  "utf8",
);
const frameSource = readFileSync(
  path.resolve(scriptDir, "../src/components/InstanceServiceFrame.tsx"),
  "utf8",
);

function assert(condition, message) {
  if (!condition) {
    throw new Error(message);
  }
}

assert(
  detailSource.includes("isDedicatedInstance") &&
    detailSource.includes('instance.instance_mode === "pro"') &&
    detailSource.includes('instance.runtime_type !== "gateway"'),
  "Instance detail page must branch pro/desktop instances away from the lite workspace layout.",
);

for (const label of ["Runtime Overview", "Runtime Events", "Instance Skills"]) {
  assert(detailSource.includes(label), `Pro instance detail section missing: ${label}`);
}

for (const api of ["getRuntimeDetails", "listInstanceSkills", "attachSkillToInstance", "removeSkillFromInstance"]) {
  assert(detailSource.includes(api), `Pro instance detail page must use ${api}.`);
}

assert(
  detailSource.includes("renderLiteWorkspace") && detailSource.includes("renderProWorkspace"),
  "Instance detail page must keep separate lite and pro render paths.",
);

function sliceBetween(source, startMarker, endMarker) {
  const start = source.indexOf(startMarker);
  assert(start >= 0, `Missing marker: ${startMarker}`);
  const end = source.indexOf(endMarker, start);
  assert(end > start, `Missing end marker after: ${startMarker}`);
  return source.slice(start, end);
}

const proRender = sliceBetween(
  detailSource,
  "const renderProWorkspace = () => (",
  "\n  return (",
);

assert(
  proRender.includes("shareLinkControl"),
  "Pro instance detail must place Share Link with the primary instance action buttons.",
);

assert(
  !detailSource.includes("externalAccessSection") && !detailSource.includes("externalAccessCompact"),
  "Instance detail must not render the old full-width or inline external access controls.",
);

assert(
  detailSource.includes('data-panel="share-link-popover"') &&
    detailSource.includes("Share link expiration") &&
    detailSource.includes("Create Password"),
  "Share link expiration and password controls must live inside the Share Link popover.",
);

assert(
  proRender.includes('data-section="runtime-overview"') &&
    proRender.indexOf("Instance Skills") < proRender.indexOf("Runtime Overview"),
  "Instance Skills must render before the compact Runtime Overview card.",
);

assert(
  !proRender.includes("Resource Monitor") && !proRender.includes("Runtime Status"),
  "Runtime Overview must use a compact summary instead of large nested Resource Monitor and Runtime Status sections.",
);

assert(
  proRender.includes('initialPath="/config"'),
  "Pro instance workspace must open at /config.",
);

assert(
  proRender.includes("pro-desktop-workspace"),
  "Pro instance workspace must be placed in the desktop workspace area.",
);

assert(
  !proRender.includes("h-[560px]") &&
    (proRender.includes("aspect-video") || proRender.includes("aspect-[16/9]")),
  "Pro desktop frame must use a stable 16:9 desktop ratio instead of the old fixed height.",
);

assert(
  proRender.indexOf("Runtime Events") > proRender.indexOf("Runtime Overview"),
  "Runtime Events must be lower priority and render after Instance Skills.",
);

assert(
  frameSource.includes("requestFullscreen") &&
    frameSource.includes("Maximize2") &&
    frameSource.includes("Minimize2"),
  "Instance service frame must expose a fullscreen control.",
);

console.log("Instance detail pro layout contract is valid.");
