import { DataTypes } from 'sequelize';
import { SYNC_DIRECTIONS } from '@tamanu/constants';
import { InvalidOperationError } from '@tamanu/errors';
import { Model } from './Model';
import { dateTimeType } from '../types/model';
import { buildEncounterLinkedLookupFilter } from '../sync/buildEncounterLinkedLookupFilter';
export class AdministeredVaccine extends Model {
    static initModel({ primaryKey, ...options }) {
        super.init({
            id: primaryKey,
            batch: DataTypes.STRING,
            consent: DataTypes.BOOLEAN,
            consentGivenBy: DataTypes.TEXT,
            status: {
                type: DataTypes.STRING,
                allowNull: false
            },
            reason: DataTypes.STRING,
            injectionSite: DataTypes.STRING,
            givenBy: DataTypes.TEXT,
            givenElsewhere: DataTypes.BOOLEAN,
            vaccineBrand: DataTypes.TEXT,
            vaccineName: DataTypes.TEXT,
            disease: DataTypes.TEXT,
            circumstanceIds: DataTypes.ARRAY(DataTypes.STRING),
            date: dateTimeType('date')
        }, {
            ...options,
            syncDirection: SYNC_DIRECTIONS.BIDIRECTIONAL,
            validate: {
                mustHaveScheduledVaccine () {
                    if (!this.deletedAt && !this.scheduledVaccineId) {
                        throw new InvalidOperationError('An administered vaccine must have a scheduled vaccine.');
                    }
                },
                mustHaveEncounter () {
                    if (!this.deletedAt && !this.encounterId) {
                        throw new InvalidOperationError('An administered vaccine must have an encounter.');
                    }
                }
            }
        });
    }
    static getListReferenceAssociations() {
        return [
            'encounter',
            'scheduledVaccine'
        ];
    }
    static initRelations(models) {
        this.belongsTo(models.Encounter, {
            foreignKey: 'encounterId',
            as: 'encounter'
        });
        this.belongsTo(models.ScheduledVaccine, {
            foreignKey: 'scheduledVaccineId',
            as: 'scheduledVaccine'
        });
        this.belongsTo(models.User, {
            foreignKey: 'recorderId',
            as: 'recorder'
        });
        this.belongsTo(models.Location, {
            foreignKey: 'locationId',
            as: 'location'
        });
        this.belongsTo(models.Department, {
            foreignKey: 'departmentId',
            as: 'department'
        });
        this.belongsTo(models.ReferenceData, {
            foreignKey: 'notGivenReasonId',
            as: 'notGivenReason'
        });
    }
    static buildPatientSyncFilter(patientCount, markedForSyncPatientsTable) {
        const joins = [];
        const wheres = [];
        if (patientCount > 0) {
            joins.push(`
        LEFT JOIN encounters
        ON administered_vaccines.encounter_id = encounters.id
        AND encounters.patient_id IN (SELECT patient_id FROM ${markedForSyncPatientsTable})
      `);
            wheres.push(`
        encounters.id IS NOT NULL
      `);
        }
        if (wheres.length === 0) {
            return null;
        }
        return `
      ${joins.join('\n')}
      WHERE (
        ${wheres.join('\nOR')}
      )
      AND ${this.tableName}.updated_at_sync_tick > :since
    `;
    }
    static async buildSyncLookupQueryDetails() {
        return buildEncounterLinkedLookupFilter(this);
    }
}

//# sourceMappingURL=AdministeredVaccine.js.map