import { describe, it, expect } from "vitest";
import { AuthenticationService } from "@/infrastructure/services/authentication.service";
import { stubPayloadConfig } from "@repo/core-testing/payload/stub-config";

describe("AuthenticationService", () => {
  const service = new AuthenticationService(stubPayloadConfig);

  describe("generateUserId", () => {
    it("returns a UUID string", () => {
      const id = service.generateUserId();
      expect(id).toMatch(
        /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
      );
    });

    it("returns unique values", () => {
      const ids = Array.from({ length: 5 }, () => service.generateUserId());
      const unique = new Set(ids);
      expect(unique.size).toBe(5);
    });
  });

  describe("hashPassword + verifyPassword", () => {
    it("round-trips: hash then verify returns true", async () => {
      const hash = await service.hashPassword("my-secret");
      const valid = await service.verifyPassword(hash, "my-secret");
      expect(valid).toBe(true);
    });

    it("returns false for wrong password", async () => {
      const hash = await service.hashPassword("my-secret");
      const valid = await service.verifyPassword(hash, "wrong-password");
      expect(valid).toBe(false);
    });

    it("returns false for malformed stored hash", async () => {
      const valid = await service.verifyPassword("not-a-valid-hash", "anything");
      expect(valid).toBe(false);
    });
  });

  describe("deferred methods (NotImplementedError)", () => {
    const user = {
      id: "test-id",
      username: "testuser",
      passwordHash: "hashed_password",
    };

    it("createSession throws NotImplementedError", async () => {
      await expect(service.createSession(user)).rejects.toThrow("NotImplemented");
    });

    it("validateSession throws NotImplementedError", async () => {
      await expect(service.validateSession("some-session")).rejects.toThrow("NotImplemented");
    });

    it("invalidateSession throws NotImplementedError", async () => {
      await expect(service.invalidateSession("some-session")).rejects.toThrow("NotImplemented");
    });
  });
});
