"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "importSurvey", {
    enumerable: true,
    get: function() {
        return importSurvey;
    }
});
const _xlsx = require("xlsx");
const _sequelize = require("sequelize");
const _constants = require("@tamanu/constants");
const _criteria = require("@tamanu/utils/criteria");
const _errors = require("../errors");
const _importRows = require("../importer/importRows");
const _readSurveyQuestions = require("./readSurveyQuestions");
const _validation = require("./validation");
const _programDataElementValidation = require("./programDataElementValidation");
async function validateFormVisibilityCriteriaQuestionCodes(context, surveyInfo) {
    const { visibilityCriteria, rowIndex, name } = surveyInfo;
    const questionCodes = (0, _criteria.getQuestionCodesFromFormVisibilityCriteria)(visibilityCriteria);
    if (questionCodes.length === 0) return;
    const { models } = context;
    const existing = await models.ProgramDataElement.findAll({
        where: {
            code: {
                [_sequelize.Op.in]: questionCodes
            }
        },
        attributes: [
            'code'
        ]
    });
    const existingCodes = new Set(existing.map((el)=>el.code));
    const missingCodes = questionCodes.filter((code)=>!existingCodes.has(code));
    if (missingCodes.length > 0) {
        throw new _errors.ValidationError('Metadata', rowIndex, `Survey "${name}" has form visibility criteria referencing question code(s) "${missingCodes.join('", "')}" which do not exist. The question codes must exist in the database (from this or another program).`);
    }
}
function readSurveyInfo(workbook, surveyInfo) {
    const { sheetName, surveyType, code } = surveyInfo;
    const surveyRecord = {
        model: 'Survey',
        sheetRow: -2,
        values: surveyInfo
    };
    // don't bother looking for the sheet of questions from obsoleted surveys
    // (it may not even exist in the doc, and that's fine)
    if (surveyType === _constants.SURVEY_TYPES.OBSOLETE) {
        return [
            surveyRecord
        ];
    }
    // Strip some characters from workbook names before trying to find them
    // (this mirrors the punctuation stripping that node-xlsx does internally)
    const worksheet = workbook.Sheets[sheetName.replace(/['"]/g, '')] || workbook.Sheets[code];
    if (!worksheet) {
        const keys = Object.keys(workbook.Sheets);
        throw new _errors.ImporterMetadataError(`Sheet named "${sheetName}" was not found in the workbook. (found: ${keys})`);
    }
    const data = _xlsx.utils.sheet_to_json(worksheet);
    const questionRecords = (0, _readSurveyQuestions.readSurveyQuestions)(data, surveyInfo);
    (0, _validation.ensureRequiredQuestionsPresent)(surveyInfo, questionRecords);
    return [
        surveyRecord,
        ...questionRecords
    ];
}
async function importSurvey(context, workbook, surveyInfo) {
    var _surveyInfo;
    const { sheetName, surveyType, programId } = surveyInfo;
    if (surveyType === _constants.SURVEY_TYPES.VITALS) {
        await (0, _validation.validateVitalsSurvey)(context, surveyInfo);
    }
    if (_constants.CHARTING_SURVEY_TYPES.includes(surveyType)) {
        await (0, _validation.validateChartingSurvey)(context, surveyInfo);
    }
    if (surveyInfo.visibilityCriteria) {
        await validateFormVisibilityCriteriaQuestionCodes(context, surveyInfo);
    }
    (_surveyInfo = surveyInfo).notifiable ?? (_surveyInfo.notifiable = false);
    surveyInfo.notifyEmailAddresses = (surveyInfo.notifyEmailAddresses ?? '').split(',').map((email)=>email.trim()).filter(Boolean);
    const records = readSurveyInfo(workbook, surveyInfo);
    const stats = (0, _programDataElementValidation.validateProgramDataElementRecords)(records, {
        context,
        sheetName,
        surveyType
    });
    const customPatientFieldIds = (await context.models.PatientFieldDefinition.findAll({
        attributes: [
            'id'
        ]
    })).map((f)=>f.id);
    return (0, _importRows.importRows)(context, {
        sheetName,
        rows: records,
        stats
    }, {
        models: context.models,
        programId,
        customPatientFieldIds
    });
}

//# sourceMappingURL=importSurvey.js.map