import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
const { emitUsageMeterEvent, emitAiTokenMeterEvent, emitSeoAiCallMeterEvent } = await import('../../billing/stripe-meter.js');
describe('Stripe usage metering', () => {
    const envKeys = [
        'STRIPE_SECRET_KEY',
        'STRIPE_BILLING_CUSTOMER_ID',
        'STRIPE_METER_AI_TOKENS',
        'STRIPE_METER_SEO_CALLS',
    ];
    const savedEnv = {};
    afterEach(() => {
        for (const key of envKeys) {
            if (savedEnv[key] === undefined)
                delete process.env[key];
            else
                process.env[key] = savedEnv[key];
        }
        vi.restoreAllMocks();
    });
    beforeEach(() => {
        for (const key of envKeys) {
            savedEnv[key] = process.env[key];
        }
    });
    it('no-ops when Stripe billing env is unset', async () => {
        delete process.env.STRIPE_SECRET_KEY;
        delete process.env.STRIPE_BILLING_CUSTOMER_ID;
        const fetchSpy = vi.spyOn(globalThis, 'fetch');
        await emitUsageMeterEvent({
            kind: 'ai_tokens',
            quantity: 100,
            idempotencyKey: 'test-key',
        });
        expect(fetchSpy).not.toHaveBeenCalled();
    });
    it('posts a meter event when billing env is configured', async () => {
        process.env.STRIPE_SECRET_KEY = 'sk_test_abc';
        process.env.STRIPE_BILLING_CUSTOMER_ID = 'cus_test';
        process.env.STRIPE_METER_AI_TOKENS = 'ai_tokens';
        const fetchSpy = vi
            .spyOn(globalThis, 'fetch')
            .mockResolvedValue(new Response('{}', { status: 200 }));
        await emitUsageMeterEvent({
            kind: 'ai_tokens',
            quantity: 42,
            idempotencyKey: 'idem-123',
            userId: 'user-1',
        });
        expect(fetchSpy).toHaveBeenCalledTimes(1);
        const [url, init] = fetchSpy.mock.calls[0];
        expect(url).toBe('https://api.stripe.com/v1/billing/meter_events');
        expect(init?.method).toBe('POST');
        const headers = init?.headers;
        const authHeader = headers instanceof Headers
            ? headers.get('Authorization')
            : (headers?.Authorization ?? headers?.authorization);
        expect(authHeader).toBe('Bearer sk_test_abc');
        expect(String(init?.body)).toContain('event_name=ai_tokens');
        expect(String(init?.body)).toContain('payload%5Bvalue%5D=42');
    });
    it('emitAiTokenMeterEvent skips zero quantities', async () => {
        process.env.STRIPE_SECRET_KEY = 'sk_test_abc';
        process.env.STRIPE_BILLING_CUSTOMER_ID = 'cus_test';
        process.env.STRIPE_METER_AI_TOKENS = 'ai_tokens';
        const fetchSpy = vi.spyOn(globalThis, 'fetch');
        emitAiTokenMeterEvent({
            featureKey: 'coauthor',
            modelId: 'gpt-4',
            totalTokens: 0,
        });
        expect(fetchSpy).not.toHaveBeenCalled();
    });
    it('emitSeoAiCallMeterEvent uses the seo meter event name', async () => {
        process.env.STRIPE_SECRET_KEY = 'sk_test_abc';
        process.env.STRIPE_BILLING_CUSTOMER_ID = 'cus_test';
        process.env.STRIPE_METER_SEO_CALLS = 'seo_ai_calls';
        const fetchSpy = vi
            .spyOn(globalThis, 'fetch')
            .mockResolvedValue(new Response('{}', { status: 200 }));
        emitSeoAiCallMeterEvent({ userId: 'user-1', action: 'generate-field', issueId: 'issue-9' });
        await new Promise((resolve) => setTimeout(resolve, 0));
        expect(fetchSpy).toHaveBeenCalledTimes(1);
        expect(String(fetchSpy.mock.calls[0][1]?.body)).toContain('event_name=seo_ai_calls');
    });
});
//# sourceMappingURL=stripe-meter.test.js.map