/**
 * Renders the API-reference section of the system prompt: platform header,
 * filtered interface/type declarations from the host's API spec, and the
 * client-specific addendum.
 */
import { AgentExecuteCodeMode } from '../../contracts/agent-execute-code.js';
const EXCEL_HEADER = `PLATFORM: Microsoft Excel Add-in (Office.js)

To use raw Office.js APIs, wrap in Excel.run:

await Excel.run(async (context) => {
  const sheet = context.workbook.worksheets.getActiveWorksheet();
  sheet.load("name");
  await context.sync();
  console.log("Active sheet:", sheet.name);
});

Key patterns:
- Use \`context.workbook\` to access worksheets, names, etc.
- Batch multiple loads before a single sync for performance
- Sizes (row height, column width) are in points (pt), not pixels
- Excel's RichApi rejects array literals \`{...}\` that contain cell references in formulas.
  FAILS:  =IRR({-D17,0,0,H180})     — cell refs inside array literal
  FAILS:  =SMALL({A1,B1,C1},2)      — cell refs inside array literal
  WORKS:  =IRR({-100,0,0,500})      — only literal constants
  WORKS:  =IRR(A1:A4)               — contiguous range reference
When you need IRR/XIRR/SMALL/QUARTILE with non-contiguous cells, write the values
to a contiguous helper range first, then reference that range in the formula.`;
const WEB_HEADER = `PLATFORM: SpreadJS Web Application

To use raw SpreadJS APIs, access the underlying objects:

const rawWs = sheet.originalSheet;          // GC.Spread.Sheets.Worksheet
const rawWb = workbook.originalWorkbook;  // GC.Spread.Sheets.Workbook

// Example: get cell value
console.log(rawWs.getValue(0, 0)); // row 0, col 0

Key patterns:
- The \`GC\` namespace is available globally for enums and constants
- Sizes (row height, column width) are in pixels (px)`;
const SHEETS_HEADER = `PLATFORM: Google Sheets Add-on (Apps Script)

You are running in Google Sheets through the Shortcut add-on. Use the wrapped
\`workbook\`, \`sheet\`, and \`general\` APIs from the API reference below.
`;
function isObjectRecord(value) {
    return value != null && typeof value === 'object';
}
function isPromptMetadata(value) {
    return isObjectRecord(value);
}
function shouldIncludeItem(itemInfo, filterTags) {
    const itemTags = new Set(itemInfo?.tags ?? []);
    if (itemTags.size === 0) {
        return true;
    }
    if (filterTags == null) {
        return true;
    }
    for (const tag of itemTags) {
        if (filterTags.has(tag)) {
            return true;
        }
    }
    return false;
}
function generateInterface(interfaceName, interfaceInfo, filterTags) {
    const functions = interfaceInfo.functions ?? {};
    const filteredFunctions = Object.entries(functions).filter(([, info]) => {
        return (isObjectRecord(info) &&
            typeof info.signature === 'string' &&
            shouldIncludeItem(info, filterTags));
    });
    if (filteredFunctions.length === 0) {
        return null;
    }
    const lines = [];
    const usedTypes = new Set();
    if (interfaceInfo.docstring) {
        lines.push('/**');
        for (const docLine of interfaceInfo.docstring.split('\n')) {
            lines.push(docLine ? ` * ${docLine}` : ' *');
        }
        lines.push(' */');
    }
    lines.push(`export interface ${interfaceName} {`);
    for (const [, funcInfo] of filteredFunctions) {
        if (funcInfo.docstring) {
            lines.push('  /**');
            for (const docLine of funcInfo.docstring.split('\n')) {
                lines.push(docLine ? `   * ${docLine}` : '   *');
            }
            lines.push('   */');
        }
        const signatureLines = funcInfo.signature.split('\n');
        if (signatureLines.length === 1) {
            lines.push(`  ${signatureLines[0]}`);
        }
        else {
            lines.push(`  ${signatureLines[0]}`);
            for (const signatureLine of signatureLines.slice(1)) {
                lines.push(`  ${signatureLine}`);
            }
        }
        lines.push('');
        for (const typeName of funcInfo.usedTypes ?? []) {
            usedTypes.add(typeName);
        }
    }
    lines.push('}');
    return { code: lines.join('\n'), usedTypes };
}
function generateEnum(typeName, typeInfo) {
    const lines = [];
    if (typeInfo.docstring) {
        lines.push('/**');
        lines.push(` * ${typeInfo.docstring}`);
        lines.push(' */');
    }
    lines.push(`export enum ${typeName} {`);
    const values = Object.entries(typeInfo.values ?? {});
    values.forEach(([key, rawValue], index) => {
        const separator = index < values.length - 1 ? ',' : '';
        const commentIndex = rawValue.indexOf('//');
        if (commentIndex >= 0) {
            const value = rawValue.slice(0, commentIndex).trim();
            const comment = rawValue.slice(commentIndex);
            lines.push(`  ${key} = ${value}${separator} ${comment}`.trimEnd());
            return;
        }
        lines.push(`  ${key} = ${rawValue}${separator}`);
    });
    lines.push('}');
    return lines.join('\n');
}
function generateTypeAlias(typeName, typeInfo) {
    const lines = [];
    if (typeInfo.docstring) {
        lines.push('/**');
        lines.push(` * ${typeInfo.docstring}`);
        lines.push(' */');
    }
    lines.push(`export type ${typeName} = ${typeInfo.definition ?? ''};`);
    return lines.join('\n');
}
function generateApiReference(apiSpec, filterTags) {
    if (!isPromptMetadata(apiSpec)) {
        return '';
    }
    const sections = [];
    const usedTypes = new Set();
    const interfaces = apiSpec.interfaces ?? {};
    const types = apiSpec.types ?? {};
    for (const [interfaceName, interfaceValue] of Object.entries(interfaces)) {
        if (!isObjectRecord(interfaceValue) || !shouldIncludeItem(interfaceValue, filterTags)) {
            continue;
        }
        const generated = generateInterface(interfaceName, interfaceValue, filterTags);
        if (!generated) {
            continue;
        }
        sections.push(generated.code);
        for (const typeName of generated.usedTypes) {
            if (types[typeName]) {
                usedTypes.add(typeName);
            }
        }
    }
    for (const [typeName, typeValue] of Object.entries(types)) {
        if (!usedTypes.has(typeName) || !isObjectRecord(typeValue)) {
            continue;
        }
        sections.push(typeValue.isEnum
            ? generateEnum(typeName, typeValue)
            : generateTypeAlias(typeName, typeValue));
    }
    return sections.join('\n\n');
}
function assertNeverPlatform(value) {
    throw new Error(`Unhandled ShortcutXL prompt platform: ${String(value)}`);
}
function getPlatformHeader(platformName) {
    switch (platformName) {
        case 'web':
            return WEB_HEADER;
        case 'sheets':
            return SHEETS_HEADER;
        case 'plugin':
            return EXCEL_HEADER;
    }
    return assertNeverPlatform(platformName);
}
function getFilterTags(mode) {
    return mode === AgentExecuteCodeMode.Action ? new Set(['action']) : new Set(['ask']);
}
const READ_ONLY_API_PREAMBLE = `\
You can write Typescript code that reads from the excel workbook based on the below API using the execute_code tool.
Execute code as many times as needed to fully understand the data before answering.`;
/** Build the `# 🔧 API REFERENCE` block. Action: bare. Ask/plan: `(READ-ONLY)` heading + read-only preamble. */
export function buildShortcutXLApiReferenceSection(options) {
    const apiReference = generateApiReference(options.apiSpec, getFilterTags(options.mode));
    const platformHeader = getPlatformHeader(options.platformName);
    const isAction = options.mode === AgentExecuteCodeMode.Action;
    const heading = isAction ? '# 🔧 API REFERENCE' : '# 🔧 API REFERENCE (READ-ONLY)';
    const sections = [
        isAction ? '' : READ_ONLY_API_PREAMBLE,
        `/*\n${platformHeader}\n*/`,
        apiReference,
        options.clientSpecificPrompt.trim()
    ].filter((section) => section.length > 0);
    return `\
======================
${heading}
======================

${sections.join('\n\n')}`.trim();
}
/**
 * Convenience helper for subagent prompt builders. Takes a prompt
 * platform + a read-only flag and returns the full `# API REFERENCE`
 * block for the matching API filter (ask vs action) and host (web vs
 * plugin). Subagents append this to their static prompt body.
 */
export function buildSubagentApiReferenceSection(platform, spreadsheetReadOnly) {
    return buildShortcutXLApiReferenceSection({
        apiSpec: platform.getApiSpec(),
        clientSpecificPrompt: platform.getClientSpecificPrompt(),
        mode: spreadsheetReadOnly ? AgentExecuteCodeMode.Ask : AgentExecuteCodeMode.Action,
        platformName: platform.name
    });
}
//# sourceMappingURL=api-reference.js.map