import { render } from 'ejs';
import { logger } from 'rspress/core';
import { ResponseError, xfetch } from 'x-fetch';
import { cyan, red } from 'yoctocolors';
import { isCI } from './utils.js';
const releaseCache = new Map();
const FIELD_MAPPER = {
    zh: 'customfield_13800',
    en: 'customfield_13801',
};
const issuesToListItems = (issues, lang, isMdx) => issues
    .map((issue) => {
    const description = ((FIELD_MAPPER[lang] && issue.fields[FIELD_MAPPER[lang]]) ||
        issue.fields[FIELD_MAPPER.en])?.trim();
    if (!description) {
        return;
    }
    return {
        type: 'listItem',
        children: [
            {
                type: 'paragraph',
                children: description
                    .split('\n')
                    .map((line) => ({ type: 'text', value: line }))
                    .reduce((acc, curr, index) => {
                    if (index === 0) {
                        acc.push(curr);
                    }
                    else {
                        acc.push(
                        // @ts-expect-error -- seems like a typing issue in mdast or TypeScript
                        isMdx
                            ? { type: 'mdxJsxFlowElement', name: 'br' }
                            : { type: 'html', value: '<br>' }, curr);
                    }
                    return acc;
                }, []),
            },
        ],
    };
})
    .filter(Boolean);
const { JIRA_USERNAME, JIRA_PASSWORD } = process.env;
let warned = false;
const NO_ISSUE_MAPPER = {
    zh: '此次发版无相关问题。',
    en: 'No issues in this release.',
};
const resolveRelease_ = async (releaseTemplates, releaseQuery, isMdx) => {
    const query = new URLSearchParams(releaseQuery);
    const templateName = query.get('template');
    if (!templateName) {
        logger.error(`Release notes template not found for query \`${red(releaseQuery)}\``);
        return;
    }
    const template = releaseTemplates[templateName];
    if (!template) {
        logger.error(`Release notes template \`${red(templateName)}\` not found`);
        return;
    }
    let Authorization;
    if (JIRA_USERNAME && JIRA_PASSWORD) {
        Authorization = `Basic ${Buffer.from(`${JIRA_USERNAME}:${JIRA_PASSWORD}`).toString('base64')}`;
    }
    else {
        if (warned) {
            return;
        }
        warned = true;
        const message = `\`${cyan('JIRA_USERNAME')}\` and \`${cyan('JIRA_PASSWORD')}\` environments must be set for fetching Jira issues`;
        if (isCI) {
            throw new Error(message);
        }
        logger.warn(message);
        return;
    }
    const data = {};
    for (const [key, value] of query.entries()) {
        if (key === 'template') {
            continue;
        }
        data[key] = value;
    }
    const jql = await render(template, data, { async: true });
    logger.info(`Fetching release notes for query \`${cyan(releaseQuery)}\``);
    let issues;
    try {
        ;
        ({ issues } = await xfetch(`https://jira.alauda.cn/rest/api/2/search?${new URLSearchParams({ jql })}`, { headers: { Authorization } }));
    }
    catch (err) {
        if (err instanceof ResponseError) {
            const error = err;
            logger.error(`Failed to fetch release notes for query \`${red(releaseQuery)}\` with status \`${error.response.status}\` and ${error.data ? `data ${JSON.stringify(error.data, null, 2)}` : `message \`${error.message}\``}`);
        }
        return;
    }
    return ['en', 'zh'].reduce((acc, lang) => Object.assign(acc, {
        [lang]: issues.length
            ? {
                type: 'list',
                children: issuesToListItems(issues, lang, isMdx),
            }
            : {
                type: 'paragraph',
                children: [
                    {
                        type: 'text',
                        value: NO_ISSUE_MAPPER[lang] || NO_ISSUE_MAPPER.en,
                    },
                ],
            },
    }), {});
};
export const resolveRelease = async (releaseTemplates, releaseQuery, lang, isMdx) => {
    if (releaseCache.has(releaseQuery)) {
        const cached = await releaseCache.get(releaseQuery);
        return cached?.[lang] ?? cached?.en;
    }
    const resolving = resolveRelease_(releaseTemplates, releaseQuery, isMdx);
    releaseCache.set(releaseQuery, resolving);
    const resolved = await resolving;
    return resolved?.[lang] ?? resolved?.en;
};
