import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
import { join } from "node:path";

const version = "0.8.8";

const dependencyGroups = [
  "dependencies",
  "devDependencies",
  "peerDependencies",
  "optionalDependencies",
];

const rootPackageFile = "package.json";
const rootPackage = JSON.parse(readFileSync(rootPackageFile, "utf8"));
rootPackage.version = version;
writeFileSync(rootPackageFile, `${JSON.stringify(rootPackage, null, 2)}\n`);

for (const entry of readdirSync("packages", {
  withFileTypes: true,
})) {
  if (!entry.isDirectory()) {
    continue;
  }

  const packageFile = join("packages", entry.name, "package.json");

  if (!existsSync(packageFile)) {
    continue;
  }

  const packageJson = JSON.parse(readFileSync(packageFile, "utf8"));

  packageJson.version = version;

  for (const group of dependencyGroups) {
    const dependencies = packageJson[group];

    if (!dependencies || typeof dependencies !== "object") {
      continue;
    }

    for (const dependencyName of Object.keys(dependencies)) {
      if (!dependencyName.startsWith("@wrnexus/")) {
        continue;
      }

      const currentVersion = dependencies[dependencyName];

      if (typeof currentVersion !== "string") {
        continue;
      }

      if (currentVersion.startsWith("workspace:")) {
        continue;
      }

      if (currentVersion.startsWith("^")) {
        dependencies[dependencyName] = `^${version}`;
      } else if (currentVersion.startsWith("~")) {
        dependencies[dependencyName] = `~${version}`;
      } else {
        dependencies[dependencyName] = version;
      }
    }
  }

  writeFileSync(packageFile, `${JSON.stringify(packageJson, null, 2)}\n`);
}

const editorPackageFile = join("editors", "vscode", "package.json");
if (existsSync(editorPackageFile)) {
  const editorPackage = JSON.parse(readFileSync(editorPackageFile, "utf8"));
  editorPackage.version = version;
  writeFileSync(editorPackageFile, `${JSON.stringify(editorPackage, null, 2)}\n`);
}

const editorLockFile = join("editors", "vscode", "package-lock.json");
if (existsSync(editorLockFile)) {
  const editorLock = JSON.parse(readFileSync(editorLockFile, "utf8"));
  editorLock.version = version;
  if (editorLock.packages?.[""]) editorLock.packages[""].version = version;
  writeFileSync(editorLockFile, `${JSON.stringify(editorLock, null, 2)}\n`);
}

const bunLockFile = "bun.lock";
if (existsSync(bunLockFile)) {
  let currentWorkspace = "";
  const lines = readFileSync(bunLockFile, "utf8").split(/(?<=\n)/);
  const updated = lines.map((line) => {
    const workspace = /^ {4}"([^"]+)": \{\r?\n?$/.exec(line)?.[1];
    if (workspace) currentWorkspace = workspace;
    if (currentWorkspace.startsWith("packages/") && /^ {6}"version": "[^"]+",\r?\n?$/.test(line)) {
      const newline = line.endsWith("\r\n") ? "\r\n" : line.endsWith("\n") ? "\n" : "";
      return `      "version": "${version}",${newline}`;
    }
    if (/^ {4}\},?\r?\n?$/.test(line)) currentWorkspace = "";
    return line;
  });
  writeFileSync(bunLockFile, updated.join(""));
}
