import { beforeEach, describe, expect, it } from "bun:test";
import {
	createApiKey,
	deleteApiKey,
	listApiKeys,
	verifyApiKey,
} from "../../src/server/services/auth.service.ts";
import { createTestDb } from "../helpers/db.ts";

describe("Auth Service", () => {
	let db: any;
	let userId: number;

	beforeEach(async () => {
		({ db, userId } = await createTestDb());
	});

	describe("API Key Management", () => {
		it("creates key and returns raw key once (length > 16, prefix matches first 8 chars)", async () => {
			const result = await createApiKey(db, userId, "test-key");

			expect(result).toBeDefined();
			expect(result.rawKey).toBeDefined();
			expect(result.rawKey.length).toBeGreaterThan(16);
			expect(result.keyPrefix).toBe(result.rawKey.slice(0, 8));
			expect(result.name).toBe("test-key");
		});

		it("verifies valid key returns { userId }", async () => {
			const result = await createApiKey(db, userId, "test-key");
			const verified = await verifyApiKey(db, result.rawKey);

			expect(verified).not.toBeNull();
			expect(verified?.userId).toBe(userId);
		});

		it("rejects invalid key returns null", async () => {
			await createApiKey(db, userId, "test-key");
			const verified = await verifyApiKey(db, "invalidkey12345678");

			expect(verified).toBeNull();
		});

		it("deletes key so it is no longer valid", async () => {
			const result = await createApiKey(db, userId, "test-key");
			await deleteApiKey(db, userId, result.id);

			const verified = await verifyApiKey(db, result.rawKey);
			expect(verified).toBeNull();
		});

		it("listApiKeys returns keys without hashes", async () => {
			await createApiKey(db, userId, "key-one");
			await createApiKey(db, userId, "key-two");

			const keys = await listApiKeys(db, userId);
			expect(keys).toHaveLength(2);
			expect(keys[0].name).toBe("key-one");
			expect(keys[1].name).toBe("key-two");
			// Ensure no hash is exposed
			for (const key of keys) {
				expect(key).toHaveProperty("id");
				expect(key).toHaveProperty("name");
				expect(key).toHaveProperty("keyPrefix");
				expect(key).toHaveProperty("createdAt");
				expect(key).not.toHaveProperty("keyHash");
			}
		});
	});
});
