import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'vitest';
import { connectTestDb, closeTestDb } from '../../../../__tests__/helpers/db-connection.js';
import { runMigrationsIfNeeded } from '../../../../__tests__/helpers/db-migrations.js';
import { DBProvider } from '../../../app-providers/db.provider.js';
import { TenantAwareDBClient } from '../../../app-providers/tenant-db-client.js';
import { FiatExchangeProvider } from '../../../exchange-rates/providers/fiat-exchange.provider.js';
import { ScraperIngestionProvider } from '../scraper-ingestion.provider.js';
let pool;
let provider;
const TRIGGER_TABLES = [
    'cal_creditcard_transactions',
    'bank_discount_transactions',
    'max_creditcard_transactions',
];
function createMockAuthContextProvider() {
    return {
        getAuthContext: () => Promise.resolve({
            authType: 'apiKey',
            token: 'test-token',
            tenant: { businessId: '00000000-0000-0000-0000-000000000000' },
            user: {
                userId: 'api-key:test',
                auth0UserId: null,
                email: '',
                roleId: 'admin',
                permissions: [],
                emailVerified: true,
                permissionsVersion: 0,
            },
        }),
    };
}
beforeAll(async () => {
    pool = await connectTestDb();
    await runMigrationsIfNeeded(pool);
    const dbProvider = new DBProvider(pool);
    const dbClient = new TenantAwareDBClient(dbProvider, createMockAuthContextProvider());
    const fiatExchangeProvider = new FiatExchangeProvider(dbProvider);
    // Stub the DataLoader so it returns null for any date (no pre-existing rates in test DB)
    fiatExchangeProvider.getExchangeRatesByDatesLoader = {
        loadMany: async (dates) => dates.map(() => null),
    };
    provider = new ScraperIngestionProvider(dbClient, fiatExchangeProvider);
    // Disable triggers so inserts don't cascade into charges/transactions,
    // which require financial_accounts and owner_id to be set up.
    for (const table of TRIGGER_TABLES) {
        await pool.query(`ALTER TABLE accounter_schema.${table} DISABLE TRIGGER ALL`);
    }
});
afterAll(async () => {
    for (const table of TRIGGER_TABLES) {
        await pool.query(`ALTER TABLE accounter_schema.${table} ENABLE TRIGGER ALL`);
    }
    await closeTestDb();
});
// ── Helpers ────────────────────────────────────────────────────────────────────
async function truncate(table) {
    await pool.query(`TRUNCATE TABLE accounter_schema.${table} CASCADE`);
}
// ── Cal ───────────────────────────────────────────────────────────────────────
describe('uploadCalTransactions', () => {
    beforeEach(() => truncate('cal_creditcard_transactions'));
    const baseTx = {
        trnIntId: 'CAL-TXN-001',
        card: 4321,
        merchantName: 'Cal Store',
        trnAmt: '150.00',
        trnCurrencySymbol: 'ILS',
        debCrdCurrencySymbol: 'ILS',
    };
    it('inserts new cal transactions', async () => {
        const result = await provider.uploadCalTransactions([baseTx]);
        expect(result.inserted).toBe(1);
        expect(result.skipped).toBe(0);
    });
    it('skips duplicate cal transactions by trnIntId', async () => {
        await provider.uploadCalTransactions([baseTx]);
        const result = await provider.uploadCalTransactions([baseTx]);
        expect(result.inserted).toBe(0);
        expect(result.skipped).toBe(1);
    });
    it('inserts two transactions with different trnIntId', async () => {
        const tx2 = { ...baseTx, trnIntId: 'CAL-TXN-002' };
        const result = await provider.uploadCalTransactions([baseTx, tx2]);
        expect(result.inserted).toBe(2);
        expect(result.skipped).toBe(0);
    });
});
// ── Discount ──────────────────────────────────────────────────────────────────
describe('uploadDiscountTransactions', () => {
    beforeEach(() => truncate('bank_discount_transactions'));
    const baseTx = {
        urn: 'DISCOUNT-URN-001',
        accountNumber: 'ACC-001',
        operationDate: '2024-01-15',
        operationAmount: '300.00',
        operationDescription: 'Transfer',
    };
    it('inserts new discount transactions', async () => {
        const result = await provider.uploadDiscountTransactions([baseTx]);
        expect(result.inserted).toBe(1);
        expect(result.skipped).toBe(0);
    });
    it('skips duplicate discount transactions by urn + accountNumber', async () => {
        await provider.uploadDiscountTransactions([baseTx]);
        const result = await provider.uploadDiscountTransactions([baseTx]);
        expect(result.inserted).toBe(0);
        expect(result.skipped).toBe(1);
    });
    it('inserts same urn with different accountNumber', async () => {
        const tx2 = { ...baseTx, accountNumber: 'ACC-002' };
        const result = await provider.uploadDiscountTransactions([baseTx, tx2]);
        expect(result.inserted).toBe(2);
        expect(result.skipped).toBe(0);
    });
});
// ── Max ───────────────────────────────────────────────────────────────────────
describe('uploadMaxTransactions', () => {
    beforeEach(() => truncate('max_creditcard_transactions'));
    const baseTx = {
        uid: 'MAX-UID-001',
        merchantName: 'Max Store',
        merchant: 'Max Store',
        originalAmount: '400.00',
        originalCurrency: 'ILS',
        purchaseDate: '2024-01-15',
        paymentDate: '2024-02-15',
        cardIndex: 1,
        categoryId: 100,
        planName: 'regular',
        planTypeId: 1,
        actualPaymentAmount: '400.00',
        arn: 'ARN-001',
        comments: '',
        dealDataAcq: '',
        dealDataAdjustmentType: '0',
        dealDataAmount: '400.00',
        dealDataAmountIls: '400.00',
        dealDataAmountLeft: '0',
        dealDataArn: 'ARN-001',
        dealDataAuthorizationNumber: '000000',
        dealDataCommissionVat: '0',
        dealDataExchangeDirect: 'N',
        dealDataExchangeRate: '1',
        dealDataInterestAmount: '0',
        dealDataIsAllowedSpreadWithBenefit: 0,
        dealDataIssuerCurrency: 'ILS',
        dealDataPlan: '0',
        dealDataPosEntryEmv: '0',
        dealDataProcessingDate: '2024-01-15',
        dealDataRefNbr: 'REF001',
        dealDataShowCancelDebit: 0,
        dealDataShowSpread: 0,
        dealDataShowSpreadBenefitButton: 0,
        dealDataShowSpreadButton: 0,
        dealDataShowSpreadForLeumi: 0,
        dealDataTdmCardToken: '',
        dealDataTdmTransactionType: 0,
        dealDataTransactionType: 0,
        dealDataTxnCode: 0,
        dealDataUserName: '',
        dealDataWithdrawalCommissionAmount: '0',
        ethocaInd: 0,
        isRegisterCh: 0,
        isSpreadingAutorizationAllowed: 0,
        issuerId: 0,
        merchantMaxPhone: 0,
        merchantNumber: '0',
        merchantPhone: '',
        merchantTaxId: '',
        promotionClub: '',
        refIndex: 0,
        runtimeReferenceInternalId: '',
        runtimeReferenceType: 0,
        spreadTransactionByCampainInd: 0,
        tableType: 0,
        userIndex: 0,
    };
    it('inserts new max transactions', async () => {
        const result = await provider.uploadMaxTransactions([baseTx]);
        expect(result.inserted).toBe(1);
        expect(result.skipped).toBe(0);
    });
    it('skips duplicate max transactions by uid', async () => {
        await provider.uploadMaxTransactions([baseTx]);
        const result = await provider.uploadMaxTransactions([baseTx]);
        expect(result.inserted).toBe(0);
        expect(result.skipped).toBe(1);
    });
});
// ── Currency Rates ────────────────────────────────────────────────────────────
describe('uploadCurrencyRates', () => {
    beforeEach(() => truncate('exchange_rates'));
    const baseRate = {
        exchangeDate: '2024-01-15',
        usd: 3.712,
        eur: 4.01,
        gbp: 4.65,
    };
    it('inserts new currency rates', async () => {
        const result = await provider.uploadCurrencyRates([baseRate]);
        expect(result.inserted).toBe(1);
        expect(result.skipped).toBe(0);
    });
    it('skips duplicate currency rates by exchangeDate', async () => {
        await provider.uploadCurrencyRates([baseRate]);
        const result = await provider.uploadCurrencyRates([baseRate]);
        expect(result.inserted).toBe(0);
        expect(result.skipped).toBe(1);
    });
    it('inserts rates for different dates', async () => {
        const rate2 = { ...baseRate, exchangeDate: '2024-01-16', usd: 3.72 };
        const result = await provider.uploadCurrencyRates([baseRate, rate2]);
        expect(result.inserted).toBe(2);
        expect(result.skipped).toBe(0);
    });
    it('returns empty result for empty input', async () => {
        const result = await provider.uploadCurrencyRates([]);
        expect(result).toEqual({ inserted: 0, skipped: 0, insertedIds: [], changedTransactions: [], insertedTransactions: [] });
    });
});
//# sourceMappingURL=scraper-ingestion.integration.test.js.map