package de.votian.services.controller;

import de.votian.services.dto.GroupwareAppointmentCommandDto;
import de.votian.services.dto.GroupwareAppointmentDto;
import de.votian.services.dto.GroupwareCancellationCommandDto;
import de.votian.services.dto.UserSessionDto;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.GroupwareService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;

import java.time.LocalDateTime;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

class GroupwareControllerTest {

    private GroupwareService groupwareService;
    private AccessControlService accessControlService;
    private Authentication authentication;
    private UserSessionDto user;
    private GroupwareController controller;

    @BeforeEach
    void setUp() {
        groupwareService = mock(GroupwareService.class);
        accessControlService = mock(AccessControlService.class);
        authentication = mock(Authentication.class);
        user = new UserSessionDto();
        user.setUserId(12L);
        user.setHeadquartersId(1L);
        user.setEmployeeId(5L);
        user.setUserType(1);
        controller = new GroupwareController(groupwareService, accessControlService);

        when(accessControlService.sessionUser(authentication)).thenReturn(user);
        when(accessControlService.canViewGroupware(user)).thenReturn(true);
        when(accessControlService.canManageGroupware(user)).thenReturn(true);
    }

    @Test
    void createAppointmentDelegatesToService() {
        GroupwareAppointmentCommandDto request = new GroupwareAppointmentCommandDto();
        request.setText("Neuer Termin");
        request.setStartTime(LocalDateTime.of(2026, 3, 28, 10, 0));
        request.setEndTime(LocalDateTime.of(2026, 3, 28, 11, 0));

        GroupwareAppointmentDto responseDto = new GroupwareAppointmentDto();
        responseDto.setId(99L);
        when(groupwareService.createAppointment(user, request)).thenReturn(responseDto);

        ResponseEntity<GroupwareAppointmentDto> response = controller.createAppointment(request, authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).isSameAs(responseDto);
        verify(groupwareService).createAppointment(user, request);
    }

    @Test
    void cancelAppointmentDelegatesToService() {
        GroupwareCancellationCommandDto request = new GroupwareCancellationCommandDto();
        request.setNotifyParticipants(true);

        ResponseEntity<Void> response = controller.cancelAppointment(17L, request, authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        verify(groupwareService).cancelAppointment(user, 17L, request);
    }

    @Test
    void getOptionsReturnsForbiddenWithoutRight() {
        when(accessControlService.canViewGroupware(user)).thenReturn(false);

        ResponseEntity<?> response = controller.getOptions(authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
    }
}
