import Shortify, { DatabaseConfig } from "../src/index";

describe("Multi-Database Support", () => {
  describe("MongoDB Adapter", () => {
    let shortify: Shortify | undefined;

    beforeAll(async () => {
      // Skip if MongoDB is not available
      try {
        shortify = Shortify.createWithMongo(
          "https://test.com",
          "mongodb://localhost:27017/shortify-test",
          { maxRetries: 1, retryDelay: 100 } // Quick retry for tests
        );
        await shortify.connect();
      } catch (error) {
        console.log("MongoDB not available, skipping tests");
        shortify = undefined;
        return;
      }
    }, 10000); // 10 second timeout

    afterAll(async () => {
      if (shortify) {
        await shortify.disconnect();
      }
    });

    it("should create MongoDB adapter correctly", () => {
      if (!shortify) {
        console.log("Skipping MongoDB test - MongoDB not available");
        return;
      }
      expect(shortify).toBeDefined();
      expect(shortify.isReady()).toBe(true);
    });

    it("should shorten and resolve URLs with MongoDB", async () => {
      if (!shortify) return;

      const result = await shortify.shorten("https://example.com/test-url");
      expect(result.shortUrl).toContain("https://test.com/");
      expect(result.originalUrl).toBe("https://example.com/test-url");

      const resolved = await shortify.resolve(result.urlId);
      expect(resolved).toBe("https://example.com/test-url");
    });
  });

  describe("SQLite Adapter", () => {
    let shortify: Shortify;

    beforeAll(async () => {
      const dbConfig: DatabaseConfig = {
        type: "sqlite",
        database: ":memory:", // Use in-memory database for testing
        maxRetries: 1,
        retryDelay: 100,
      };

      shortify = new Shortify("https://test.com", dbConfig);
      await shortify.connect();
    });

    afterAll(async () => {
      if (shortify) {
        await shortify.disconnect();
      }
    });

    it("should create SQLite adapter correctly", () => {
      expect(shortify).toBeDefined();
      expect(shortify.isReady()).toBe(true);
    });

    it("should shorten and resolve URLs with SQLite", async () => {
      const result = await shortify.shorten(
        "https://example.com/test-url-sqlite"
      );
      expect(result.shortUrl).toContain("https://test.com/");
      expect(result.originalUrl).toBe("https://example.com/test-url-sqlite");

      const resolved = await shortify.resolve(result.urlId);
      expect(resolved).toBe("https://example.com/test-url-sqlite");
    });

    it("should handle URL expiration with SQLite", async () => {
      const result = await shortify.shorten(
        "https://example.com/expiring-url",
        {
          expiresInDays: 1,
        }
      );
      expect(result.expiresAt).toBeDefined();

      const stats = await shortify.getStats(result.urlId);
      expect(stats?.expiresAt).toBeDefined();
    });
  });

  describe("Database Factory", () => {
    it("should throw error for unsupported database types", () => {
      const dbConfig: DatabaseConfig = {
        type: "postgresql",
        host: "localhost",
        port: 5432,
        database: "test",
        username: "user",
        password: "password",
      };

      expect(() => {
        new Shortify("https://test.com", dbConfig);
      }).toThrow("PostgreSQL adapter not yet implemented");
    });

    it("should throw error for missing MongoDB connection string", () => {
      const dbConfig: DatabaseConfig = {
        type: "mongodb",
      };

      expect(() => {
        new Shortify("https://test.com", dbConfig);
      }).toThrow("MongoDB connection string is required");
    });

    it("should throw error for missing SQLite database path", () => {
      const dbConfig: DatabaseConfig = {
        type: "sqlite",
      };

      expect(() => {
        new Shortify("https://test.com", dbConfig);
      }).toThrow("SQLite database path is required");
    });
  });

  describe("Backward Compatibility", () => {
    it("should support old MongoDB constructor pattern", () => {
      const shortify = Shortify.createWithMongo(
        "https://test.com",
        "mongodb://localhost:27017/test"
      );
      expect(shortify).toBeDefined();
    });
  });
});
