"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var api_json_to_md_exports = {};
__export(api_json_to_md_exports, {
  apiJsonToMd: () => apiJsonToMd,
  collectReferencedTypesMd: () => collectReferencedTypesMd
});
module.exports = __toCommonJS(api_json_to_md_exports);
var import_api_extractor_model = require("@microsoft/api-extractor-model");
var import_typescript = __toESM(require("typescript"));
var import_fs = require("fs");
var import_path = require("path");
const EMPTY_CTX = { typeToSlug: /* @__PURE__ */ new Map(), currentSlug: void 0 };
const sourceOrderCache = /* @__PURE__ */ new Map();
const buildSourceOrderMap = (filePath) => {
  const cached = sourceOrderCache.get(filePath);
  if (cached) {
    return cached;
  }
  const map = /* @__PURE__ */ new Map();
  try {
    const text = (0, import_fs.readFileSync)(filePath, "utf-8");
    const sf = import_typescript.default.createSourceFile(filePath, text, import_typescript.default.ScriptTarget.Latest, true);
    sf.forEachChild((node) => {
      if (import_typescript.default.isInterfaceDeclaration(node)) {
        const order = [];
        for (const member of node.members) {
          if ((import_typescript.default.isPropertySignature(member) || import_typescript.default.isMethodSignature(member)) && member.name && import_typescript.default.isIdentifier(member.name)) {
            order.push(member.name.text);
          }
        }
        map.set(node.name.text, order);
      }
    });
  } catch {
  }
  sourceOrderCache.set(filePath, map);
  return map;
};
const getMemberOrderIndex = (iface, packageRoot) => {
  if (!packageRoot) {
    return null;
  }
  const fileUrlPath = iface.fileUrlPath;
  if (!fileUrlPath) {
    return null;
  }
  const sourceMap = buildSourceOrderMap((0, import_path.join)(packageRoot, fileUrlPath));
  const order = sourceMap.get(iface.name);
  if (!order) {
    return null;
  }
  return new Map(order.map((name, i) => [name, i]));
};
const apiJsonToMd = (apiJsonPath, sectionNames, hints = {}, typeToSlug = /* @__PURE__ */ new Map(), sectionToSlug = /* @__PURE__ */ new Map()) => {
  const model = new import_api_extractor_model.ApiModel();
  model.loadPackage(apiJsonPath);
  const entryPoint = model.packages[0]?.entryPoints[0];
  if (!entryPoint) {
    throw new Error(`No entry point found in ${apiJsonPath}`);
  }
  const packageRoot = (0, import_path.dirname)((0, import_path.dirname)(apiJsonPath));
  const result = {};
  for (const name of sectionNames) {
    const item = findApiItem(entryPoint.members, name);
    if (!item) {
      console.warn(`Warning: "${name}" not found in API model, skipping.`);
      continue;
    }
    const ctx = { typeToSlug, currentSlug: sectionToSlug.get(name) };
    result[name] = renderItem(item, entryPoint.members, hints[name], ctx, packageRoot);
  }
  return result;
};
const collectReferencedTypesMd = (apiJsonPath, rootNames, typeToSlug = /* @__PURE__ */ new Map(), ownerSlug = void 0) => {
  const model = new import_api_extractor_model.ApiModel();
  model.loadPackage(apiJsonPath);
  const entryPoint = model.packages[0]?.entryPoints[0];
  if (!entryPoint) {
    return { md: "", collectedNames: [] };
  }
  const seen = new Set(rootNames);
  const queue = [];
  const enqueue = (name) => {
    if (!seen.has(name)) {
      seen.add(name);
      queue.push(name);
    }
  };
  for (const name of rootNames) {
    const item = findApiItem(entryPoint.members, name);
    if (item && item.kind === import_api_extractor_model.ApiItemKind.Interface) {
      discoverReferencedTypes(item, entryPoint.members, enqueue);
    }
  }
  const ctx = { typeToSlug, currentSlug: ownerSlug };
  const sections = [];
  const collectedNames = [];
  while (queue.length > 0) {
    const name = queue.shift();
    const item = findApiItem(entryPoint.members, name);
    if (!item) {
      continue;
    }
    const heading = getTypeHeading(name);
    const body = renderItem(item, entryPoint.members, void 0, ctx);
    sections.push(`${heading}

${body}`);
    collectedNames.push(name);
    if (item.kind === import_api_extractor_model.ApiItemKind.Interface) {
      discoverReferencedTypes(item, entryPoint.members, enqueue);
    }
  }
  return { md: sections.join("\n\n"), collectedNames };
};
const discoverReferencedTypes = (iface, allMembers, enqueue) => {
  for (const baseName of getExtendsNames(iface)) {
    enqueue(baseName);
  }
  const visitInterface = (i) => {
    for (const member of i.members) {
      if (member.kind !== import_api_extractor_model.ApiItemKind.PropertySignature) {
        continue;
      }
      const prop = member;
      for (const token of prop.propertyTypeExcerpt.spannedTokens) {
        if (token.kind === import_api_extractor_model.ExcerptTokenKind.Reference) {
          const typeName = token.text.trim();
          if (typeName && !isPrimitiveOrBuiltin(typeName)) {
            enqueue(typeName);
          }
        }
      }
    }
  };
  visitInterface(iface);
  for (const heritageType of iface.extendsTypes) {
    const baseName = heritageType.excerpt.text.trim();
    const baseItem = findApiItem(allMembers, baseName);
    if (baseItem && baseItem.kind === import_api_extractor_model.ApiItemKind.Interface) {
      visitInterface(baseItem);
    }
  }
};
const PRIMITIVE_AND_BUILTIN = /* @__PURE__ */ new Set([
  "string",
  "number",
  "boolean",
  "void",
  "undefined",
  "null",
  "any",
  "unknown",
  "never",
  "object",
  "HTMLElement",
  "React.ReactNode",
  "ReactElement",
  "FC",
  "Promise"
]);
const isPrimitiveOrBuiltin = (name) => PRIMITIVE_AND_BUILTIN.has(name);
const getExtendsNames = (iface) => iface.extendsTypes.map((h) => h.excerpt.text.trim());
const getTypeHeading = (name) => `#### <span style="font-weight: 700;" class="rounded-lg border-[1px] border-blue-300 font-mono border-none bg-blue-100 px-2 py-1 leading-[18px] tracking-[0.0175em] font-bold text-slate-900">${name}</span>`;
const findApiItem = (members, name) => members.find(
  (m) => (m.kind === import_api_extractor_model.ApiItemKind.Interface || m.kind === import_api_extractor_model.ApiItemKind.TypeAlias) && m.name === name
);
const renderItem = (item, allMembers, hints, ctx = EMPTY_CTX, packageRoot) => {
  if (item.kind === import_api_extractor_model.ApiItemKind.Interface) {
    return renderInterface(item, allMembers, hints, ctx, packageRoot);
  }
  if (item.kind === import_api_extractor_model.ApiItemKind.TypeAlias) {
    return renderTypeAlias(item, allMembers, ctx);
  }
  return "";
};
const renderInterface = (iface, allMembers, _hints, ctx = EMPTY_CTX, packageRoot) => {
  const description = extractSummary(iface);
  const parts = [];
  if (description) {
    parts.push(description);
  }
  const extendsClause = iface.extendsTypes.length > 0 ? ` extends ${iface.extendsTypes.map((h) => {
    const name = h.excerpt.text.trim();
    return findApiItem(allMembers, name) ? typeLink(name, ctx.typeToSlug.get(name), ctx.currentSlug) : escapeHtml(name);
  }).join(", ")}` : "";
  parts.push(
    `<code class="font-mono text-sm"><span class="text-blue-700">interface</span> ${escapeHtml(iface.name)}${extendsClause}</code>`
  );
  const properties = collectProperties(iface, allMembers, ctx);
  const orderIndex = getMemberOrderIndex(iface, packageRoot);
  if (orderIndex) {
    const fallback = orderIndex.size;
    properties.sort((a, b) => {
      const ai = orderIndex.get(a.propName) ?? fallback;
      const bi = orderIndex.get(b.propName) ?? fallback;
      if (ai !== bi) {
        return ai - bi;
      }
      return a.propName.localeCompare(b.propName);
    });
  }
  const dlItems = properties.map((p) => {
    const optionalMark = p.isOptional ? '<span class="text-slate-400">?</span>' : "";
    const deprecatedStyle = p.isDeprecated ? ' style="opacity: 0.5;"' : "";
    const dt = `<dt${deprecatedStyle}><code><strong>${escapeHtml(p.propName)}</strong>${optionalMark}: ${p.typeHtml}</code></dt>`;
    const ddParts = [];
    if (p.isDeprecated && p.deprecatedText) {
      ddParts.push(`<p><em>Deprecated.</em> ${escapeHtml(p.deprecatedText)}</p>`);
    } else if (p.isDeprecated) {
      ddParts.push("<p><em>Deprecated.</em></p>");
    }
    if (p.summary) {
      ddParts.push(`<p>${escapeHtml(p.summary)}</p>`);
    }
    if (p.defaultValue) {
      ddParts.push(`<p>Default: <code>${escapeHtml(p.defaultValue)}</code></p>`);
    }
    const dd = ddParts.length > 0 ? `<dd>${ddParts.join("\n")}</dd>` : "<dd></dd>";
    const exampleBlock = p.examples ? `
</dl>

<div class="pl-4 border-l-2 border-slate-200 mb-4">

${p.examples}

</div>

<dl class="pl-4 border-l-2 border-slate-200">` : "";
    return `${dt}
${dd}${exampleBlock}`;
  });
  parts.push(`<dl class="pl-4 border-l-2 border-slate-200">
${dlItems.join("\n")}
</dl>`);
  return parts.join("\n\n");
};
const renderTypeAlias = (alias, allMembers, ctx = EMPTY_CTX) => {
  const description = extractSummary(alias);
  const typeTokens = alias.typeExcerpt?.spannedTokens ?? [];
  const parts = [];
  if (description) {
    parts.push(description);
  }
  if (typeTokens.length > 0) {
    const typeHtml = allMembers ? renderTypeExcerpt(typeTokens, allMembers, ctx.typeToSlug, ctx.currentSlug) : escapeHtml(alias.typeExcerpt?.text?.trim() ?? "");
    const code = `<span class="text-blue-700">type</span> ${escapeHtml(alias.name)} = ${typeHtml}`;
    parts.push(
      `<pre class="block py-4 px-4 my-2 overflow-auto rounded border-none bg-slate-200 font-mono text-sm leading-6 tracking-wide text-slate-900"><code>${code}</code></pre>`
    );
  }
  return parts.join("\n\n");
};
const collectProperties = (iface, allMembers, ctx) => {
  const rows = [];
  const seen = /* @__PURE__ */ new Set();
  addPropertiesFromInterface(iface, rows, seen, allMembers, ctx);
  for (const heritageType of iface.extendsTypes) {
    const baseName = heritageType.excerpt.text.trim();
    const baseItem = findApiItem(allMembers, baseName);
    if (baseItem && baseItem.kind === import_api_extractor_model.ApiItemKind.Interface) {
      addPropertiesFromInterface(baseItem, rows, seen, allMembers, ctx);
    }
  }
  return rows;
};
const addPropertiesFromInterface = (iface, rows, seen, allMembers, ctx) => {
  for (const member of iface.members) {
    if (member.kind !== import_api_extractor_model.ApiItemKind.PropertySignature && member.kind !== import_api_extractor_model.ApiItemKind.MethodSignature) {
      continue;
    }
    const prop = member;
    if (seen.has(prop.name)) {
      continue;
    }
    seen.add(prop.name);
    const isDeprecated = !!prop.tsdocComment?.deprecatedBlock;
    const summary = extractSummary(prop);
    const deprecatedText = extractDeprecatedText(prop);
    const defaultValue = extractDefaultValue(prop);
    const examples = extractExamples(prop);
    let isOptional;
    let typeHtml;
    if (member.kind === import_api_extractor_model.ApiItemKind.PropertySignature) {
      const propSig = member;
      isOptional = propSig.isOptional;
      typeHtml = renderTypeExcerpt(
        propSig.propertyTypeExcerpt.spannedTokens,
        allMembers,
        ctx.typeToSlug,
        ctx.currentSlug
      );
    } else {
      const methodSig = member;
      isOptional = methodSig.isOptional;
      const excerpt = methodSig.excerpt.text.trim();
      const sigStart = excerpt.indexOf("(");
      typeHtml = sigStart >= 0 ? escapeHtml(excerpt.slice(sigStart)) : escapeHtml(excerpt);
    }
    rows.push({
      propName: prop.name,
      isOptional,
      isDeprecated,
      deprecatedText,
      typeHtml,
      summary,
      defaultValue,
      examples
    });
  }
};
const extractSummary = (item) => {
  if (!("tsdocComment" in item)) {
    return "";
  }
  const comment = item.tsdocComment;
  if (!comment?.summarySection) {
    return "";
  }
  return renderDocNodes(comment.summarySection.nodes).trim();
};
const extractDeprecatedText = (item) => {
  if (!("tsdocComment" in item)) {
    return "";
  }
  const comment = item.tsdocComment;
  if (!comment?.deprecatedBlock?.content) {
    return "";
  }
  return renderDocNodes(comment.deprecatedBlock.content.nodes).trim();
};
const extractExamples = (item) => {
  if (!("tsdocComment" in item)) {
    return "";
  }
  const comment = item.tsdocComment;
  if (!comment?.customBlocks) {
    return "";
  }
  const blocks = [];
  for (const block of comment.customBlocks) {
    if (block.blockTag?.tagName !== "@example" || !block.content) {
      continue;
    }
    for (const node of block.content.nodes) {
      if (node.kind === "FencedCode") {
        const fc = node;
        const code = (fc.code ?? "").replace(/\n+$/, "");
        if (code) {
          blocks.push(`\`\`\`tsx widget
${code}
\`\`\``);
        }
      }
    }
  }
  return blocks.join("\n\n");
};
const extractDefaultValue = (item) => {
  if (!("tsdocComment" in item)) {
    return "";
  }
  const comment = item.tsdocComment;
  if (!comment?.customBlocks) {
    return "";
  }
  for (const block of comment.customBlocks) {
    if (block.blockTag?.tagName === "@defaultValue" && block.content) {
      return renderDocNodes(block.content.nodes).trim();
    }
  }
  return "";
};
const renderDocNodes = (nodes) => {
  let text = "";
  for (const node of nodes) {
    if (node.kind === "PlainText") {
      text += node.text;
    } else if (node.kind === "SoftBreak") {
      text += " ";
    } else if (node.kind === "Paragraph" || node.kind === "Section") {
      text += renderDocNodes(node.nodes);
    } else if (node.kind === "CodeSpan") {
      text += `\`${node.code ?? ""}\``;
    } else if (node.kind === "FencedCode") {
      const fc = node;
      text += `

\`\`\`${fc.language ?? "tsx"}
${(fc.code ?? "").replace(/\n+$/, "")}
\`\`\`

`;
    } else if (node.kind === "LinkTag") {
      const linkTag = node;
      text += linkTag.linkText ?? linkTag.urlDestination ?? "";
    }
  }
  return text;
};
const anchorOf = (name) => name.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-");
const typeLink = (title, targetSlug, currentSlug) => {
  const anchor = anchorOf(title);
  const href = !targetSlug || targetSlug === currentSlug ? `#${anchor}` : `/api-docs/${targetSlug}#${anchor}`;
  return `<a href="${href}"><span class="font-mono">${title}</span></a>`;
};
const renderTypeExcerpt = (tokens, allMembers, typeToSlug, currentSlug) => tokens.map((token) => {
  if (token.kind === import_api_extractor_model.ExcerptTokenKind.Reference) {
    const name = token.text.trim();
    if (name && !isPrimitiveOrBuiltin(name) && findApiItem(allMembers, name)) {
      return typeLink(name, typeToSlug.get(name), currentSlug);
    }
  }
  return escapeHtml(token.text);
}).join("");
const escapeHtml = (text) => text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, " ");
//# sourceMappingURL=api-json-to-md.js.map
