import { basename } from "node:path";
import { extractInsightParam, paramStr, typeStr } from "./agent/ui-utils.mjs";
import { ScreenshotItem } from "./screenshot-item.mjs";
import { normalizeScreenshotRef } from "./dump/screenshot-store.mjs";
function toExecutionDump(execution) {
    if (!execution || 'object' != typeof execution) throw new Error('executionToMarkdown: execution is required');
    if (!Array.isArray(execution.tasks)) throw new Error('executionToMarkdown: execution.tasks must be an array');
    if (!execution.name) throw new Error('executionToMarkdown: execution.name is required');
    return execution;
}
function toReportDump(report) {
    if (!report || 'object' != typeof report) throw new Error('reportToMarkdown: report is required');
    if (!Array.isArray(report.executions)) throw new Error('reportToMarkdown: report.executions must be an array');
    return report;
}
function formatTime(ts) {
    if ('number' != typeof ts || Number.isNaN(ts)) return 'N/A';
    return new Date(ts).toISOString();
}
function resolveTaskTiming(task) {
    const timing = task.timing;
    if (!timing) return {};
    const start = timing.start ?? timing.callAiStart ?? timing.callActionStart;
    const end = timing.end ?? timing.callAiEnd ?? timing.callActionEnd ?? timing.captureAfterCallingSnapshotEnd;
    const cost = timing.cost ?? ('number' == typeof start && 'number' == typeof end ? end - start : void 0);
    return {
        start,
        end,
        cost
    };
}
function safeTaskParam(task) {
    const readable = paramStr(task);
    if (readable) return readable;
    if ('Insight' === task.type) return extractInsightParam(task.param).content;
    return '';
}
function formatSize(size) {
    if (!size || 'number' != typeof size.width || 'number' != typeof size.height || Number.isNaN(size.width) || Number.isNaN(size.height)) return;
    return `${size.width} x ${size.height}`;
}
function extractLocateCenter(task) {
    const outputCenter = task.output?.element?.center;
    if (Array.isArray(outputCenter) && outputCenter.length >= 2 && 'number' == typeof outputCenter[0] && 'number' == typeof outputCenter[1]) return [
        outputCenter[0],
        outputCenter[1]
    ];
    const paramLocateCenter = task.param?.locate?.center;
    if (Array.isArray(paramLocateCenter) && paramLocateCenter.length >= 2 && 'number' == typeof paramLocateCenter[0] && 'number' == typeof paramLocateCenter[1]) return [
        paramLocateCenter[0],
        paramLocateCenter[1]
    ];
    const paramCenter = task.param?.center;
    if (Array.isArray(paramCenter) && paramCenter.length >= 2 && 'number' == typeof paramCenter[0] && 'number' == typeof paramCenter[1]) return [
        paramCenter[0],
        paramCenter[1]
    ];
}
function tryExtractBase64(screenshot) {
    if (!screenshot || 'object' != typeof screenshot) return;
    const s = screenshot;
    if ('string' == typeof s.base64 && s.base64.length > 0) return s.base64;
}
function screenshotAttachment(screenshot, screenshotBaseDir, executionIndex, taskIndex) {
    if (screenshot instanceof ScreenshotItem) {
        const ext = screenshot.extension;
        const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${screenshot.id}.${ext}`;
        return {
            markdown: `\n![task-${taskIndex + 1}](${screenshotBaseDir}/${suggestedFileName})`,
            attachment: {
                id: screenshot.id,
                suggestedFileName,
                mimeType: `image/${'jpeg' === ext ? 'jpeg' : 'png'}`,
                executionIndex,
                taskIndex,
                base64Data: tryExtractBase64(screenshot)
            }
        };
    }
    const ref = normalizeScreenshotRef(screenshot);
    if (ref) {
        const ext = 'image/jpeg' === ref.mimeType ? 'jpeg' : 'png';
        const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${ref.id}.${ext}`;
        return {
            markdown: `\n![task-${taskIndex + 1}](${screenshotBaseDir}/${suggestedFileName})`,
            attachment: {
                id: ref.id,
                suggestedFileName,
                sourceRef: ref,
                mimeType: ref.mimeType,
                executionIndex,
                taskIndex,
                base64Data: tryExtractBase64(screenshot)
            }
        };
    }
    const base64 = tryExtractBase64(screenshot);
    if (base64) {
        const ext = base64.startsWith('data:image/jpeg') ? 'jpeg' : 'png';
        const id = `restored-${executionIndex + 1}-${taskIndex + 1}`;
        const suggestedFileName = `execution-${executionIndex + 1}-task-${taskIndex + 1}-${id}.${ext}`;
        return {
            markdown: `\n![task-${taskIndex + 1}](${screenshotBaseDir}/${suggestedFileName})`,
            attachment: {
                id,
                suggestedFileName,
                mimeType: `image/${ext}`,
                executionIndex,
                taskIndex,
                base64Data: base64
            }
        };
    }
    throw new Error(`executionToMarkdown: missing screenshot for execution #${executionIndex + 1} task #${taskIndex + 1}`);
}
function recorderMarkdownSection(recorder, screenshotBaseDir, executionIndex, taskIndex) {
    if (!recorder?.length) return {
        lines: [],
        attachments: []
    };
    const lines = [
        '',
        '### Recorder'
    ];
    const attachments = [];
    recorder.forEach((item, recorderIndex)=>{
        lines.push(`- #${recorderIndex + 1} type=${item.type}, ts=${formatTime(item.ts)}, timing=${item.timing || 'N/A'}`);
        if (!item.screenshot) return;
        const imageResult = screenshotAttachment(item.screenshot, screenshotBaseDir, executionIndex, taskIndex);
        lines.push(imageResult.markdown);
        attachments.push(imageResult.attachment);
    });
    return {
        lines,
        attachments
    };
}
function renderExecution(executionRaw, executionIndex, options) {
    const execution = toExecutionDump(executionRaw);
    const screenshotBaseDir = options?.screenshotBaseDir ?? './screenshots';
    const lines = [];
    const attachments = [];
    lines.push(`# ${execution.name}`);
    if (execution.description) lines.push('', execution.description);
    lines.push('', `- Execution start: ${formatTime(execution.logTime)}`);
    lines.push(`- Task count: ${execution.tasks.length}`);
    execution.tasks.forEach((task, taskIndex)=>{
        const title = typeStr(task);
        const detail = safeTaskParam(task);
        const time = resolveTaskTiming(task);
        lines.push('', `## ${taskIndex + 1}. ${title}${detail ? ` - ${detail}` : ''}`);
        lines.push(`- Status: ${task.status || 'unknown'}`);
        lines.push(`- Start: ${formatTime(time.start)}`);
        lines.push(`- End: ${formatTime(time.end)}`);
        lines.push(`- Cost(ms): ${'number' == typeof time.cost ? time.cost : 'N/A'}`);
        lines.push(`- Screen size: ${formatSize(task.uiContext?.shotSize) || 'N/A'}`);
        if ('Locate' === task.subType) {
            const locateCenter = extractLocateCenter(task);
            if (locateCenter) lines.push(`- Locate center: (${locateCenter[0]}, ${locateCenter[1]})`);
        }
        if (task.errorMessage) lines.push(`- Error: ${task.errorMessage}`);
        if (task.uiContext?.screenshot) {
            const imageResult = screenshotAttachment(task.uiContext.screenshot, screenshotBaseDir, executionIndex, taskIndex);
            lines.push(imageResult.markdown);
            attachments.push(imageResult.attachment);
        }
        const recorderSection = recorderMarkdownSection(task.recorder, screenshotBaseDir, executionIndex, taskIndex);
        if (recorderSection.lines.length) {
            lines.push(...recorderSection.lines);
            attachments.push(...recorderSection.attachments);
        }
    });
    return {
        markdown: lines.join('\n'),
        attachments
    };
}
function reportFileName(execution, executionIndex) {
    const safeName = execution.name.trim().replace(/\s+/g, '-').replace(/[^a-zA-Z0-9-_]/g, '') || `execution-${executionIndex + 1}`;
    return `${executionIndex + 1}-${basename(safeName)}.md`;
}
function executionToMarkdown(execution, options) {
    return renderExecution(execution, 0, options);
}
function reportToMarkdown(report) {
    const reportDump = toReportDump(report);
    const executionResults = reportDump.executions.map((execution, index)=>{
        const rendered = renderExecution(execution, index);
        return {
            executionIndex: index,
            executionName: execution.name,
            markdown: rendered.markdown,
            attachments: rendered.attachments,
            suggestedFileName: reportFileName(execution, index)
        };
    });
    const attachments = executionResults.flatMap((item)=>item.attachments);
    const header = [
        `# ${reportDump.groupName}`,
        reportDump.groupDescription ? `\n${reportDump.groupDescription}` : '',
        `\n- SDK Version: ${reportDump.sdkVersion}`,
        `- Execution count: ${reportDump.executions.length}`,
        '\n## Suggested execution markdown files',
        ...executionResults.map((item)=>`- ${item.suggestedFileName} (${item.executionName})`)
    ].filter(Boolean).join('\n');
    return {
        markdown: `${header}\n\n${executionResults.map((item)=>item.markdown).join('\n\n---\n\n')}`,
        attachments
    };
}
export { executionToMarkdown, reportToMarkdown };

//# sourceMappingURL=report-markdown.mjs.map