package de.votian.services.service;

import de.votian.services.config.ParameterKeys;
import de.votian.services.entity.CostCenter;
import de.votian.services.entity.Courier;
import de.votian.services.entity.Customer;
import de.votian.services.entity.Employee;
import de.votian.services.entity.User;
import de.votian.services.repository.CostCenterRepository;
import de.votian.services.repository.CourierRepository;
import de.votian.services.repository.CustomerRepository;
import de.votian.services.repository.UserRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@SuppressWarnings("null")
class LegacyXmlB2BAuthServiceTest {

    private LegacyXmlCustomerAuthService customerAuthService;
    private CustomerRepository customerRepository;
    private UserRepository userRepository;
    private CourierRepository courierRepository;
    private CostCenterRepository costCenterRepository;
    private JdbcTemplate jdbcTemplate;
    private ParameterService parameterService;
    private LegacyXmlB2BAuthService service;

    @BeforeEach
    void setUp() {
        customerAuthService = mock(LegacyXmlCustomerAuthService.class);
        customerRepository = mock(CustomerRepository.class);
        userRepository = mock(UserRepository.class);
        courierRepository = mock(CourierRepository.class);
        costCenterRepository = mock(CostCenterRepository.class);
        jdbcTemplate = mock(JdbcTemplate.class);
        parameterService = mock(ParameterService.class);
        service = new LegacyXmlB2BAuthService(
                customerAuthService,
                customerRepository,
                userRepository,
                courierRepository,
                costCenterRepository,
                jdbcTemplate,
                parameterService
        );
    }

    @Test
    void customerAuthDelegatesToLegacyCustomerAuthService() {
        Customer customer = new Customer();
        customer.setId(7L);
        User user = new User();
        user.setId(11L);
        Employee employee = new Employee();
        employee.setId(13L);
        CostCenter costCenter = new CostCenter();
        costCenter.setId(17L);

        when(customerAuthService.authenticate(any())).thenReturn(
                new LegacyXmlCustomerAuthService.AuthContext(customer, user, employee, null, costCenter)
        );

        LegacyXmlB2BAuthService.AuthContext result = service.authenticate(
                new LegacyXmlB2BAuthService.AuthRequest("cs", "", "", "AG-100", "demo", "secret", "SID", "Root")
        );

        assertThat(result.customer()).isSameAs(customer);
        assertThat(result.user()).isSameAs(user);
        assertThat(result.employee()).isSameAs(employee);
        assertThat(result.effectiveCostCenter()).isSameAs(costCenter);
        verify(customerAuthService).authenticate(any());
    }

    @Test
    void courierAuthAcceptsContractorUserForCustomerScope() {
        Customer customer = new Customer();
        customer.setId(7L);
        customer.setEid("AG-100");
        customer.setHeadquartersId(3L);
        customer.setCostCenterPayerId(17L);

        User user = new User();
        user.setId(11L);

        Courier courier = new Courier();
        courier.setId(19L);
        courier.setUserId(11L);
        courier.setHeadquartersId(3L);

        CostCenter payer = new CostCenter();
        payer.setId(17L);

        when(customerRepository.findByEid("AG-100")).thenReturn(Optional.of(customer));
        when(userRepository.authenticate("driver", "secret")).thenReturn(Optional.of(user));
        when(courierRepository.findByUserId(11L)).thenReturn(Optional.of(courier));
        when(costCenterRepository.findById(17L)).thenReturn(Optional.of(payer));
        when(parameterService.getParameterValue(ParameterKeys.GLOBAL_UNIQUE_DB_INSTANCE_NO, 0L)).thenReturn("DB1");
        when(jdbcTemplate.queryForObject(anyString(), eq(Integer.class), anyString(), anyLong(), anyString())).thenReturn(1);

        LegacyXmlB2BAuthService.AuthContext result = service.authenticate(
                new LegacyXmlB2BAuthService.AuthRequest("cr", "", "", "AG-100", "driver", "secret", "SID", "")
        );

        assertThat(result.customer()).isSameAs(customer);
        assertThat(result.courier()).isSameAs(courier);
        assertThat(result.user()).isSameAs(user);
        assertThat(result.effectiveCostCenter()).isSameAs(payer);
    }
}
