import { describe, it, expect } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { Msg91SmsProviderAdapter } from '@zyphon/provider-sms-msg91';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const fixture = JSON.parse(
  fs.readFileSync(path.join(__dirname, 'fixtures/msg91/success.json'), 'utf8'),
) as { statusCode: number; body: Record<string, unknown> };

describe('MSG91 contract', () => {
  it('maps recorded success fixture to provider result', async () => {
    const fetchFn = async () =>
      new Response(JSON.stringify(fixture.body), { status: fixture.statusCode });

    const adapter = new Msg91SmsProviderAdapter({ id: 'msg91-test', fetchFn });
    const result = await adapter.send(
      {
        message_id: 'msg_contract',
        request_id: 'req_contract',
        application_id: 'app',
        channel: 'sms',
        recipient: '+919876543210',
        content: { type: 'text', body: 'Your code is 1234', template: '1107161234567890123' },
        metadata: {},
        created_at: Date.now(),
      },
      {
        auth_key: 'test-auth-key',
        sender_id: 'ACMEIN',
        pe_id: '1100123456789012345',
        route: '4',
      },
      AbortSignal.timeout(5000),
    );

    expect(result.success).toBe(true);
    expect(result.provider_reference).toBeDefined();
    expect(JSON.stringify(result)).not.toContain('test-auth-key');
  });

  it('returns CREDENTIAL_ERROR when auth key missing', async () => {
    const adapter = new Msg91SmsProviderAdapter({ id: 'msg91-test' });
    const result = await adapter.send(
      {
        message_id: 'm',
        request_id: 'r',
        application_id: 'a',
        channel: 'sms',
        recipient: '+14155550100',
        content: { type: 'text', body: 'x', template: '1107161234567890123' },
        metadata: {},
        created_at: Date.now(),
      },
      { sender_id: 'ACMEIN', pe_id: '1100123456789012345' },
      AbortSignal.timeout(1000),
    );
    expect(result.success).toBe(false);
    expect(result.error?.code).toBe('CREDENTIAL_ERROR');
  });
});
