// src/config.test.ts
import { describe, it, expect } from 'vitest';
import config from './config';

/**
 * Tests for src/config.ts - client-side configuration module.
 *
 * Note: import.meta.env values are replaced at build time by Vite.
 * These tests verify the config object structure and the logic for boolean
 * parsing. Testing dynamic env variable loading requires build-time
 * configuration changes, so we focus on structure and logic validation.
 */
describe('config (client-side)', () => {
  describe('config structure', () => {
    it('should export a default config object', () => {
      expect(config).toBeDefined();
      expect(typeof config).toBe('object');
    });

    it('should have app section with version, commitMessage, and commitUrl', () => {
      expect(config).toHaveProperty('app');
      expect(config.app).toHaveProperty('version');
      expect(config.app).toHaveProperty('commitMessage');
      expect(config.app).toHaveProperty('commitUrl');
    });

    it('should have google section with mapsEmbedApiKey', () => {
      expect(config).toHaveProperty('google');
      expect(config.google).toHaveProperty('mapsEmbedApiKey');
    });

    it('should have sentry section with dsn, environment, debug, and enabled', () => {
      expect(config).toHaveProperty('sentry');
      expect(config.sentry).toHaveProperty('dsn');
      expect(config.sentry).toHaveProperty('environment');
      expect(config.sentry).toHaveProperty('debug');
      expect(config.sentry).toHaveProperty('enabled');
    });
  });

  describe('app configuration values', () => {
    it('should have app.version as a string or undefined', () => {
      expect(
        typeof config.app.version === 'string' || config.app.version === undefined,
      ).toBeTruthy();
    });

    it('should have app.commitMessage as a string or undefined', () => {
      expect(
        typeof config.app.commitMessage === 'string' || config.app.commitMessage === undefined,
      ).toBeTruthy();
    });

    it('should have app.commitUrl as a string or undefined', () => {
      expect(
        typeof config.app.commitUrl === 'string' || config.app.commitUrl === undefined,
      ).toBeTruthy();
    });
  });

  describe('google configuration values', () => {
    it('should have google.mapsEmbedApiKey as a string or undefined', () => {
      expect(
        typeof config.google.mapsEmbedApiKey === 'string' ||
          config.google.mapsEmbedApiKey === undefined,
      ).toBeTruthy();
    });
  });

  describe('sentry configuration values', () => {
    it('should have sentry.dsn as a string or undefined', () => {
      expect(typeof config.sentry.dsn === 'string' || config.sentry.dsn === undefined).toBeTruthy();
    });

    it('should have sentry.environment as a string', () => {
      // environment falls back to MODE, so should always be a string
      expect(typeof config.sentry.environment).toBe('string');
    });

    it('should have sentry.debug as a boolean', () => {
      expect(typeof config.sentry.debug).toBe('boolean');
    });

    it('should have sentry.enabled as a boolean', () => {
      expect(typeof config.sentry.enabled).toBe('boolean');
    });
  });

  describe('sentry boolean parsing logic', () => {
    // These tests verify the parsing logic used in config.ts
    // by testing the same expressions used there
    // Helper to simulate env var parsing (values come as strings at runtime)
    const parseDebug = (value: string | undefined): boolean => value === 'true';
    const parseEnabled = (value: string | undefined): boolean => value !== 'false';

    describe('debug parsing (=== "true")', () => {
      it('should return true only when value is exactly "true"', () => {
        expect(parseDebug('true')).toBe(true);
      });

      it('should return false when value is "false"', () => {
        expect(parseDebug('false')).toBe(false);
      });

      it('should return false when value is "1"', () => {
        expect(parseDebug('1')).toBe(false);
      });

      it('should return false when value is empty string', () => {
        expect(parseDebug('')).toBe(false);
      });

      it('should return false when value is undefined', () => {
        expect(parseDebug(undefined)).toBe(false);
      });

      it('should return false when value is "TRUE" (case sensitive)', () => {
        expect(parseDebug('TRUE')).toBe(false);
      });
    });

    describe('enabled parsing (!== "false")', () => {
      it('should return true when value is undefined (default enabled)', () => {
        expect(parseEnabled(undefined)).toBe(true);
      });

      it('should return true when value is empty string', () => {
        expect(parseEnabled('')).toBe(true);
      });

      it('should return true when value is "true"', () => {
        expect(parseEnabled('true')).toBe(true);
      });

      it('should return false only when value is exactly "false"', () => {
        expect(parseEnabled('false')).toBe(false);
      });

      it('should return true when value is "FALSE" (case sensitive)', () => {
        expect(parseEnabled('FALSE')).toBe(true);
      });

      it('should return true when value is "0"', () => {
        expect(parseEnabled('0')).toBe(true);
      });
    });
  });

  describe('environment fallback logic', () => {
    // Tests the || fallback pattern used in config.ts
    it('should use first value when VITE_SENTRY_ENVIRONMENT is set', () => {
      const sentryEnv = 'production';
      const mode = 'development';
      const result = sentryEnv || mode;
      expect(result).toBe('production');
    });

    it('should fall back to MODE when VITE_SENTRY_ENVIRONMENT is undefined', () => {
      const sentryEnv = undefined;
      const mode = 'development';
      const result = sentryEnv || mode;
      expect(result).toBe('development');
    });

    it('should fall back to MODE when VITE_SENTRY_ENVIRONMENT is empty string', () => {
      const sentryEnv = '';
      const mode = 'development';
      const result = sentryEnv || mode;
      expect(result).toBe('development');
    });
  });

  describe('current test environment values', () => {
    // These tests document what the config looks like in the test environment
    // They help ensure the test setup is working correctly

    it('should have test environment mode', () => {
      // In test environment, MODE should be 'test'
      expect(config.sentry.environment).toBe('test');
    });

    it('should have sentry disabled in test environment by default', () => {
      // Test environment typically has sentry disabled
      expect(config.sentry.enabled).toBe(false);
    });

    it('should have sentry debug disabled in test environment', () => {
      expect(config.sentry.debug).toBe(false);
    });
  });
});
