import { beforeEach, describe, expect, it, vi } from 'vitest';
import { actions } from './+page.server';

const mockApi = {
	PATCH: vi.fn(),
	DELETE: vi.fn()
};

vi.mock('$lib/shared/api.server', () => ({
	createApiClient: () => mockApi,
	extractErrorCode: (e: unknown) => (e as { code?: string } | undefined)?.code
}));

beforeEach(() => vi.clearAllMocks());

// ─── update action ─────────────────────────────────────────────────────────────

describe('groups/[id] — update action', () => {
	it('returns success: true when API responds ok', async () => {
		mockApi.PATCH.mockResolvedValue({ response: { ok: true }, data: {} });

		const formData = new FormData();
		formData.set('name', 'Editors');
		formData.append('permissions', 'WRITE_ALL');

		const result = await actions.update({
			params: { id: 'g1' },
			request: { formData: async () => formData },
			fetch
		} as never);

		expect(result).toEqual({ success: true });
	});

	it('returns fail with error message when API responds not ok', async () => {
		mockApi.PATCH.mockResolvedValue({
			response: { ok: false, status: 409 },
			error: { code: 'GROUP_NOT_FOUND' }
		});

		const formData = new FormData();
		formData.set('name', 'Editors');

		const result = await actions.update({
			params: { id: 'g1' },
			request: { formData: async () => formData },
			fetch
		} as never);

		expect((result as { status: number }).status).toBe(409);
	});
});

// ─── delete action ─────────────────────────────────────────────────────────────

describe('groups/[id] — delete action', () => {
	it('redirects to /admin/groups on successful delete', async () => {
		mockApi.DELETE.mockResolvedValue({ response: { ok: true } });

		let redirectUrl: string | null = null;
		try {
			await actions.delete({
				params: { id: 'g1' },
				fetch
			} as never);
		} catch (e: unknown) {
			// SvelteKit redirect throws a Response-like object
			const r = e as { location?: string; status?: number };
			redirectUrl = r.location ?? null;
		}

		expect(redirectUrl).toBe('/admin/groups');
	});

	it('returns fail with error message when delete API responds not ok', async () => {
		mockApi.DELETE.mockResolvedValue({
			response: { ok: false, status: 403 },
			error: { code: 'FORBIDDEN' }
		});

		const result = await actions.delete({
			params: { id: 'g1' },
			fetch
		} as never);

		expect((result as { status: number }).status).toBe(403);
	});
});
