import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import type { RedisConfig } from '../src/types';
import { getRedisConnection } from '../src/utils';

describe('Queue Utils', () => {
  describe('getRedisConnection', () => {
    const originalEnv = process.env;

    beforeEach(() => {
      process.env = { ...originalEnv };
    });

    afterEach(() => {
      process.env = originalEnv;
    });

    it('should return test connection in test environment', () => {
      process.env.NODE_ENV = 'test';

      const config: RedisConfig = {
        host: 'production.redis.com',
        port: 6380,
        password: 'secret',
      };

      const connection = getRedisConnection(config);

      expect(connection.host).toBe('localhost');
      expect(connection.port).toBe(6379);
      expect(connection.password).toBeUndefined();
    });

    it('should return test connection when BUNIT is set', () => {
      process.env.BUNIT = '1';

      const config: RedisConfig = {
        host: 'production.redis.com',
        port: 6380,
      };

      const connection = getRedisConnection(config);

      expect(connection.host).toBe('localhost');
      expect(connection.port).toBe(6379);
    });

    it('should return actual config in non-test environment', () => {
      process.env.NODE_ENV = 'production';
      delete process.env.BUNIT;

      const config: RedisConfig = {
        host: 'production.redis.com',
        port: 6380,
        password: 'secret',
        db: 1,
        username: 'user',
      };

      const connection = getRedisConnection(config);

      expect(connection.host).toBe('production.redis.com');
      expect(connection.port).toBe(6380);
      expect(connection.password).toBe('secret');
      expect(connection.db).toBe(1);
      expect(connection.maxRetriesPerRequest).toBe(null);
      expect(connection.enableReadyCheck).toBe(false);
      expect(connection.connectTimeout).toBe(3000);
      expect(connection.lazyConnect).toBe(false);
      expect(connection.keepAlive).toBe(true);
      expect(typeof connection.retryStrategy).toBe('function');
    });

    it('should handle minimal config', () => {
      process.env.NODE_ENV = 'development';

      const config: RedisConfig = {
        host: 'localhost',
        port: 6379,
      };

      const connection = getRedisConnection(config);

      expect(connection.host).toBe('localhost');
      expect(connection.port).toBe(6379);
      expect(connection.password).toBeUndefined();
      expect(connection.db).toBeUndefined();
    });

    it('should preserve all config properties in non-test mode', () => {
      delete process.env.NODE_ENV;
      delete process.env.BUNIT;

      const config: RedisConfig = {
        host: 'redis.example.com',
        port: 6379,
        password: 'pass123',
        db: 2,
        username: 'admin',
        // Additional properties that might be passed
        maxRetriesPerRequest: 3,
        enableReadyCheck: true,
        enableOfflineQueue: false,
      } as RedisConfig & Record<string, any>;

      const connection = getRedisConnection(config);

      // Check that all original properties are preserved
      expect(connection.host).toBe('redis.example.com');
      expect(connection.port).toBe(6379);
      expect(connection.password).toBe('pass123');
      expect(connection.db).toBe(2);
      expect(connection.maxRetriesPerRequest).toBe(null); // Our override
      expect(connection.enableReadyCheck).toBe(false); // Our override
      expect(connection.enableOfflineQueue).toBe(false); // Preserved from original
      expect(connection.username).toBe('admin'); // Preserved from original
    });
  });
});
