// Server-only: uses GITHUB_TOKEN, never called from client directly.
const BASE = "https://api.github.com";
const OWNER = process.env.GITHUB_OWNER;
const REPO = process.env.GITHUB_REPO;
const TOKEN = process.env.GITHUB_TOKEN;

function headers() {
  return {
    Authorization: `Bearer ${TOKEN}`,
    Accept: "application/vnd.github.v3+json",
    "X-GitHub-Api-Version": "2022-11-28",
  };
}

/** List contents of a directory path (empty string = root). */
export async function getContents(path = "") {
  const url = `${BASE}/repos/${OWNER}/${REPO}/contents/${encodeURIPath(path)}`;
  const res = await fetch(url, {
    headers: headers(),
    next: { revalidate: 30 },
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.message || `GitHub ${res.status}`);
  }
  return res.json();
}

/** Get a single file's decoded text content + metadata. */
export async function getFile(path) {
  const data = await getContents(path);
  if (Array.isArray(data)) throw new Error("Path is a directory, not a file");
  return {
    sha: data.sha,
    size: data.size,
    name: data.name,
    download_url: data.download_url,
    encoding: data.encoding,
    // content may be empty for files > 1 MB; use download_url instead
    content: data.content
      ? Buffer.from(data.content, "base64").toString("utf-8")
      : null,
  };
}

/** Create or update a text file. sha required for updates. */
export async function putFile(path, textContent, sha, message) {
  const url = `${BASE}/repos/${OWNER}/${REPO}/contents/${encodeURIPath(path)}`;
  const body = {
    message: message || `Update ${path}`,
    content: Buffer.from(textContent, "utf-8").toString("base64"),
    ...(sha ? { sha } : {}),
  };
  const res = await fetch(url, {
    method: "PUT",
    headers: { ...headers(), "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.message || `GitHub ${res.status}`);
  }
  return res.json();
}

/** Upload a binary file (pass content as base64 string). */
export async function putBinaryFile(path, base64Content, sha, message) {
  const url = `${BASE}/repos/${OWNER}/${REPO}/contents/${encodeURIPath(path)}`;
  const body = {
    message: message || `Upload ${path}`,
    content: base64Content,
    ...(sha ? { sha } : {}),
  };
  const res = await fetch(url, {
    method: "PUT",
    headers: { ...headers(), "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.message || `GitHub ${res.status}`);
  }
  return res.json();
}

/** Delete a file. sha is required by GitHub API. */
export async function deleteFile(path, sha, message) {
  const url = `${BASE}/repos/${OWNER}/${REPO}/contents/${encodeURIPath(path)}`;
  const body = {
    message: message || `Delete ${path}`,
    sha,
  };
  const res = await fetch(url, {
    method: "DELETE",
    headers: { ...headers(), "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  if (!res.ok) {
    const err = await res.json().catch(() => ({}));
    throw new Error(err.message || `GitHub ${res.status}`);
  }
  return res.json();
}

// Encode path segments but keep slashes
function encodeURIPath(path) {
  return path.split("/").map(encodeURIComponent).join("/");
}