import { describe, expect, it, vi } from 'vitest';
import { emailIngestionModule } from '../index.js';
import { gmailListenerModule } from '../../gmail-listener/index.js';
import { emailIngestionResolvers } from '../resolvers/email-ingestion.resolver.js';
import { BusinessesProvider } from '../../financial-entities/providers/businesses.provider.js';
import { AdminContextProvider } from '../../admin-context/providers/admin-context.provider.js';
import { DocumentsProvider } from '../../documents/providers/documents.provider.js';
import { ChargesProvider } from '../../charges/providers/charges.provider.js';
import { TenantAwareDBClient } from '../../app-providers/tenant-db-client.js';
function createMockInjector(providers = {}) {
    const businessesProvider = {
        getBusinessByEmail: vi.fn().mockResolvedValue(null),
        ...providers.businessesProvider,
    };
    const adminContextProvider = {
        getVerifiedAdminContext: vi.fn().mockResolvedValue({ ownerId: 'owner-1' }),
        ...providers.adminContextProvider,
    };
    const documentsProvider = {
        getDocumentByHash: { load: vi.fn().mockResolvedValue(null) },
        insertDocuments: vi.fn().mockResolvedValue([]),
        ...providers.documentsProvider,
    };
    const chargesProvider = {
        generateCharge: vi.fn().mockResolvedValue({ id: 'charge-1' }),
        ...providers.chargesProvider,
    };
    const dbClient = {
        transaction: vi.fn().mockImplementation(async (fn) => fn({})),
        ...providers.dbClient,
    };
    return {
        get: (token) => {
            if (token === BusinessesProvider)
                return businessesProvider;
            if (token === AdminContextProvider)
                return adminContextProvider;
            if (token === DocumentsProvider)
                return documentsProvider;
            if (token === ChargesProvider)
                return chargesProvider;
            if (token === TenantAwareDBClient)
                return dbClient;
            throw new Error(`Unexpected provider: ${String(token)}`);
        },
    };
}
// ---------------------------------------------------------------------------
// Module structure and S02 naming guards
// ---------------------------------------------------------------------------
describe('emailIngestionModule', () => {
    it('has the correct module id', () => {
        expect(emailIngestionModule.id).toBe('email-ingestion');
    });
    it('exports CommonTypes namespace', async () => {
        const { CommonTypes } = await import('../index.js');
        expect(CommonTypes).toBeDefined();
    });
    // S02 guard: emailIngestionModule must be exported directly from
    // email-ingestion, not only via the gmail-listener shim.
    // This test fails if the export is removed or renamed back.
    it('is directly exported from email-ingestion (not only via gmail-listener shim)', () => {
        expect(emailIngestionModule).toBeDefined();
        expect(emailIngestionModule.id).toBe('email-ingestion');
    });
});
// S02 guard: resolver identifiers use email-ingestion naming.
// These tests fail if the canonical exports are removed or reverted to old names.
describe('emailIngestionResolvers (S02 naming guard)', () => {
    it('is exported from the email-ingestion resolver module', () => {
        expect(emailIngestionResolvers).toBeDefined();
    });
    it('provides Query.businessEmailConfig resolver', () => {
        expect(emailIngestionResolvers.Query?.businessEmailConfig).toBeDefined();
    });
    it('provides Mutation.insertEmailDocuments resolver', () => {
        expect(emailIngestionResolvers.Mutation?.insertEmailDocuments).toBeDefined();
    });
});
// ---------------------------------------------------------------------------
// Backward-compat shim (explicit adapter — not new code)
// ---------------------------------------------------------------------------
describe('gmailListenerModule (backward-compat shim)', () => {
    it('is the same module instance as emailIngestionModule', () => {
        expect(gmailListenerModule).toBe(emailIngestionModule);
    });
});
// ---------------------------------------------------------------------------
// businessEmailConfig resolver
// ---------------------------------------------------------------------------
describe('businessEmailConfig resolver', () => {
    const resolver = emailIngestionResolvers.Query.businessEmailConfig;
    it('returns null when no business matches the email', async () => {
        const injector = createMockInjector({
            businessesProvider: { getBusinessByEmail: vi.fn().mockResolvedValue(null) },
        });
        const result = await resolver({}, { email: 'unknown@example.com' }, { injector }, {});
        expect(result).toBeNull();
    });
    it('returns businessId and empty config when business has no suggestion_data', async () => {
        const injector = createMockInjector({
            businessesProvider: {
                getBusinessByEmail: vi.fn().mockResolvedValue({
                    id: 'biz-1',
                    name: 'Test Business',
                    suggestion_data: null,
                }),
            },
        });
        const result = await resolver({}, { email: 'test@example.com' }, { injector }, {});
        expect(result).toMatchObject({ businessId: 'biz-1' });
        expect(result?.internalEmailLinks).toBeUndefined();
        expect(result?.emailBody).toBeUndefined();
    });
    it('returns emailListener config from valid suggestion_data', async () => {
        const suggestionData = {
            emailListener: {
                internalEmailLinks: ['partner@example.com'],
                emailBody: true,
                attachments: [],
            },
        };
        const injector = createMockInjector({
            businessesProvider: {
                getBusinessByEmail: vi.fn().mockResolvedValue({
                    id: 'biz-2',
                    name: 'Test Business',
                    suggestion_data: suggestionData,
                }),
            },
        });
        const result = await resolver({}, { email: 'test@example.com' }, { injector }, {});
        expect(result).toMatchObject({
            businessId: 'biz-2',
            internalEmailLinks: ['partner@example.com'],
            emailBody: true,
            attachments: [],
        });
    });
});
// ---------------------------------------------------------------------------
// insertEmailDocuments resolver
// ---------------------------------------------------------------------------
describe('insertEmailDocuments resolver', () => {
    const resolver = emailIngestionResolvers.Mutation.insertEmailDocuments;
    it('returns true immediately when documents array is empty', async () => {
        const injector = createMockInjector();
        const result = await resolver({}, { documents: [], userDescription: 'test', messageId: null, businessId: null }, { injector }, {});
        expect(result).toBe(true);
    });
    it('skips a document that already exists in the database (dedup by hash)', async () => {
        const existingDoc = { id: 'doc-existing' };
        const mockDoc = {
            text: vi.fn().mockResolvedValue('document-content'),
            name: 'invoice.pdf',
        };
        const insertDocuments = vi.fn().mockResolvedValue([]);
        const injector = createMockInjector({
            documentsProvider: {
                getDocumentByHash: { load: vi.fn().mockResolvedValue(existingDoc) },
                insertDocuments,
            },
        });
        const result = await resolver({}, { documents: [mockDoc], userDescription: 'test', messageId: 'msg-1', businessId: null }, { injector }, {});
        expect(result).toBe(true);
        expect(insertDocuments).not.toHaveBeenCalled();
    });
});
//# sourceMappingURL=email-ingestion.module.test.js.map