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';
const getAllSortCodes = sql `
  SELECT *
  FROM accounter_schema.sort_codes`;
const getSortCodesByIds = sql `
  SELECT sc.*
  FROM accounter_schema.sort_codes sc
  WHERE ($isSortCodesIds = 0 OR sc.key IN $$sortCodesIds);`;
const getSortCodesByOwnerIds = sql `
  SELECT sc.*
  FROM accounter_schema.sort_codes sc
  WHERE sc.owner_id IN $$ownerIds;`;
const insertSortCode = sql `
    INSERT INTO accounter_schema.sort_codes (name, key, default_irs_code, owner_id)
    VALUES ($name, $key, $defaultIrsCode, $ownerId)
    RETURNING *;
  `;
const insertSortCodes = sql `
    INSERT INTO accounter_schema.sort_codes (name, key, default_irs_code, owner_id)
    VALUES $$sortCodes(name, key, defaultIrsCode, ownerId)
    ON CONFLICT (key, owner_id) DO NOTHING
    RETURNING *;
  `;
const updateSortCode = sql `
    UPDATE accounter_schema.sort_codes
    SET name = COALESCE(
      $name,
      name
    ),
    default_irs_code = COALESCE(
      $defaultIrsCode,
      default_irs_code
    )
    WHERE key = $key AND owner_id = $ownerId
    RETURNING *;
  `;
let SortCodesProvider = class SortCodesProvider {
    db;
    adminContextProvider;
    constructor(db, adminContextProvider) {
        this.db = db;
        this.adminContextProvider = adminContextProvider;
    }
    allSortCodesCache = null;
    getAllSortCodes() {
        if (this.allSortCodesCache) {
            return this.allSortCodesCache;
        }
        this.allSortCodesCache = getAllSortCodes.run(undefined, this.db).then(data => {
            data.map(sortCode => {
                this.getSortCodesByIdLoader.prime({ key: sortCode.key, ownerId: sortCode.owner_id }, sortCode);
            });
            return data;
        });
        return this.allSortCodesCache;
    }
    async batchSortCodesByOwnerIds(ownerIds) {
        const sortCodes = await getSortCodesByOwnerIds.run({
            ownerIds,
        }, this.db);
        return ownerIds.map(id => sortCodes.filter(record => record.owner_id === id));
    }
    getSortCodesByOwnerIdLoader = new DataLoader((ownerIds) => this.batchSortCodesByOwnerIds(ownerIds));
    async batchSortCodesByIds(keys) {
        const sortCodes = await getSortCodesByIds.run({
            isSortCodesIds: keys.length > 0 ? 1 : 0,
            sortCodesIds: keys.map(k => k.key),
        }, this.db);
        return keys.map(k => sortCodes.find(record => record.key === k.key && record.owner_id === k.ownerId));
    }
    getSortCodesByIdLoader = new DataLoader((keys) => this.batchSortCodesByIds(keys));
    async addSortCode(params) {
        this.clearCache();
        const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
        return insertSortCode.run(reassureOwnerIdExists(params, ownerId), this.db);
    }
    async addSortCodes(params, client) {
        this.clearCache();
        const hasMissingOwnerId = params.sortCodes.some(sortCode => !sortCode.ownerId);
        const ownerId = hasMissingOwnerId
            ? (await this.adminContextProvider.getVerifiedAdminContext()).ownerId
            : '';
        params.sortCodes = params.sortCodes.map(sortCode => reassureOwnerIdExists(sortCode, ownerId));
        return insertSortCodes.run(params, client ?? this.db);
    }
    async updateSortCode(params) {
        this.clearCache();
        return updateSortCode.run(params, this.db);
    }
    clearCache() {
        this.getSortCodesByIdLoader.clearAll();
        this.allSortCodesCache = null;
    }
};
SortCodesProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AdminContextProvider])
], SortCodesProvider);
export { SortCodesProvider };
//# sourceMappingURL=sort-codes.provider.js.map