package de.votian.services.controller;

import de.votian.services.dto.CustomerListItemDto;
import de.votian.services.dto.ImportExecutionResultDto;
import de.votian.services.dto.ImportProcessDto;
import de.votian.services.dto.UserSessionDto;
import de.votian.services.security.AccessControlService;
import de.votian.services.service.ImportWorkspaceService;
import de.votian.services.service.ViewDataService;
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.util.List;

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 ImportControllerTest {

    private ImportWorkspaceService importWorkspaceService;
    private AccessControlService accessControlService;
    private ViewDataService viewDataService;
    private ImportController controller;
    private Authentication authentication;
    private UserSessionDto user;

    @BeforeEach
    void setUp() {
        importWorkspaceService = mock(ImportWorkspaceService.class);
        accessControlService = mock(AccessControlService.class);
        viewDataService = mock(ViewDataService.class);
        controller = new ImportController(importWorkspaceService, accessControlService, viewDataService);
        authentication = mock(Authentication.class);
        user = new UserSessionDto();
        user.setUserType(1);
        user.setHeadquartersId(1L);

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

    @Test
    void getProcessesReturnsCatalogForAuthorizedUser() {
        ImportProcessDto dto = new ImportProcessDto();
        dto.setKey("ZONE");
        when(importWorkspaceService.getProcesses()).thenReturn(List.of(dto));

        ResponseEntity<List<ImportProcessDto>> response = controller.getProcesses(authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).hasSize(1);
    }

    @Test
    void getCustomersUsesHeadquartersScope() {
        CustomerListItemDto dto = new CustomerListItemDto();
        dto.setId(4L);
        dto.setCompanyName("Musterkunde");
        when(viewDataService.findCustomersByHeadquarters(1L)).thenReturn(List.of(dto));

        ResponseEntity<List<CustomerListItemDto>> response = controller.getCustomers(authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).extracting(CustomerListItemDto::getId).containsExactly(4L);
    }

    @Test
    void executeDelegatesAndReturnsResult() {
        ImportExecutionResultDto result = new ImportExecutionResultDto();
        result.setSuccess(true);
        result.setSummary("ok");
        when(importWorkspaceService.execute("ZONE", "zone.csv", 8L, 1L)).thenReturn(result);

        ImportController.ImportExecutionRequest request = new ImportController.ImportExecutionRequest();
        request.fileName = "zone.csv";
        request.customerId = 8L;

        ResponseEntity<ImportExecutionResultDto> response = controller.execute("ZONE", request, authentication);

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        assertThat(response.getBody()).isSameAs(result);
        verify(importWorkspaceService).execute("ZONE", "zone.csv", 8L, 1L);
    }

    @Test
    void getProcessesRejectsUnauthorizedUser() {
        when(accessControlService.canManageImports(user)).thenReturn(false);

        ResponseEntity<List<ImportProcessDto>> response = controller.getProcesses(authentication);

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