import { existsSync, writeFileSync, unlinkSync } from "node:fs";
import { PathLike } from "node:fs";
import { vi } from "vitest";
import { join } from "node:path";

// Mock fs module for existsSync (but allow real writeFileSync/unlinkSync for temp file)
vi.mock("node:fs", async () => {
  const actual = await vi.importActual<typeof import("node:fs")>("node:fs");
  return {
    ...actual,
    existsSync: vi.fn(),
  };
});

describe("provideConfig", () => {
  const configPath = join(process.cwd(), "embeddable.config.ts");
  const mockConfig = { default: "mocked-config" };

  beforeEach(() => {
    // Mock that only the TS config exists
    vi.mocked(existsSync).mockImplementation((path: PathLike) =>
      path.toString().endsWith("embeddable.config.ts"),
    );
  });

  afterEach(() => {
    // Clean up temp file if it exists
    try {
      if (existsSync(configPath)) {
        unlinkSync(configPath);
      }
    } catch {
      // Ignore cleanup errors
    }
  });

  it("should return the default config when the config file exists", async () => {
    vi.resetModules();
    
    // Create a temporary actual config file (more reliable than mocking file:// URLs on Windows)
    writeFileSync(
      configPath,
      `export default ${JSON.stringify(mockConfig.default)};`,
      "utf-8",
    );
    
    // Re-mock fs.existsSync after resetModules
    vi.mocked(existsSync).mockImplementation((path: PathLike) =>
      path.toString().endsWith("embeddable.config.ts"),
    );
    
    // Dynamically import provideConfig after file is created
    const { default: provideConfig } = await import("./provideConfig");
    const result = await provideConfig();
    expect(result).toEqual("mocked-config");
    
    // Clean up
    unlinkSync(configPath);
  });
});
