// #region MaintenanceApiTest [C:3] [TYPE Module] [SEMANTICS test, maintenance, api, banners, events]
// @BRIEF Unit tests for maintenance API client — start/end events, settings, dashboard banners.
// @LAYER Tests
// @RELATION BINDS_TO -> [MaintenanceApi]
// @TEST_CONTRACT: startMaintenance -> POST /maintenance/start with params
// @TEST_CONTRACT: endMaintenance -> POST /maintenance/{id}/end
// @TEST_CONTRACT: endAllMaintenance -> POST /maintenance/end-all
// @TEST_CONTRACT: getSettings -> GET /maintenance/settings
// @TEST_CONTRACT: updateSettings -> PUT /maintenance/settings with payload
// @TEST_CONTRACT: listEvents -> GET /maintenance/events
// @TEST_CONTRACT: listDashboardBanners -> GET /maintenance/dashboard-banners

import { describe, it, expect, vi, beforeEach } from 'vitest';

const mockRequestApi = vi.fn();

vi.mock('$lib/api.js', () => ({
	requestApi: mockRequestApi,
}));

describe('Maintenance API', () => {
	beforeEach(async () => {
		vi.clearAllMocks();
	});

	it('startMaintenance sends POST to /maintenance/start with params', async () => {
		mockRequestApi.mockResolvedValue({ task_id: 't-1', maintenance_id: 'm-1', status: 'started' });
		const { startMaintenance } = await import('$lib/api/maintenance.js');
		const params = { environment_id: 'env-1', tables: ['sales'], start_time: '2025-01-01T00:00:00Z' };
		const result = await startMaintenance(params);
		expect(result).toEqual({ task_id: 't-1', maintenance_id: 'm-1', status: 'started' });
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/start', 'POST', params);
	});

	it('startMaintenance accepts optional end_time and message', async () => {
		mockRequestApi.mockResolvedValue({ task_id: 't-2', maintenance_id: 'm-2', status: 'started' });
		const { startMaintenance } = await import('$lib/api/maintenance.js');
		const params = {
			environment_id: 'env-1',
			tables: ['sales'],
			start_time: '2025-01-01T00:00:00Z',
			end_time: '2025-01-02T00:00:00Z',
			message: 'Scheduled maintenance',
		};
		await startMaintenance(params);
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/start', 'POST', params);
	});

	it('endMaintenance sends POST to /maintenance/{id}/end', async () => {
		mockRequestApi.mockResolvedValue({ task_id: 't-1', status: 'ended' });
		const { endMaintenance } = await import('$lib/api/maintenance.js');
		const result = await endMaintenance('m-42');
		expect(result).toEqual({ task_id: 't-1', status: 'ended' });
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/m-42/end', 'POST');
	});

	it('endAllMaintenance sends POST to /maintenance/end-all', async () => {
		mockRequestApi.mockResolvedValue({ task_id: 't-3', status: 'ended' });
		const { endAllMaintenance } = await import('$lib/api/maintenance.js');
		const result = await endAllMaintenance();
		expect(result).toEqual({ task_id: 't-3', status: 'ended' });
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/end-all', 'POST');
	});

	it('getSettings sends GET to /maintenance/settings', async () => {
		const settingsFixture = { auto_end_enabled: true, default_message: 'Maintenance' };
		mockRequestApi.mockResolvedValue(settingsFixture);
		const { getSettings } = await import('$lib/api/maintenance.js');
		const result = await getSettings();
		expect(result).toEqual(settingsFixture);
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/settings', 'GET');
	});

	it('updateSettings sends PUT to /maintenance/settings with payload', async () => {
		const updatedSettings = { auto_end_enabled: false };
		mockRequestApi.mockResolvedValue({ auto_end_enabled: false, default_message: 'Maintenance' });
		const { updateSettings } = await import('$lib/api/maintenance.js');
		const result = await updateSettings(updatedSettings);
		expect(result).toEqual({ auto_end_enabled: false, default_message: 'Maintenance' });
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/settings', 'PUT', updatedSettings);
	});

	it('listEvents sends GET to /maintenance/events', async () => {
		const eventsFixture = { active: [{ id: 'm-1' }], completed: [{ id: 'm-2' }] };
		mockRequestApi.mockResolvedValue(eventsFixture);
		const { listEvents } = await import('$lib/api/maintenance.js');
		const result = await listEvents();
		expect(result).toEqual(eventsFixture);
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/events', 'GET');
	});

	it('listDashboardBanners sends GET to /maintenance/dashboard-banners', async () => {
		const bannersFixture = [{ dashboard_id: 'd-1', active: true, events: [], start_time: null, end_time: null }];
		mockRequestApi.mockResolvedValue(bannersFixture);
		const { listDashboardBanners } = await import('$lib/api/maintenance.js');
		const result = await listDashboardBanners();
		expect(result).toEqual(bannersFixture);
		expect(mockRequestApi).toHaveBeenCalledWith('/maintenance/dashboard-banners', 'GET');
	});

	it('propagates API error from requestApi', async () => {
		mockRequestApi.mockRejectedValue(new Error('Server Error'));
		const { listEvents } = await import('$lib/api/maintenance.js');
		await expect(listEvents()).rejects.toThrow('Server Error');
	});

	it('startMaintenance propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('Start failed'));
		const { startMaintenance } = await import('$lib/api/maintenance.js');
		await expect(startMaintenance({ environment_id: 'e1', tables: ['t1'], start_time: '2025-01-01T00:00:00Z' })).rejects.toThrow('Start failed');
	});

	it('endMaintenance propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('End failed'));
		const { endMaintenance } = await import('$lib/api/maintenance.js');
		await expect(endMaintenance('m-1')).rejects.toThrow('End failed');
	});

	it('endAllMaintenance propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('End all failed'));
		const { endAllMaintenance } = await import('$lib/api/maintenance.js');
		await expect(endAllMaintenance()).rejects.toThrow('End all failed');
	});

	it('getSettings propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('Settings fetch failed'));
		const { getSettings } = await import('$lib/api/maintenance.js');
		await expect(getSettings()).rejects.toThrow('Settings fetch failed');
	});

	it('updateSettings propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('Update settings failed'));
		const { updateSettings } = await import('$lib/api/maintenance.js');
		await expect(updateSettings({ auto_end_enabled: true })).rejects.toThrow('Update settings failed');
	});

	it('listDashboardBanners propagates API error', async () => {
		mockRequestApi.mockRejectedValue(new Error('Banners failed'));
		const { listDashboardBanners } = await import('$lib/api/maintenance.js');
		await expect(listDashboardBanners()).rejects.toThrow('Banners failed');
	});

	it('propagates string rejection as error', async () => {
		mockRequestApi.mockRejectedValue('Not allowed');
		const { listEvents } = await import('$lib/api/maintenance.js');
		await expect(listEvents()).rejects.toThrow('Not allowed');
	});
});
// #endregion MaintenanceApiTest
