import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { reassureOwnerIdExists } from '../../../shared/helpers/index.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { BusinessTripsProvider } from './business-trips.provider.js';
const getBusinessTripsAttendeesByBusinessTripIds = sql `
  SELECT bta.business_trip_id, bta.arrival, bta.departure, fe.*, b.vat_number, b.hebrew_name, b.address, b.address_hebrew, b.email, b.website, b.phone_number, b.country, b.no_invoices_required, b.suggestion_data, b.can_settle_with_receipt, b.exempt_dealer, b.optional_vat, b.pcn874_record_type_override, b.city, b.zip_code
  FROM accounter_schema.financial_entities fe
  LEFT JOIN accounter_schema.business_trips_attendees bta
    ON bta.attendee_business_id = fe.id
  LEFT JOIN accounter_schema.businesses b
    ON bta.attendee_business_id = b.id
  WHERE bta.business_trip_id IN $$businessTripIds;`;
const getBusinessTripsByAttendeeId = sql `
  SELECT DISTINCT bt.*
  FROM accounter_schema.business_trips_attendees bta
  LEFT JOIN accounter_schema.business_trips bt
    ON bt.id = bta.business_trip_id
  WHERE bta.attendee_business_id = $attendeeId;`;
const getLastFlightByDateAndAttendeeId = sql `
  SELECT *
  FROM accounter_schema.business_trips_attendees
  WHERE attendee_business_id = $attendeeBusinessId
    AND arrival < $date
    AND departure <= $date AND departure >= $date - INTERVAL '14 DAY'
  ORDER BY departure DESC
      FETCH FIRST 1 ROWS ONLY;`;
const addBusinessTripAttendees = sql `
  INSERT INTO accounter_schema.business_trips_attendees (business_trip_id, attendee_business_id, arrival, departure, owner_id)
  VALUES ($businessTripId, $businessId, $arrival, $departure, $ownerId)
  ON CONFLICT DO NOTHING
  RETURNING *;`;
const updateBusinessTripAttendee = sql `
  UPDATE accounter_schema.business_trips_attendees
  SET
  arrival = COALESCE(
    $arrival,
    arrival
  ),
  departure = COALESCE(
    $departure,
    departure
  )
  WHERE
    business_trip_id = $businessTripId
    AND attendee_business_id = $attendeeBusinessId
  RETURNING *;
`;
const removeBusinessTripAttendees = sql `
  DELETE FROM accounter_schema.business_trips_attendees
  WHERE business_trip_id = $businessTripId
    AND attendee_business_id = $businessId
  RETURNING *;`;
let BusinessTripAttendeesProvider = class BusinessTripAttendeesProvider {
    db;
    adminContextProvider;
    businessTripsProvider;
    constructor(db, adminContextProvider, businessTripsProvider) {
        this.db = db;
        this.adminContextProvider = adminContextProvider;
        this.businessTripsProvider = businessTripsProvider;
    }
    async batchBusinessTripsAttendeesByChargeIds(chargeIds) {
        const businessTripsMatches = await this.businessTripsProvider.getBusinessTripsByChargeIdLoader
            .loadMany(chargeIds)
            .then(res => res.filter(item => item && !(item instanceof Error)));
        const businessTripsAttendees = await this.getBusinessTripsAttendeesByBusinessTripIdLoader
            .loadMany(businessTripsMatches.filter(record => record.id).map(record => record.id))
            .then(records => records
            .flat()
            .filter(record => !(record instanceof Error)));
        return chargeIds.map(id => businessTripsMatches
            .filter(record => record.charge_id === id)
            .map(match => businessTripsAttendees.filter(attendee => attendee.business_trip_id === match.id))
            .flat());
    }
    getBusinessTripsAttendeesByChargeIdLoader = new DataLoader((chargeIds) => this.batchBusinessTripsAttendeesByChargeIds(chargeIds), {
        cache: false,
    });
    async batchBusinessTripsAttendeesByBusinessTripIds(businessTripIds) {
        const businessTrips = await getBusinessTripsAttendeesByBusinessTripIds.run({
            businessTripIds,
        }, this.db);
        return businessTripIds.map(id => businessTrips.filter(record => record.business_trip_id === id));
    }
    getBusinessTripsAttendeesByBusinessTripIdLoader = new DataLoader((ids) => this.batchBusinessTripsAttendeesByBusinessTripIds(ids));
    async getBusinessTripsByAttendeeId(attendeeId) {
        return getBusinessTripsByAttendeeId.run({ attendeeId }, this.db);
    }
    async getLastFlightByDateAndAttendeeId(params) {
        return getLastFlightByDateAndAttendeeId.run(params, this.db);
    }
    async addBusinessTripAttendees(params) {
        if (params.businessTripId) {
            this.getBusinessTripsAttendeesByBusinessTripIdLoader.clear(params.businessTripId);
        }
        const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
        return addBusinessTripAttendees.run(reassureOwnerIdExists(params, ownerId), this.db);
    }
    async updateBusinessTripAttendee(params) {
        if (params.businessTripId) {
            this.getBusinessTripsAttendeesByBusinessTripIdLoader.clear(params.businessTripId);
        }
        return updateBusinessTripAttendee.run(params, this.db);
    }
    async removeBusinessTripAttendees(params) {
        if (params.businessTripId) {
            this.getBusinessTripsAttendeesByBusinessTripIdLoader.clear(params.businessTripId);
        }
        return removeBusinessTripAttendees.run(params, this.db);
    }
    clearCache() {
        this.getBusinessTripsAttendeesByChargeIdLoader.clearAll();
        this.getBusinessTripsAttendeesByBusinessTripIdLoader.clearAll();
    }
};
BusinessTripAttendeesProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AdminContextProvider,
        BusinessTripsProvider])
], BusinessTripAttendeesProvider);
export { BusinessTripAttendeesProvider };
//# sourceMappingURL=business-trips-attendees.provider.js.map