import { beforeEach, describe, expect, it, vi } from 'vitest';
import { AdminContextProvider } from '../providers/admin-context.provider.js';
const asQueryResult = (rows) => ({ rows, rowCount: rows.length });
describe('AdminContextProvider', () => {
    let provider;
    let dbProvider;
    let authContextProvider;
    beforeEach(() => {
        dbProvider = {
            pool: {
                query: vi.fn(),
            },
            healthCheck: vi.fn(),
            query: vi.fn(),
        };
        const mockAuthContext = {
            authType: 'jwt',
            tenant: {
                businessId: 'test-owner-id',
            },
        };
        authContextProvider = {
            getAuthContext: vi.fn().mockResolvedValue(mockAuthContext),
        };
        // Inject mocks: authContextProvider (for auth context) and dbProvider
        provider = new AdminContextProvider(authContextProvider, dbProvider);
    });
    it('should fetch admin context for the current user', async () => {
        dbProvider.query.mockResolvedValue({
            rows: [{ owner_id: 'test-owner-id', default_local_currency: 'USD' }],
            rowCount: 1,
        });
        const result = await provider.getAdminContext();
        expect(result).toBeDefined();
        expect(result?.defaultLocalCurrency).toBe('USD');
        expect(dbProvider.query).toHaveBeenCalled();
    });
    it('should prefer single-business active scope over primary tenant business', async () => {
        const scopedOwnerId = 'scoped-owner-id';
        const primaryOwnerId = 'primary-owner-id';
        authContextProvider.getAuthContext.mockResolvedValue({
            authType: 'jwt',
            tenant: {
                businessId: primaryOwnerId,
            },
            activeReadScope: {
                businessIds: [scopedOwnerId],
            },
        });
        dbProvider.query.mockImplementation((_statement, values) => {
            const serializedValues = JSON.stringify(values ?? []);
            if (serializedValues.includes(scopedOwnerId)) {
                return Promise.resolve(asQueryResult([{ owner_id: scopedOwnerId, default_local_currency: 'USD' }]));
            }
            return Promise.resolve(asQueryResult([]));
        });
        const result = await provider.getVerifiedAdminContext();
        expect(result.ownerId).toBe(scopedOwnerId);
    });
    it('should prefer primary tenant business when it is inside multi-business active scope', async () => {
        const primaryOwnerId = 'primary-owner-id';
        authContextProvider.getAuthContext.mockResolvedValue({
            authType: 'jwt',
            tenant: {
                businessId: primaryOwnerId,
            },
            activeReadScope: {
                businessIds: ['scope-owner-a', primaryOwnerId, 'scope-owner-b'],
            },
        });
        dbProvider.query.mockImplementation((_statement, values) => {
            const serializedValues = JSON.stringify(values ?? []);
            if (serializedValues.includes(primaryOwnerId)) {
                return Promise.resolve(asQueryResult([{ owner_id: primaryOwnerId, default_local_currency: 'USD' }]));
            }
            return Promise.resolve(asQueryResult([]));
        });
        const result = await provider.getVerifiedAdminContext();
        expect(result.ownerId).toBe(primaryOwnerId);
    });
    it('should fallback to first scoped business when primary tenant business is outside active scope', async () => {
        const primaryOwnerId = 'primary-owner-id';
        const firstScopedOwnerId = 'scope-owner-a';
        authContextProvider.getAuthContext.mockResolvedValue({
            authType: 'jwt',
            tenant: {
                businessId: primaryOwnerId,
            },
            activeReadScope: {
                businessIds: [firstScopedOwnerId, 'scope-owner-b'],
            },
        });
        dbProvider.query.mockImplementation((_statement, values) => {
            const serializedValues = JSON.stringify(values ?? []);
            if (serializedValues.includes(firstScopedOwnerId)) {
                return Promise.resolve(asQueryResult([{ owner_id: firstScopedOwnerId, default_local_currency: 'USD' }]));
            }
            return Promise.resolve(asQueryResult([]));
        });
        const result = await provider.getVerifiedAdminContext();
        expect(result.ownerId).toBe(firstScopedOwnerId);
    });
    it('should use single-business active scope when updating admin context', async () => {
        const scopedOwnerId = 'scoped-owner-id';
        const primaryOwnerId = 'primary-owner-id';
        authContextProvider.getAuthContext.mockResolvedValue({
            authType: 'jwt',
            tenant: {
                businessId: primaryOwnerId,
            },
            activeReadScope: {
                businessIds: [scopedOwnerId],
            },
        });
        dbProvider.query.mockImplementation((_statement, values) => {
            const serializedValues = JSON.stringify(values ?? []);
            if (serializedValues.includes(scopedOwnerId)) {
                return Promise.resolve(asQueryResult([{ owner_id: scopedOwnerId, default_local_currency: 'EUR' }]));
            }
            return Promise.resolve(asQueryResult([]));
        });
        const result = await provider.updateAdminContext({ defaultLocalCurrency: 'EUR' });
        expect(result?.ownerId).toBe(scopedOwnerId);
        expect(result?.defaultLocalCurrency).toBe('EUR');
    });
    it('should cache the result', async () => {
        dbProvider.query.mockResolvedValue({
            rows: [{ owner_id: 'test-owner-id' }],
            rowCount: 1,
        });
        await provider.getAdminContext();
        await provider.getAdminContext();
        expect(dbProvider.query).toHaveBeenCalledTimes(1);
    });
    it('should invalidate cache on update', async () => {
        dbProvider.query.mockResolvedValueOnce({
            rows: [{ owner_id: 'test-owner-id', default_local_currency: 'USD' }],
            rowCount: 1,
        }); // get
        await provider.getAdminContext();
        expect(dbProvider.query).toHaveBeenCalledTimes(1);
        dbProvider.query.mockResolvedValueOnce({
            rows: [{ owner_id: 'test-owner-id', default_local_currency: 'EUR' }],
            rowCount: 1
        }); // update
        await provider.updateAdminContext({ defaultLocalCurrency: 'EUR' });
        expect(dbProvider.query).toHaveBeenCalledTimes(2); // +1 for update
        // The cache should now have the updated value from updateAdminContext
        const result = await provider.getAdminContext();
        expect(result?.defaultLocalCurrency).toBe('EUR');
        expect(dbProvider.query).toHaveBeenCalledTimes(2); // No additional call, using cache
    });
});
//# sourceMappingURL=admin-context.provider.test.js.map