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 getFinancialAccountsByOwnerIds = sql `
    SELECT id, account_number, account_name, private_business, owner, type
    FROM accounter_schema.financial_accounts
    WHERE owner IN $$ownerIds;`;
const getFinancialAccountsByAccountNumbers = sql `
SELECT id, account_number, account_name, private_business, owner, type
FROM accounter_schema.financial_accounts
WHERE account_number IN $$accountNumbers;`;
const getFinancialAccountsByAccountIDs = sql `
SELECT id, account_number, account_name, private_business, owner, type
FROM accounter_schema.financial_accounts
WHERE id IN $$accountIDs;`;
const getAllFinancialAccounts = sql `
    SELECT id, account_number, account_name, private_business, owner, type
    FROM accounter_schema.financial_accounts;`;
const updateFinancialAccount = sql `
      UPDATE accounter_schema.financial_accounts
      SET
      account_number = COALESCE(
        $accountNumber,
        account_number
      ),
      account_name = COALESCE(
        $name,
        account_name
      ),
      private_business = COALESCE(
        $privateBusiness,
        private_business
      ),
      owner = COALESCE(
        $ownerId,
        owner
      ),
      type = COALESCE(
        $type,
        type
      )
      WHERE
        id = $financialAccountId
      RETURNING *;
    `;
const insertFinancialAccounts = sql `
      INSERT INTO accounter_schema.financial_accounts (
        account_number, account_name, private_business, owner, type, owner_id
      )
      VALUES $$bankAccounts(
        accountNumber, name, privateBusiness, ownerId, type, ownerId
      )
      RETURNING *;`;
const deleteFinancialAccount = sql `
        DELETE FROM accounter_schema.financial_accounts
        WHERE id = $financialAccountId
        RETURNING id;
      `;
let FinancialAccountsProvider = class FinancialAccountsProvider {
    db;
    adminContextProvider;
    constructor(db, adminContextProvider) {
        this.db = db;
        this.adminContextProvider = adminContextProvider;
    }
    async batchFinancialAccountsByOwnerIds(ownerIds) {
        const accounts = await getFinancialAccountsByOwnerIds.run({
            ownerIds,
        }, this.db);
        return ownerIds.map(ownerId => accounts.filter(charge => charge.owner === ownerId));
    }
    getFinancialAccountsByOwnerIdLoader = new DataLoader((keys) => this.batchFinancialAccountsByOwnerIds(keys));
    async batchFinancialAccountsByAccountNumbers(accountNumbers) {
        const accounts = await getFinancialAccountsByAccountNumbers.run({
            accountNumbers,
        }, this.db);
        return accountNumbers.map(accountNumber => accounts.find(charge => charge.account_number === accountNumber));
    }
    getFinancialAccountByAccountNumberLoader = new DataLoader((keys) => this.batchFinancialAccountsByAccountNumbers(keys));
    async batchFinancialAccountsByAccountIDs(accountIDs) {
        const accounts = await getFinancialAccountsByAccountIDs.run({
            accountIDs,
        }, this.db);
        return accountIDs.map(id => accounts.find(account => account.id === id));
    }
    getFinancialAccountByAccountIDLoader = new DataLoader((keys) => this.batchFinancialAccountsByAccountIDs(keys));
    allFinancialAccountsCache = null;
    getAllFinancialAccounts() {
        if (this.allFinancialAccountsCache) {
            return this.allFinancialAccountsCache;
        }
        const result = getAllFinancialAccounts.run(undefined, this.db).then(accounts => {
            accounts.map(account => {
                this.getFinancialAccountByAccountIDLoader.prime(account.id, account);
                this.getFinancialAccountByAccountNumberLoader.prime(account.account_number, account);
            });
            return accounts;
        });
        this.allFinancialAccountsCache = result;
        return result;
    }
    async updateFinancialAccount(params) {
        const updatedAccounts = await updateFinancialAccount.run(params, this.db);
        const updatedAccount = updatedAccounts[0];
        if (updatedAccount) {
            this.invalidateById(updatedAccount.id);
        }
        return updatedAccount;
    }
    async deleteFinancialAccount(params) {
        if (params.financialAccountId) {
            this.invalidateById(params.financialAccountId);
        }
        return deleteFinancialAccount.run(params, this.db);
    }
    async insertFinancialAccounts(params) {
        this.allFinancialAccountsCache = null;
        const { ownerId } = await this.adminContextProvider.getVerifiedAdminContext();
        const bankAccountsWithOwnerId = params.bankAccounts.map(account => reassureOwnerIdExists(account, ownerId));
        return insertFinancialAccounts.run({ bankAccounts: bankAccountsWithOwnerId }, this.db);
    }
    invalidateById(financialAccountId) {
        this.getFinancialAccountByAccountIDLoader.clear(financialAccountId);
        this.getFinancialAccountsByOwnerIdLoader.clearAll();
        this.getFinancialAccountByAccountNumberLoader.clearAll();
        this.allFinancialAccountsCache = null;
    }
    clearCache() {
        this.getFinancialAccountsByOwnerIdLoader.clearAll();
        this.getFinancialAccountByAccountNumberLoader.clearAll();
        this.getFinancialAccountByAccountIDLoader.clearAll();
        this.allFinancialAccountsCache = null;
    }
};
FinancialAccountsProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AdminContextProvider])
], FinancialAccountsProvider);
export { FinancialAccountsProvider };
//# sourceMappingURL=financial-accounts.provider.js.map