package de.votian.services.controller;

import de.votian.services.dto.UserSessionDto;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.CommunicationWorkspaceService;
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 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 CommunicationWorkspaceControllerTest {

    private CommunicationWorkspaceService communicationWorkspaceService;
    private AccessControlService accessControlService;
    private CommunicationWorkspaceController controller;
    private Authentication authentication;
    private UserSessionDto user;

    @BeforeEach
    void setUp() {
        communicationWorkspaceService = mock(CommunicationWorkspaceService.class);
        accessControlService = mock(AccessControlService.class);
        controller = new CommunicationWorkspaceController(communicationWorkspaceService, accessControlService);
        authentication = mock(Authentication.class);
        user = new UserSessionDto();
        user.setUserType(1);
        user.setHeadquartersId(1L);
        user.setUserId(7L);
        user.setEmployeeId(11L);

        when(accessControlService.sessionUser(authentication)).thenReturn(user);
        when(accessControlService.canViewCommunication(user)).thenReturn(true);
        when(accessControlService.canAccessHeadquarters(user, 1L)).thenReturn(true);
        when(accessControlService.canManageNewsletter(user)).thenReturn(true);
    }

    @Test
    void bootstrapRejectsUnauthorizedUsers() {
        when(accessControlService.canViewCommunication(user)).thenReturn(false);

        ResponseEntity<CommunicationWorkspaceService.Bootstrap> response = controller.bootstrap(1L, authentication);

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

    @Test
    void bootstrapDelegatesForAuthorizedUsers() {
        CommunicationWorkspaceService.Bootstrap bootstrap = new CommunicationWorkspaceService.Bootstrap(
                true,
                true,
                true,
                false,
                3
        );
        when(communicationWorkspaceService.bootstrap(user, 1L)).thenReturn(bootstrap);

        ResponseEntity<CommunicationWorkspaceService.Bootstrap> response = controller.bootstrap(1L, authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).isEqualTo(bootstrap);
        verify(communicationWorkspaceService).bootstrap(user, 1L);
    }

    @Test
    void createTickerRejectsUnauthorizedUsers() {
        CommunicationWorkspaceController.TickerRequest request = new CommunicationWorkspaceController.TickerRequest();
        request.hqId = 1L;
        request.text = "Test";
        when(accessControlService.canViewCommunication(user)).thenReturn(false);

        ResponseEntity<CommunicationWorkspaceService.TickerRow> response = controller.createTicker(request, authentication);

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

    @Test
    void newsletterRejectsUsersWithoutNewsletterRight() {
        when(accessControlService.canManageNewsletter(user)).thenReturn(false);

        ResponseEntity<java.util.List<CommunicationWorkspaceService.NewsletterRecipientRow>> response =
                controller.newsletter(1L, "all", "all", "", authentication);

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

    @Test
    void updateNewsletterDelegatesForAuthorizedUsers() {
        CommunicationWorkspaceController.NewsletterStateRequest request = new CommunicationWorkspaceController.NewsletterStateRequest();
        request.hqId = 1L;
        request.newsletterActive = true;
        request.dsgvoConfirmed = true;
        CommunicationWorkspaceService.NewsletterRecipientRow row = new CommunicationWorkspaceService.NewsletterRecipientRow(
                "cs",
                12L,
                18L,
                "Kunde",
                "CS1001",
                "",
                "Beispiel GmbH",
                "Max Mustermann",
                "max@example.com",
                true,
                true,
                true
        );
        when(communicationWorkspaceService.updateNewsletterRecipient(user, 1L, "cs", 12L, true, true)).thenReturn(row);

        ResponseEntity<CommunicationWorkspaceService.NewsletterRecipientRow> response =
                controller.updateNewsletter("cs", 12L, request, authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).isEqualTo(row);
        verify(communicationWorkspaceService).updateNewsletterRecipient(user, 1L, "cs", 12L, true, true);
    }
}
