import { clearIdempotencyStoreForTests } from '@/lib/demo/idempotency';
import type { LeadDestinationAdapter } from '@/lib/demo/adapters';
import { submitDemoLead } from '@/lib/demo/service';
import type { DemoLead } from '@/lib/demo/schema';
import type { IntegrationEnvironment } from '@/lib/integrations/environment';
import { beforeEach, describe, expect, it, vi } from 'vitest';

const environment: IntegrationEnvironment = {
  NODE_ENV: 'test',
  NEXT_PUBLIC_DEMO_ENABLED: true,
  DEMO_SUBMISSION_MODE: 'local',
  DEMO_REQUEST_TIMEOUT_MS: 250,
  DEMO_IDEMPOTENCY_TTL_SECONDS: 900,
  DEMO_TEST_SCENARIOS_ENABLED: true,
  DEMO_LOCAL_TEST_MODE: false,
  NEXT_PUBLIC_ANALYTICS_MODE: 'disabled',
};

const lead: DemoLead = {
  fullName: 'Avery Example',
  workEmail: 'avery@example.test',
  company: 'Example Rental Lab',
  fleetSize: '10-24',
  preferredLanguage: 'en',
  idempotencyKey: '6b4992d5-d88e-4e44-9b66-adc18fd8ee37',
  source: 'hero',
};

beforeEach(clearIdempotencyStoreForTests);

describe('demo submission orchestration', () => {
  it('confirms acceptance before returning success', async () => {
    const adapter: LeadDestinationAdapter = {
      name: 'test-success',
      submitLead: vi.fn(async () => ({
        ok: true as const,
        externalId: 'local_test',
        acceptedAt: '2026-06-25T00:00:00.000Z',
        mode: 'local' as const,
      })),
    };
    const result = await submitDemoLead(lead, { environment, adapter });
    expect(result.ok).toBe(true);
    expect(adapter.submitLead).toHaveBeenCalledOnce();
  });

  it('coalesces repeated transport with the same idempotency key', async () => {
    const adapter: LeadDestinationAdapter = {
      name: 'test-idempotent',
      submitLead: vi.fn(async () => ({
        ok: true as const,
        externalId: 'local_once',
        acceptedAt: '2026-06-25T00:00:00.000Z',
        mode: 'local' as const,
      })),
    };
    const [first, second] = await Promise.all([
      submitDemoLead(lead, { environment, adapter }),
      submitDemoLead(lead, { environment, adapter }),
    ]);
    expect(first).toEqual(second);
    expect(adapter.submitLead).toHaveBeenCalledOnce();
  });

  it('normalizes adapter failures without exposing vendor bodies', async () => {
    const adapter: LeadDestinationAdapter = {
      name: 'test-error',
      submitLead: async () => ({
        ok: false,
        category: 'integration',
        retryable: true,
        code: 'normalized_failure',
      }),
    };
    const result = await submitDemoLead(lead, { environment, adapter });
    expect(result).toMatchObject({
      ok: false,
      category: 'integration',
      formErrorCode: 'normalized_failure',
      retryable: true,
    });
  });

  it('bounds a hung integration with a timeout', async () => {
    const adapter: LeadDestinationAdapter = {
      name: 'test-timeout',
      submitLead: (_lead, context) =>
        new Promise((_resolve, reject) => {
          context.signal.addEventListener('abort', () =>
            reject(new DOMException('Aborted', 'AbortError')),
          );
        }),
    };
    const result = await submitDemoLead(lead, { environment, adapter });
    expect(result).toMatchObject({ ok: false, category: 'timeout', retryable: true });
  });
});
