import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { AuthContextProvider } from '../../auth/providers/auth-context.provider.js';
const getCorporateTaxesByCorporateIds = sql `
  SELECT *
  FROM accounter_schema.corporate_tax_variables
  WHERE corporate_id IN $$corporateIds
  ORDER BY date DESC;`;
const updateCorporateTax = sql `
  UPDATE accounter_schema.corporate_tax_variables
  SET
  date = COALESCE(
    $date,
    date
  ),
  tax_rate = COALESCE(
    $taxRate,
    tax_rate
  ),
  original_tax_rate = COALESCE(
    $originalTaxRate,
    original_tax_rate
  )
  WHERE
    corporate_id = $corporateId
    AND date = $originalDate
  RETURNING *;`;
const insertCorporateTax = sql `
  INSERT INTO accounter_schema.corporate_tax_variables (corporate_id, date, tax_rate, original_tax_rate, owner_id)
  VALUES ($corporateId, $date, $taxRate, $originalTaxRate, $ownerId)
  RETURNING *`;
const deleteCorporateTax = sql `
  DELETE FROM accounter_schema.corporate_tax_variables
  WHERE corporate_id = $corporateId
  AND date = $date
  RETURNING *`;
let CorporateTaxesProvider = class CorporateTaxesProvider {
    db;
    authContextProvider;
    businessIdCache = null;
    constructor(db, authContextProvider) {
        this.db = db;
        this.authContextProvider = authContextProvider;
    }
    async getBusinessId() {
        if (this.businessIdCache !== null) {
            return this.businessIdCache;
        }
        const authContext = await this.authContextProvider.getAuthContext();
        this.businessIdCache = authContext?.tenant.businessId ?? null;
        if (!this.businessIdCache) {
            throw new Error('Missing businessId in AuthContext');
        }
        return this.businessIdCache;
    }
    allCorporateTaxesCache = new Map();
    getAllCorporateTaxes(corporateId) {
        if (this.allCorporateTaxesCache.has(corporateId)) {
            return this.allCorporateTaxesCache.get(corporateId);
        }
        this.allCorporateTaxesCache.set(corporateId, getCorporateTaxesByCorporateIds.run({ corporateIds: [corporateId] }, this.db));
        return this.allCorporateTaxesCache.get(corporateId);
    }
    async batchCorporateTaxesByDates(taxRates) {
        const corporateIds = [...new Set(taxRates.map(t => t.corporateId))];
        const rates = (await Promise.all(corporateIds.map(id => this.getAllCorporateTaxes(id)))).flat();
        return taxRates.map(({ date, corporateId }) => {
            const time = new Date(date).getTime();
            return rates
                .filter(rate => rate.corporate_id === corporateId)
                .sort((a, b) => b.date.getTime() - a.date.getTime())
                .find(rate => rate.date.getTime() <= time);
        });
    }
    getCorporateTaxesByDateLoader = new DataLoader(async (dates) => {
        const businessId = await this.getBusinessId();
        return this.batchCorporateTaxesByDates(dates.map(date => ({ date, corporateId: businessId })));
    });
    async batchCorporateTaxesByCorporateIds(corporateIds) {
        const taxes = await getCorporateTaxesByCorporateIds.run({ corporateIds }, this.db);
        return corporateIds.map(id => taxes.filter(expense => expense.corporate_id === id));
    }
    getCorporateTaxesByCorporateIdLoader = new DataLoader((corporateIds) => this.batchCorporateTaxesByCorporateIds(corporateIds));
    updateCorporateTax(params) {
        this.allCorporateTaxesCache = new Map();
        return updateCorporateTax.run(params, this.db);
    }
    async insertCorporateTax(params) {
        this.allCorporateTaxesCache = new Map();
        const ownerId = params.ownerId ?? (await this.getBusinessId());
        return insertCorporateTax.run({
            ...params,
            ownerId,
        }, this.db);
    }
    deleteCorporateTax(params) {
        this.allCorporateTaxesCache = new Map();
        return deleteCorporateTax.run(params, this.db);
    }
};
CorporateTaxesProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        AuthContextProvider])
], CorporateTaxesProvider);
export { CorporateTaxesProvider };
//# sourceMappingURL=corporate-taxes.provider.js.map