import c from "chalk";
import fs from "fs-extra";
import * as path from "path";
import { MetadataUtils } from "../metadata-utils/index.js";
import { uxLog } from "../utils/index.js";
import { generateFlowVisualGitDiff } from "../utils/mermaidUtils.js";
import { GitProvider } from "./index.js";
export function deployErrorsToMarkdown(errorsAndTips) {
    let md = "## Deployment errors\n\n";
    for (const err of errorsAndTips) {
        const errorMessage = err?.error?.message?.trim().includes("Error ")
            ? err?.error?.message
                .trim()
                .replace("| Error ", "")
                .replace("Error ", "")
                .replace(" ", "<br/>")
                .trim()
                .replace(/(.*)<br\/>/gm, `<b>$1</b> `)
            : err?.error?.message?.trim() || "WE SHOULD NOT GO THERE: PLEASE DECLARE AN ISSUE";
        // sfdx-hardis tip
        if (err.tip) {
            const aiText = err?.tipFromAi?.promptResponse
                ? getAiPromptResponseMarkdown("AI Deployment Assistant recommendation", err.tipFromAi.promptResponse)
                : err?.tipFromAi?.promptText
                    ? getAiPromptTextMarkdown("Get prompt for AI", err.tipFromAi.promptText)
                    : "";
            md += `<details><summary>⛔ ${errorMessage}</summary>

_[**✏️ ${err.tip.label}**](${err.tip.docUrl || "https://sfdx-hardis.cloudity.com/salesforce-deployment-assistant-home/"})_

${err.tip.message.replace(/:\n-/gm, `:\n\n-`)}
${aiText}
</details>
<br/>
`;
        }
        // No sfdx-hardis tip but AI instructions
        else if (err?.tipFromAi?.promptResponse) {
            md += getAiPromptResponseMarkdown(errorMessage, err.tipFromAi.promptResponse);
        }
        // No tip or AI instruction but a prompt to copy-paste
        else if (err?.tipFromAi?.promptText) {
            md += getAiPromptTextMarkdown(errorMessage, err.tipFromAi.promptText);
        }
        // No tip & no AI prompt or response
        else {
            md += "🔨 " + errorMessage + "\n\n";
        }
    }
    return md;
}
export function testFailuresToMarkdown(testFailures) {
    let md = "## Test classes failures\n\n";
    for (const err of testFailures) {
        const errorMessage = `<b>${err.class}.${err.method}</b><br/>${err.error}`;
        if (err.stack) {
            md += `<details><summary>💥 ${errorMessage}</summary>

${err.stack}
</details>

`;
        }
        else {
            md += "💥 " + errorMessage + "\n\n";
        }
    }
    return md;
}
export function deployCodeCoverageToMarkdown(orgCoverage, orgCoverageTarget) {
    if (orgCoverage < orgCoverageTarget) {
        return `❌ Your code coverage is insufficient: **${orgCoverage}%**, while your target is **${orgCoverageTarget}%**`;
    }
    else {
        return `✅ Your code coverage is ok :) **${orgCoverage}%**, while target is **${orgCoverageTarget}%**`;
    }
}
export function mdTableCell(str) {
    if (!str) {
        return "<!-- -->";
    }
    return str.replace(/\n/gm, "<br/>").replace(/\|/gm, "");
}
export async function flowDiffToMarkdownForPullRequest(flowNames, fromCommit, toCommit, truncatedNb = 0) {
    if (flowNames.length === 0) {
        return "";
    }
    const supportsMermaidInPrMarkdown = await GitProvider.supportsMermaidInPrMarkdown();
    const supportsSvgAttachments = await GitProvider.supportsSvgAttachments();
    const flowDiffMarkdownList = [];
    let flowDiffFilesSummary = "## Flow changes\n\n";
    for (const flowName of flowNames) {
        flowDiffFilesSummary += `- [${flowName}](#${flowName})\n`;
        const fileMetadata = await MetadataUtils.findMetaFileFromTypeAndName("Flow", flowName);
        try {
            // Markdown with pure mermaidJs
            if (supportsMermaidInPrMarkdown) {
                await generateDiffMarkdownWithMermaid(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName);
            }
            // Markdown with Mermaid converted as SVG
            else if (supportsSvgAttachments) {
                await generateDiffMarkdownWithSvg(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName);
            }
            // Markdown with images converted as PNG
            else {
                await generateDiffMarkdownWithPng(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName);
            }
        }
        catch (e) {
            uxLog("warning", this, c.yellow(`[FlowGitDiff] Unable to generate Flow diff for ${flowName}: ${e.message}`));
        }
    }
    if (truncatedNb > 0) {
        flowDiffFilesSummary += `\n\n:warning: _${truncatedNb} Flows have been truncated_\n\n`;
    }
    return {
        markdownSummary: flowDiffFilesSummary,
        flowDiffMarkdownList: flowDiffMarkdownList
    };
}
async function generateDiffMarkdownWithMermaid(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName) {
    const { outputDiffMdFile, hasFlowDiffs } = await generateFlowVisualGitDiff(fileMetadata, fromCommit, toCommit, { mermaidMd: true, svgMd: false, pngMd: false, debug: false });
    if (outputDiffMdFile && hasFlowDiffs) {
        const flowDiffMarkdownMermaid = await fs.readFile(outputDiffMdFile.replace(".md", ".mermaid.md"), "utf8");
        flowDiffMarkdownList.push({ name: flowName, markdown: flowDiffMarkdownMermaid, markdownFile: outputDiffMdFile });
    }
}
async function generateDiffMarkdownWithSvg(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName) {
    const { outputDiffMdFile, hasFlowDiffs } = await generateFlowVisualGitDiff(fileMetadata, fromCommit, toCommit, { mermaidMd: true, svgMd: true, pngMd: false, debug: false });
    if (outputDiffMdFile && hasFlowDiffs && fs.existsSync(outputDiffMdFile)) {
        const flowDiffMarkdownWithSvg = await fs.readFile(outputDiffMdFile, "utf8");
        flowDiffMarkdownList.push({ name: flowName, markdown: flowDiffMarkdownWithSvg, markdownFile: outputDiffMdFile });
    }
}
async function generateDiffMarkdownWithPng(fileMetadata, fromCommit, toCommit, flowDiffMarkdownList, flowName) {
    const { outputDiffMdFile, hasFlowDiffs } = await generateFlowVisualGitDiff(fileMetadata, fromCommit, toCommit, { mermaidMd: true, svgMd: false, pngMd: true, debug: false });
    if (outputDiffMdFile && hasFlowDiffs && fs.existsSync(outputDiffMdFile)) {
        const flowDiffMarkdownWithPng = await fs.readFile(outputDiffMdFile, "utf8");
        flowDiffMarkdownList.push({ name: flowName, markdown: flowDiffMarkdownWithPng, markdownFile: outputDiffMdFile });
    }
}
function getAiPromptResponseMarkdown(title, message) {
    return `<details><summary>🤖 <b>${title}</b></summary>

_AI Deployment Assistant tip (not verified !)_

${message.replace(/:\n-/gm, `:\n\n-`).trim()}
</details>
<br/>
`;
}
function getAiPromptTextMarkdown(title, message) {
    return `<details><summary><b>${title}</b></summary>

_Request AI by copy-pasting the following text in ChatGPT or other AI prompt_

${message.replace(/:\n-/gm, `:\n\n-`)}
</details>
<br/>
`;
}
export function extractImagesFromMarkdown(markdown, sourceFile) {
    let sourceFilePath = "";
    if (sourceFile && fs.existsSync(sourceFile)) {
        sourceFilePath = path.dirname(sourceFile);
    }
    const imageRegex = /!\[.*?\]\((.*?)\)/gm;
    const matches = Array.from(markdown.matchAll(imageRegex));
    return matches.map((match) => match[1]).filter(file => {
        if (fs.existsSync(file)) {
            return true;
        }
        else if (fs.existsSync(path.join(sourceFilePath, file))) {
            return true;
        }
        uxLog("warning", this, c.yellow(`[Markdown] Image file not found: ${file} or ${path.join(sourceFilePath, file)}`));
        return false;
    }).map(file => {
        if (fs.existsSync(file)) {
            return { name: file, path: file };
        }
        else if (fs.existsSync(path.join(sourceFilePath, file))) {
            return { name: file, path: path.join(sourceFilePath, file) };
        }
        return {};
    });
}
export function replaceImagesInMarkdown(markdown, replacements) {
    for (const replacedImage of Object.keys(replacements)) {
        markdown = markdown.replaceAll(replacedImage, replacements[replacedImage]);
    }
    return markdown;
}
//# sourceMappingURL=utilsMarkdown.js.map