import { GraphQLError } from 'graphql';
import { EMPTY_UUID } from '../../../shared/constants.js';
import { BusinessTripsProvider } from '../../business-trips/providers/business-trips.provider.js';
import { ChargeTagsProvider } from '../../tags/providers/charge-tags.provider.js';
import { ChargeSpreadProvider } from '../providers/charge-spread.provider.js';
import { ChargesProvider } from '../providers/charges.provider.js';
export async function batchUpdateChargesTags(injector, tags, chargeIds) {
    const tagsPromises = [];
    const pastTagsForCharges = await injector
        .get(ChargeTagsProvider)
        .getTagsByChargeIDLoader.loadMany(chargeIds)
        .then(res => res.map((chargeTags, i) => {
        if (chargeTags instanceof Error) {
            console.error(`Error loading tags for charge ID="${chargeIds[i]}": ${chargeTags.message}`);
            return [];
        }
        return chargeTags.map(tag => tag.id);
    }));
    for (const [i, pastTags] of pastTagsForCharges.entries()) {
        const chargeId = chargeIds[i];
        if (!chargeId) {
            throw new GraphQLError(`Charge ID at index ${i} is undefined`);
        }
        // clear removed tags
        const tagsToRemove = pastTags.filter(tagId => !tags.includes(tagId));
        if (tagsToRemove.length) {
            tagsPromises.push(injector
                .get(ChargeTagsProvider)
                .clearChargeTags({ chargeId, tagIDs: tagsToRemove })
                .catch(e => {
                console.error(e);
                throw new GraphQLError(`Error clearing tags IDs="${tagsToRemove}" to charge ID="${chargeId}"`);
            }));
        }
        // add new tags
        const tagIDsToAdd = tags.filter(tagId => !pastTags.includes(tagId));
        for (const tagId of tagIDsToAdd) {
            tagsPromises.push(injector
                .get(ChargeTagsProvider)
                .insertChargeTag({ chargeId, tagId })
                .catch(e => {
                console.error(e);
                throw new GraphQLError(`Error adding tag ID="${tagId}" to charge ID="${chargeId}"`);
            }));
        }
    }
    await Promise.all(tagsPromises);
}
export async function batchUpdateChargesBusinessTrip(injector, businessTripID, chargeIds) {
    try {
        return Promise.all(chargeIds.map(chargeId => injector
            .get(BusinessTripsProvider)
            .updateChargeBusinessTrip(chargeId, businessTripID === EMPTY_UUID ? null : businessTripID)
            .catch(e => {
            console.error(e);
            throw new GraphQLError(`Error updating business trip for charge ID="${chargeId}"`);
        })));
    }
    catch (error) {
        if (error instanceof GraphQLError) {
            throw error;
        }
        console.error(error);
        throw new GraphQLError('An unexpected error occurred while updating charges business trip');
    }
}
export async function batchUpdateChargesYearsSpread(injector, yearsOfRelevance, chargeIds) {
    await injector
        .get(ChargeSpreadProvider)
        .deleteAllChargeSpreadByChargeIds({ chargeIds })
        .catch(e => {
        console.error(e);
        throw new GraphQLError(`Error deleting spread records for charge IDs "${chargeIds.join('", "')}"`);
    });
    return Promise.all(chargeIds.map(async (chargeId) => {
        const charge = await injector.get(ChargesProvider).getChargeByIdLoader.load(chargeId);
        if (!charge) {
            throw new GraphQLError(`Charge ID="${chargeId}" not found`);
        }
        return injector
            .get(ChargeSpreadProvider)
            .insertChargeSpread({
            chargeSpread: yearsOfRelevance.map(record => ({
                ownerId: charge.owner_id,
                chargeId,
                yearOfRelevance: record.year,
                amount: record.amount,
            })),
        })
            .catch(e => {
            console.error(e);
            throw new GraphQLError(`Error inserting spread records for charge ID="${chargeId}"`);
        });
    }));
}
//# sourceMappingURL=batch-update-charges.js.map