import { join } from "node:path";
import { writeGeneratedFile } from "./write-generated-file.js";
export async function generateServicesDts(rootDir, entries, options = {}) {
    const filePath = join(rootDir, "src", "types", "generated", "services.generated.d.ts");
    const tree = createServiceTree(entries);
    const body = renderServiceTree(tree, 2);
    const content = [
        "// Auto-generated by vext typegen (experimental). DO NOT EDIT.",
        "",
        'import "vextjs";',
        "",
        'declare module "vextjs" {',
        "  interface VextServices {",
        body || "",
        "  }",
        "}",
        "",
    ]
        .filter((line, index, arr) => !(line === "" && arr[index - 1] === ""))
        .join("\n");
    return writeGeneratedFile(filePath, content, options);
}
function createServiceTree(entries) {
    const root = { children: new Map() };
    for (const entry of entries) {
        let current = root;
        for (const segment of entry.keySegments) {
            let next = current.children.get(segment);
            if (!next) {
                next = { children: new Map() };
                current.children.set(segment, next);
            }
            current = next;
        }
        current.typeText = `import("${entry.importPath}").default`;
    }
    return root;
}
function renderServiceTree(node, indentLevel) {
    const indent = "  ".repeat(indentLevel);
    const lines = [];
    for (const [key, child] of [...node.children.entries()].sort(([a], [b]) => a.localeCompare(b))) {
        const hasChildren = child.children.size > 0;
        if (child.typeText && !hasChildren) {
            lines.push(`${indent}${key}: ${child.typeText};`);
            continue;
        }
        if (hasChildren && !child.typeText) {
            lines.push(`${indent}${key}: {`);
            lines.push(renderServiceTree(child, indentLevel + 1));
            lines.push(`${indent}};`);
            continue;
        }
        if (child.typeText && hasChildren) {
            lines.push(`${indent}${key}: ${child.typeText} & {`);
            lines.push(renderServiceTree(child, indentLevel + 1));
            lines.push(`${indent}};`);
        }
    }
    return lines.join("\n");
}
