import { __decorate, __metadata } from "tslib";
import { Injectable, Scope } from 'graphql-modules';
import { sql } from '@pgtyped/runtime';
import { dateToTimelessDateString } from '../../../shared/helpers/index.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
import { FiatExchangeProvider } from '../../exchange-rates/providers/fiat-exchange.provider.js';
import { formatValue } from '../helpers/utils.helper.js';
import { validateCalTransactions, validateDiscountTransactions, validateMaxTransactions, validateRates, } from '../helpers/validators.helper.js';
const uploadCalTransactions = sql `
  INSERT INTO accounter_schema.cal_creditcard_transactions (
    card,
    trn_int_id,
    trn_numaretor,
    merchant_name,
    trn_purchase_date,
    trn_amt,
    trn_currency_symbol,
    trn_type,
    trn_type_code,
    deb_crd_date,
    amt_before_conv_and_index,
    deb_crd_currency_symbol,
    merchant_address,
    merchant_phone_no,
    branch_code_desc,
    trans_card_present_ind,
    cur_payment_num,
    num_of_payments,
    token_ind,
    wallet_provider_code,
    wallet_provider_desc,
    token_number_part4,
    cash_account_trn_amt,
    charge_external_to_card_comment,
    refund_ind,
    is_immediate_comment_ind,
    is_immediate_hhk_ind,
    is_margarita,
    is_spread_paymenst_abroad,
    trn_exac_way,
    debit_spread_ind,
    on_going_transactions_comment,
    early_payment_ind,
    merchant_id,
    crd_ext_id_num_type_code,
    trans_source,
    is_abroad_transaction
  )
  VALUES $$transactions(
    card,
    trnIntId,
    trnNumaretor,
    merchantName,
    trnPurchaseDate,
    trnAmt,
    trnCurrencySymbol,
    trnType,
    trnTypeCode,
    debCrdDate,
    amtBeforeConvAndIndex,
    debCrdCurrencySymbol,
    merchantAddress,
    merchantPhoneNo,
    branchCodeDesc,
    transCardPresentInd,
    curPaymentNum,
    numOfPayments,
    tokenInd,
    walletProviderCode,
    walletProviderDesc,
    tokenNumberPart4,
    cashAccountTrnAmt,
    chargeExternalToCardComment,
    refundInd,
    isImmediateCommentInd,
    isImmediateHhkInd,
    isMargarita,
    isSpreadPaymenstAbroad,
    trnExacWay,
    debitSpreadInd,
    onGoingTransactionsComment,
    earlyPaymentInd,
    merchantId,
    crdExtIdNumTypeCode,
    transSource,
    isAbroadTransaction
  )
  ON CONFLICT (trn_int_id) DO NOTHING
  RETURNING id, trn_purchase_date, merchant_name, trn_amt, card;
`;
const uploadDiscountTransactions = sql `
  INSERT INTO accounter_schema.bank_discount_transactions (
    operation_date,
    value_date,
    operation_code,
    operation_description,
    operation_description2,
    operation_description3,
    operation_branch,
    operation_bank,
    account_number,
    channel,
    channel_name,
    check_number,
    institute_code,
    operation_amount,
    balance_after_operation,
    operation_number,
    branch_treasury_number,
    urn,
    operation_details_service_name,
    commission_channel_code,
    commission_channel_name,
    commission_type_name,
    business_day_date,
    event_name,
    category_code,
    category_desc_code,
    category_description,
    operation_description_to_display,
    operation_order,
    is_last_seen
  )
  VALUES $$transactions(
    operationDate,
    valueDate,
    operationCode,
    operationDescription,
    operationDescription2,
    operationDescription3,
    operationBranch,
    operationBank,
    accountNumber,
    channel,
    channelName,
    checkNumber,
    instituteCode,
    operationAmount,
    balanceAfterOperation,
    operationNumber,
    branchTreasuryNumber,
    urn,
    operationDetailsServiceName,
    commissionChannelCode,
    commissionChannelName,
    commissionTypeName,
    businessDayDate,
    eventName,
    categoryCode,
    categoryDescCode,
    categoryDescription,
    operationDescriptionToDisplay,
    operationOrder,
    isLastSeen
  )
  ON CONFLICT (urn, account_number) WHERE urn IS NOT NULL AND account_number IS NOT NULL DO NOTHING
  RETURNING id, operation_date, operation_description, operation_amount, account_number;
`;
const uploadMaxTransactions = sql `
  INSERT INTO accounter_schema.max_creditcard_transactions (
    actual_payment_amount,
    arn,
    card_index,
    category_id,
    comments,
    deal_data_acq,
    deal_data_adjustment_amount,
    deal_data_adjustment_type,
    deal_data_amount,
    deal_data_amount_ils,
    deal_data_amount_left,
    deal_data_arn,
    deal_data_authorization_number,
    deal_data_card_name,
    deal_data_card_token,
    deal_data_commission_vat,
    deal_data_direct_exchange,
    deal_data_exchange_commission_amount,
    deal_data_exchange_commission_maam,
    deal_data_exchange_commission_type,
    deal_data_exchange_direct,
    deal_data_exchange_rate,
    deal_data_index_rate_base,
    deal_data_index_rate_pmt,
    deal_data_interest_amount,
    deal_data_is_allowed_spread_with_benefit,
    deal_data_issuer_currency,
    deal_data_issuer_exchange_rate,
    deal_data_original_term,
    deal_data_percent_maam,
    deal_data_plan,
    deal_data_pos_entry_emv,
    deal_data_processing_date,
    deal_data_purchase_amount,
    deal_data_purchase_time,
    deal_data_ref_nbr,
    deal_data_show_cancel_debit,
    deal_data_show_spread,
    deal_data_show_spread_benefit_button,
    deal_data_show_spread_button,
    deal_data_show_spread_for_leumi,
    deal_data_tdm_card_token,
    deal_data_tdm_transaction_type,
    deal_data_transaction_type,
    deal_data_txn_code,
    deal_data_user_name,
    deal_data_withdrawal_commission_amount,
    discount_key_amount,
    discount_key_rec_type,
    ethoca_ind,
    funds_transfer_comment,
    funds_transfer_receiver_or_transfer,
    is_register_ch,
    is_spreading_autorization_allowed,
    issuer_id,
    merchant_address,
    merchant_coordinates,
    merchant_max_phone,
    merchant,
    merchant_commercial_name,
    merchant_number,
    merchant_phone,
    merchant_tax_id,
    merchant_name,
    original_amount,
    original_currency,
    payment_currency,
    payment_date,
    plan_name,
    plan_type_id,
    promotion_amount,
    promotion_club,
    promotion_type,
    purchase_date,
    receipt_p_d_f,
    ref_index,
    runtime_reference_internal_id,
    runtime_reference_type,
    runtime_reference_id,
    short_card_number,
    spread_transaction_by_campain_ind,
    spread_transaction_by_campain_number,
    table_type,
    tag,
    uid,
    up_sale_for_transaction_result,
    user_index
  )
  VALUES $$transactions(
    actualPaymentAmount,
    arn,
    cardIndex,
    categoryId,
    comments,
    dealDataAcq,
    dealDataAdjustmentAmount,
    dealDataAdjustmentType,
    dealDataAmount,
    dealDataAmountIls,
    dealDataAmountLeft,
    dealDataArn,
    dealDataAuthorizationNumber,
    dealDataCardName,
    dealDataCardToken,
    dealDataCommissionVat,
    dealDataDirectExchange,
    dealDataExchangeCommissionAmount,
    dealDataExchangeCommissionMaam,
    dealDataExchangeCommissionType,
    dealDataExchangeDirect,
    dealDataExchangeRate,
    dealDataIndexRateBase,
    dealDataIndexRatePmt,
    dealDataInterestAmount,
    dealDataIsAllowedSpreadWithBenefit,
    dealDataIssuerCurrency,
    dealDataIssuerExchangeRate,
    dealDataOriginalTerm,
    dealDataPercentMaam,
    dealDataPlan,
    dealDataPosEntryEmv,
    dealDataProcessingDate,
    dealDataPurchaseAmount,
    dealDataPurchaseTime,
    dealDataRefNbr,
    dealDataShowCancelDebit,
    dealDataShowSpread,
    dealDataShowSpreadBenefitButton,
    dealDataShowSpreadButton,
    dealDataShowSpreadForLeumi,
    dealDataTdmCardToken,
    dealDataTdmTransactionType,
    dealDataTransactionType,
    dealDataTxnCode,
    dealDataUserName,
    dealDataWithdrawalCommissionAmount,
    discountKeyAmount,
    discountKeyRecType,
    ethocaInd,
    fundsTransferComment,
    fundsTransferReceiverOrTransfer,
    isRegisterCh,
    isSpreadingAutorizationAllowed,
    issuerId,
    merchantAddress,
    merchantCoordinates,
    merchantMaxPhone,
    merchant,
    merchantCommercialName,
    merchantNumber,
    merchantPhone,
    merchantTaxId,
    merchantName,
    originalAmount,
    originalCurrency,
    paymentCurrency,
    paymentDate,
    planName,
    planTypeId,
    promotionAmount,
    promotionClub,
    promotionType,
    purchaseDate,
    receiptPDF,
    refIndex,
    runtimeReferenceInternalId,
    runtimeReferenceType,
    runtimeReferenceId,
    shortCardNumber,
    spreadTransactionByCampainInd,
    spreadTransactionByCampainNumber,
    tableType,
    tag,
    uid,
    upSaleForTransactionResult,
    userIndex
  )
  ON CONFLICT (uid, arn, purchase_date, payment_date, original_amount) DO NOTHING
  RETURNING id, purchase_date, merchant_name, actual_payment_amount, card_index;
`;
const uploadCurrencyRates = sql `
  INSERT INTO accounter_schema.exchange_rates (
    exchange_date,
    usd,
    eur,
    gbp,
    cad,
    jpy,
    aud,
    sek
  )
  VALUES $$rates(
    exchangeDate,
    usd,
    eur,
    gbp,
    cad,
    jpy,
    aud,
    sek
  )
  ON CONFLICT (exchange_date) DO NOTHING
  RETURNING exchange_date, usd, eur, gbp, cad, jpy, aud, sek;
`;
function diffExchangeRatesRow(existing, incoming) {
    const changed = [];
    for (const currency of ['aud', 'cad', 'eur', 'gbp', 'jpy', 'sek', 'usd']) {
        const oldValue = formatValue(existing[currency], true);
        const newValue = formatValue(incoming[currency], true);
        const oldStr = oldValue;
        const newStr = newValue;
        if (oldStr !== newStr) {
            changed.push({ field: currency, oldValue: String(oldStr), newValue: String(newStr) });
        }
    }
    return changed;
}
let ScraperIngestionProvider = class ScraperIngestionProvider {
    db;
    exchangeRates;
    constructor(db, exchangeRates) {
        this.db = db;
        this.exchangeRates = exchangeRates;
    }
    async uploadCalTransactions(transactions) {
        if (transactions.length === 0)
            return {
                inserted: 0,
                skipped: 0,
                insertedIds: [],
                insertedTransactions: [],
                changedTransactions: [],
            };
        const result = await uploadCalTransactions.run({ transactions: validateCalTransactions(transactions) }, this.db);
        const insertedIds = result.map(r => r.id).filter((id) => typeof id === 'string');
        const insertedTransactions = result.map(r => ({
            id: r.id,
            date: r.trn_purchase_date ?? null,
            description: r.merchant_name ?? null,
            amount: r.trn_amt == null ? null : String(r.trn_amt),
            account: String(r.card),
        }));
        return {
            inserted: insertedIds.length,
            skipped: transactions.length - insertedIds.length,
            insertedIds,
            insertedTransactions,
            changedTransactions: [],
        };
    }
    async uploadDiscountTransactions(transactions) {
        if (transactions.length === 0)
            return {
                inserted: 0,
                skipped: 0,
                insertedIds: [],
                insertedTransactions: [],
                changedTransactions: [],
            };
        const result = await uploadDiscountTransactions.run({ transactions: validateDiscountTransactions(transactions) }, this.db);
        const insertedIds = result.map(r => r.id).filter((id) => typeof id === 'string');
        const insertedTransactions = result.map(r => ({
            id: r.id,
            date: r.operation_date ?? null,
            description: r.operation_description ?? null,
            amount: r.operation_amount ?? null,
            account: r.account_number ?? null,
        }));
        return {
            inserted: insertedIds.length,
            skipped: transactions.length - insertedIds.length,
            insertedIds,
            insertedTransactions,
            changedTransactions: [],
        };
    }
    async uploadMaxTransactions(transactions) {
        if (transactions.length === 0)
            return {
                inserted: 0,
                skipped: 0,
                insertedIds: [],
                insertedTransactions: [],
                changedTransactions: [],
            };
        const result = await uploadMaxTransactions.run({ transactions: validateMaxTransactions(transactions) }, this.db);
        const insertedIds = result.map(r => r.id).filter((id) => typeof id === 'string');
        const insertedTransactions = result.map(r => ({
            id: r.id,
            date: r.purchase_date ? dateToTimelessDateString(r.purchase_date) : null,
            description: r.merchant_name ?? null,
            amount: r.actual_payment_amount == null ? null : String(r.actual_payment_amount),
            account: String(r.card_index),
        }));
        return {
            inserted: insertedIds.length,
            skipped: transactions.length - insertedIds.length,
            insertedIds,
            insertedTransactions,
            changedTransactions: [],
        };
    }
    async uploadCurrencyRates(rates) {
        if (rates.length === 0)
            return {
                inserted: 0,
                skipped: 0,
                insertedIds: [],
                insertedTransactions: [],
                changedTransactions: [],
            };
        const validated = validateRates(rates);
        const existing = await this.exchangeRates.getExchangeRatesByDatesLoader
            .loadMany(rates.map(r => new Date(r.exchangeDate)))
            .then(res => res.filter((r) => r !== null && !(r instanceof Error)));
        const existingByDate = new Map(existing.map(row => [
            row.exchange_date ? dateToTimelessDateString(row.exchange_date) : null,
            row,
        ]));
        const result = await uploadCurrencyRates.run({ rates: validated }, this.db);
        const insertedDates = result
            .map(r => (r.exchange_date ? dateToTimelessDateString(r.exchange_date) : undefined))
            .filter((date) => !!date);
        const insertedDatesSet = new Set(insertedDates);
        const insertedRates = result.map(r => {
            const date = dateToTimelessDateString(r.exchange_date);
            const description = ['usd', 'eur', 'gbp', 'cad', 'jpy', 'aud', 'sek']
                .filter(c => r[c] != null)
                .map(c => `${c.toUpperCase()}=${r[c]}`)
                .join(', ');
            return {
                id: date ?? undefined,
                date,
                description,
                amount: undefined,
                account: undefined,
            };
        });
        const changedRates = [];
        for (const r of validated) {
            if (!r.exchangeDate)
                continue;
            const date = dateToTimelessDateString(new Date(r.exchangeDate));
            const existingRow = existingByDate.get(date);
            if (existingRow?.exchange_date &&
                !insertedDatesSet.has(dateToTimelessDateString(existingRow.exchange_date))) {
                const changedFields = diffExchangeRatesRow(existingRow, r);
                if (changedFields.length > 0) {
                    changedRates.push({ id: date, changedFields });
                }
            }
        }
        return {
            inserted: insertedDates.length,
            skipped: rates.length - insertedDates.length,
            insertedIds: insertedDates,
            insertedTransactions: insertedRates,
            changedTransactions: changedRates,
        };
    }
};
ScraperIngestionProvider = __decorate([
    Injectable({
        scope: Scope.Operation,
        global: true,
    }),
    __metadata("design:paramtypes", [TenantAwareDBClient,
        FiatExchangeProvider])
], ScraperIngestionProvider);
export { ScraperIngestionProvider };
//# sourceMappingURL=scraper-ingestion.provider.js.map