import { __decorate, __metadata } from "tslib";
import DataLoader from 'dataloader';
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { dateToTimelessDateString, getCacheInstance } from '../../../shared/helpers/index.js';
import { DBProvider } from '../../app-providers/db.provider.js';
const getExchangeRatesByDate = sql `
    select *
    from accounter_schema.exchange_rates
    where exchange_date <= to_date($date, 'YYYY-MM-DD') 
    order by exchange_date desc limit 1;
  `;
const getExchangeRatesByDates = sql `
    SELECT *
    FROM accounter_schema.exchange_rates
    WHERE
      exchange_date BETWEEN (
        SELECT exchange_date FROM accounter_schema.exchange_rates
        WHERE exchange_date <= to_date($fromDate, 'YYYY-MM-DD')
        ORDER BY exchange_date DESC LIMIT 1
      )
      AND to_date($toDate, 'YYYY-MM-DD') 
    ORDER BY exchange_date DESC;
  `;
let FiatExchangeProvider = class FiatExchangeProvider {
    dbProvider;
    cache = getCacheInstance({
        stdTTL: 60 * 60 * 24, // 24 hours
    });
    constructor(dbProvider) {
        this.dbProvider = dbProvider;
    }
    async getExchangeRates(date) {
        const formattedDate = dateToTimelessDateString(date);
        try {
            const cached = this.cache.get(formattedDate);
            if (cached) {
                return Promise.resolve(cached);
            }
            const [result] = await getExchangeRatesByDate.run({ date: formattedDate }, this.dbProvider);
            this.cache.set(formattedDate, result);
            return result;
        }
        catch (error) {
            const message = `Error fetching exchange rates for date ${formattedDate}`;
            console.error(`${message}: ${error}`);
            throw new Error(message, { cause: error });
        }
    }
    async batchExchangeRatesByDates(dates) {
        const fromDate = dateToTimelessDateString(new Date(Math.min(...dates.map(d => d.getTime()))));
        const toDate = dateToTimelessDateString(new Date(Math.max(...dates.map(d => d.getTime()))));
        const rates = await getExchangeRatesByDates.run({
            fromDate,
            toDate,
        }, this.dbProvider);
        return dates.map(date => {
            const stringifiedDate = dateToTimelessDateString(date);
            return rates
                .filter(rate => dateToTimelessDateString(rate.exchange_date) <= stringifiedDate)
                .reduce((prev, curr) => (prev.exchange_date?.getTime() ?? 0) > (curr.exchange_date?.getTime() ?? 0) ? prev : curr);
        });
    }
    getExchangeRatesByDatesLoader = new DataLoader((keys) => this.batchExchangeRatesByDates(keys), {
        cacheKeyFn: key => dateToTimelessDateString(key),
        cacheMap: this.cache,
    });
    clearCache() {
        this.cache.clear();
    }
};
FiatExchangeProvider = __decorate([
    Injectable({
        scope: Scope.Singleton,
        global: true,
    }),
    __metadata("design:paramtypes", [DBProvider])
], FiatExchangeProvider);
export { FiatExchangeProvider };
//# sourceMappingURL=fiat-exchange.provider.js.map