"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "GenerateRepeatingAppointments", {
    enumerable: true,
    get: function() {
        return GenerateRepeatingAppointments;
    }
});
const _config = /*#__PURE__*/ _interop_require_default(require("config"));
const _sequelize = require("sequelize");
const _tasks = require("@tamanu/shared/tasks");
const _logging = require("@tamanu/shared/services/logging");
const _constants = require("@tamanu/constants");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
let GenerateRepeatingAppointments = class GenerateRepeatingAppointments extends _tasks.ScheduledTask {
    getName() {
        return 'GenerateRepeatingAppointments';
    }
    async run() {
        // Find all schedules that are incomplete and have a latest appointment that is older than the offset days
        const schedules = await this.sequelize.query(`
      SELECT
          appointment_schedules.*,
          latest_appointment.start_time AS latest_appointment_start_time
        FROM appointment_schedules
        LEFT JOIN LATERAL (
          SELECT start_time
          FROM appointments
          WHERE appointments.schedule_id = appointment_schedules.id AND appointments.status <> :canceledStatus
          ORDER BY appointments.start_time DESC
          LIMIT 1
        ) AS latest_appointment ON true
        WHERE appointment_schedules.deleted_at IS NULL
        AND appointment_schedules.cancelled_at_date IS NULL
        AND appointment_schedules.is_fully_generated = false
        AND latest_appointment.start_time::date < NOW() + INTERVAL :offsetDays DAY
      `, {
            type: _sequelize.QueryTypes.SELECT,
            model: this.models.AppointmentSchedule,
            mapToModel: true,
            replacements: {
                offsetDays: `${this.config.generateOffsetDays}`,
                canceledStatus: _constants.APPOINTMENT_STATUSES.CANCELLED
            }
        });
        if (!schedules.length) {
            this.log.info('No incomplete schedules found within time frame');
            return;
        }
        this.log.info('Found incomplete schedules within time frame', {
            count: schedules.length
        });
        await this.sequelize.transaction(()=>Promise.all(schedules.map(async (schedule)=>{
                const appointments = await schedule.generateRepeatingAppointment(this.settings);
                this.log.info('Generated appointments for schedule', {
                    count: appointments.length,
                    scheduleId: schedule.id
                });
            })));
    }
    /**
   *
   * @param {import('../ApplicationContext').ApplicationContext} context
   */ constructor(context){
        const conf = _config.default.schedules.generateRepeatingAppointments;
        const { schedule, jitterTime, enabled } = conf;
        super(schedule, _logging.log, jitterTime, enabled);
        this.models = context.store.models;
        this.config = conf;
        this.sequelize = context.store.sequelize;
        this.settings = context.settings;
    }
};

//# sourceMappingURL=GenerateRepeatingAppointments.js.map