import { createHash } from 'node:crypto';
import { createLogger } from '../diagnostics/logger.js';
const logger = createLogger('billing');
function resolveMeterConfig(kind) {
    const secretKey = process.env.STRIPE_SECRET_KEY?.trim();
    const customerId = process.env.STRIPE_BILLING_CUSTOMER_ID?.trim();
    if (!secretKey || !customerId)
        return null;
    const eventName = kind === 'ai_tokens'
        ? process.env.STRIPE_METER_AI_TOKENS?.trim()
        : process.env.STRIPE_METER_SEO_CALLS?.trim();
    if (!eventName)
        return null;
    return { secretKey, customerId, eventName };
}
function buildIdempotencyKey(parts) {
    const raw = parts.filter((p) => p !== undefined && p !== '').join(':');
    return createHash('sha256').update(raw).digest('hex').slice(0, 32);
}
/** Fire-and-forget Stripe Billing Meter event. No-op when billing env is unset. Never throws. */
export async function emitUsageMeterEvent(event) {
    const config = resolveMeterConfig(event.kind);
    if (!config || event.quantity <= 0)
        return;
    const body = new URLSearchParams({
        event_name: config.eventName,
        identifier: event.idempotencyKey,
        'payload[stripe_customer_id]': config.customerId,
        'payload[value]': String(Math.round(event.quantity)),
    });
    if (event.userId)
        body.set('payload[actuate_user_id]', event.userId);
    if (event.metadata) {
        for (const [key, value] of Object.entries(event.metadata)) {
            if (value)
                body.set(`payload[${key}]`, value);
        }
    }
    try {
        const res = await fetch('https://api.stripe.com/v1/billing/meter_events', {
            method: 'POST',
            headers: {
                Authorization: `Bearer ${config.secretKey}`,
                'Content-Type': 'application/x-www-form-urlencoded',
            },
            body: body.toString(),
        });
        if (!res.ok) {
            const text = await res.text().catch(() => '');
            logger.warn('Stripe meter event rejected', {
                kind: event.kind,
                status: res.status,
                body: text.slice(0, 200),
            });
        }
    }
    catch (err) {
        logger.warn('Stripe meter event failed', {
            kind: event.kind,
            error: err instanceof Error ? err.message : String(err),
        });
    }
}
export function emitAiTokenMeterEvent(input) {
    void emitUsageMeterEvent({
        kind: 'ai_tokens',
        quantity: input.totalTokens,
        userId: input.userId,
        idempotencyKey: buildIdempotencyKey([
            'ai_tokens',
            input.userId,
            input.featureKey,
            input.modelId,
            input.totalTokens,
            Date.now(),
        ]),
        metadata: {
            feature: input.featureKey,
            model: input.modelId,
        },
    });
}
export function emitSeoAiCallMeterEvent(input) {
    void emitUsageMeterEvent({
        kind: 'seo_ai_calls',
        quantity: 1,
        userId: input.userId,
        idempotencyKey: buildIdempotencyKey([
            'seo_ai_calls',
            input.userId,
            input.action,
            input.issueId,
            Date.now(),
        ]),
        metadata: {
            action: input.action,
            ...(input.issueId ? { issue_id: input.issueId } : {}),
        },
    });
}
//# sourceMappingURL=stripe-meter.js.map