/**
 * Tests for centralized API configuration
 */

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";

// Store original env
const originalEnv = { ...process.env };

describe("API Configuration", () => {
  beforeEach(() => {
    // Reset modules to pick up new env values
    vi.resetModules();
  });

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

  describe("default values", () => {
    it("should use default API URL when NEXT_PUBLIC_API_URL is not set", async () => {
      delete process.env.NEXT_PUBLIC_API_URL;
      delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
      delete process.env.NEXT_PUBLIC_AUTH_MODE;
      process.env = { ...process.env, NODE_ENV: "development" };

      const { API_BASE_URL, ORCHESTRATOR_URL, AUTH_MODE, IS_MOCK_AUTH_MODE } =
        await import("./config");

      expect(API_BASE_URL).toBe("http://localhost:3001");
      expect(ORCHESTRATOR_URL).toBe("http://localhost:3001");
      expect(AUTH_MODE).toBe("mock");
      expect(IS_MOCK_AUTH_MODE).toBe(true);
    });
  });

  describe("custom values", () => {
    it("should use NEXT_PUBLIC_API_URL when set", async () => {
      process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
      delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
      delete process.env.NEXT_PUBLIC_AUTH_MODE;
      process.env = { ...process.env, NODE_ENV: "development" };

      const { API_BASE_URL, ORCHESTRATOR_URL, AUTH_MODE } = await import("./config");

      expect(API_BASE_URL).toBe("https://api.example.com");
      // ORCHESTRATOR_URL should fall back to API_BASE_URL
      expect(ORCHESTRATOR_URL).toBe("https://api.example.com");
      expect(AUTH_MODE).toBe("mock");
    });

    it("should use separate NEXT_PUBLIC_ORCHESTRATOR_URL when set", async () => {
      process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
      process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orchestrator.example.com";
      process.env = { ...process.env, NODE_ENV: "development" };
      delete process.env.NEXT_PUBLIC_AUTH_MODE;

      const { API_BASE_URL, ORCHESTRATOR_URL } = await import("./config");

      expect(API_BASE_URL).toBe("https://api.example.com");
      expect(ORCHESTRATOR_URL).toBe("https://orchestrator.example.com");
    });
  });

  describe("helper functions", () => {
    it("should build API URLs correctly", async () => {
      process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
      delete process.env.NEXT_PUBLIC_ORCHESTRATOR_URL;
      process.env = { ...process.env, NODE_ENV: "development" };
      delete process.env.NEXT_PUBLIC_AUTH_MODE;

      const { buildApiUrl } = await import("./config");

      expect(buildApiUrl("/api/v1/tasks")).toBe("https://api.example.com/api/v1/tasks");
      expect(buildApiUrl("/auth/signin")).toBe("https://api.example.com/auth/signin");
    });

    it("should build orchestrator URLs correctly", async () => {
      process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
      process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orch.example.com";
      process.env = { ...process.env, NODE_ENV: "development" };
      delete process.env.NEXT_PUBLIC_AUTH_MODE;

      const { buildOrchestratorUrl } = await import("./config");

      expect(buildOrchestratorUrl("/agents")).toBe("https://orch.example.com/agents");
      expect(buildOrchestratorUrl("/tasks/status")).toBe("https://orch.example.com/tasks/status");
    });
  });

  describe("apiConfig object", () => {
    it("should expose all configuration through apiConfig", async () => {
      process.env.NEXT_PUBLIC_API_URL = "https://api.example.com";
      process.env.NEXT_PUBLIC_ORCHESTRATOR_URL = "https://orch.example.com";
      process.env = { ...process.env, NODE_ENV: "development" };
      process.env.NEXT_PUBLIC_AUTH_MODE = "real";

      const { apiConfig } = await import("./config");

      expect(apiConfig.baseUrl).toBe("https://api.example.com");
      expect(apiConfig.orchestratorUrl).toBe("https://orch.example.com");
      expect(apiConfig.authMode).toBe("real");
      expect(apiConfig.buildUrl("/test")).toBe("https://api.example.com/test");
      expect(apiConfig.buildOrchestratorUrl("/test")).toBe("https://orch.example.com/test");
    });
  });

  describe("auth mode", () => {
    it("should enable mock mode only in development", async () => {
      process.env = { ...process.env, NODE_ENV: "development" };
      process.env.NEXT_PUBLIC_AUTH_MODE = "mock";

      const { AUTH_MODE, IS_MOCK_AUTH_MODE } = await import("./config");

      expect(AUTH_MODE).toBe("mock");
      expect(IS_MOCK_AUTH_MODE).toBe(true);
    });

    it("should throw on invalid auth mode", async () => {
      process.env = { ...process.env, NODE_ENV: "development" };
      process.env.NEXT_PUBLIC_AUTH_MODE = "invalid";

      await expect(import("./config")).rejects.toThrow("Invalid NEXT_PUBLIC_AUTH_MODE");
    });

    it("should throw when mock mode is set outside development", async () => {
      process.env = { ...process.env, NODE_ENV: "production" };
      process.env.NEXT_PUBLIC_AUTH_MODE = "mock";

      await expect(import("./config")).rejects.toThrow(
        "NEXT_PUBLIC_AUTH_MODE=mock is only allowed when NODE_ENV=development."
      );
    });
  });
});
