import * as path from "path";

const DEFAULT_REPORT_FILENAME_PATTERN = "^[A-Za-z0-9]{4}\\.TXT$";

/**
 * Returns the default ROBODOC configuration values.
 * Configuration is intentionally not read from vscode.workspace.getConfiguration here
 * to keep core/ free of VS Code dependencies.
 *
 * The VS Code extension layer reads workspace settings directly and passes them as
 * an explicit config argument to functions that accept one (e.g. getExpectedRobodocHeader,
 * inferDocumentKind, resolveAuthorName). The robodocValidator accepts an explicit robodocConfig argument and merges it
 * with these defaults via a spread, so config injection is already in effect.
 */
function getRobodocConfig() {
    return {
        enabled: true,
        requireDocBlock: false,
        requiredSections: ["DESCRIPTION", "CHANGE HISTORY", "USES"],
        reportFilenamePattern: DEFAULT_REPORT_FILENAME_PATTERN,
        reportHeaderPrefix: "REPORT/",
        includeHeaderPrefix: "INCLUDE/",
        validateHeaderTarget: true,
        authorName: ""
    };
}

/**
 * Merges a partial user-supplied config with defaults so all fields are always
 * present. Callers that receive a config object should call this before
 * accessing individual fields.
 * @param {Object|null|undefined} config
 * @returns {Object} - Full config with defaults applied for any missing fields
 */
function normalizeRobodocConfig(config) {
    const overrides = {};
    if (config && typeof config === "object") {
        for (const key of Object.keys(config)) {
            if (config[key] !== undefined) {
                overrides[key] = config[key];
            }
        }
    }
    return Object.assign({}, getRobodocConfig(), overrides);
}

function isReportFilename(filename, patternText) {
    if (!filename) {
        return false;
    }

    const pattern = patternText || DEFAULT_REPORT_FILENAME_PATTERN;
    try {
        return new RegExp(pattern, "i").test(filename);
    } catch (_error) {
        return new RegExp(DEFAULT_REPORT_FILENAME_PATTERN, "i").test(filename);
    }
}

function inferDocumentKind(filename, config) {
    const cfg = normalizeRobodocConfig(config);
    return isReportFilename(filename, cfg.reportFilenamePattern) ? "report" : "include";
}

function getExpectedRobodocHeader(filename, config) {
    const cfg = normalizeRobodocConfig(config);
    const safeFilename = filename || "NEW_REPORT.TXT";
    const kind = inferDocumentKind(safeFilename, cfg);

    if (kind === "report") {
        const reportName = safeFilename.replace(/\.[^.]+$/, "");
        return {
            kind,
            kindChar: "r",
            target: `${cfg.reportHeaderPrefix}${reportName}`
        };
    }

    return {
        kind,
        kindChar: "h",
        target: `${cfg.includeHeaderPrefix}${safeFilename}`
    };
}

function resolveAuthorName(document, config) {
    const cfg = normalizeRobodocConfig(config);
    if (cfg.authorName && cfg.authorName.trim()) {
        return cfg.authorName.trim();
    }
    return "[Your Name]";
}

function getBaseFilename(documentOrPath) {
    if (!documentOrPath) {
        return "NEW_REPORT.TXT";
    }

    if (typeof documentOrPath === "string") {
        return path.basename(documentOrPath);
    }

    if (documentOrPath.fileName) {
        return path.basename(documentOrPath.fileName);
    }

    return "NEW_REPORT.TXT";
}

export {
    DEFAULT_REPORT_FILENAME_PATTERN,
    getRobodocConfig,
    normalizeRobodocConfig,
    inferDocumentKind,
    getExpectedRobodocHeader,
    resolveAuthorName,
    getBaseFilename
};
