package de.votian.services.service;

import de.votian.services.config.ParameterKeys;
import de.votian.services.dto.GroupAdminDto;
import de.votian.services.entity.AppGroup;
import de.votian.services.entity.CourierFilter;
import de.votian.services.repository.AppGroupRepository;
import de.votian.services.repository.CourierFilterRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Optional;

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

@SuppressWarnings("null")
class GroupFilterAdminServiceTest {

    private AppGroupRepository appGroupRepository;
    private CourierFilterRepository courierFilterRepository;
    private JdbcTemplate jdbcTemplate;
    private ParameterService parameterService;
    private GroupFilterAdminService groupFilterAdminService;

    @BeforeEach
    void setUp() {
        appGroupRepository = mock(AppGroupRepository.class);
        courierFilterRepository = mock(CourierFilterRepository.class);
        jdbcTemplate = mock(JdbcTemplate.class);
        parameterService = mock(ParameterService.class);
        groupFilterAdminService = new GroupFilterAdminService(
                appGroupRepository,
                courierFilterRepository,
                jdbcTemplate,
                parameterService
        );
    }

    @Test
    void createGroupResolvesMandatorAndStoresScopedGroup() {
        when(jdbcTemplate.queryForObject(
                eq("SELECT md_id FROM mandatorheadquarters WHERE hq_id = ? LIMIT 1"),
                eq(Long.class),
                eq(5L)
        )).thenReturn(9L);
        when(jdbcTemplate.queryForObject(startsWith("SELECT COUNT(*) FROM "), eq(Long.class), any()))
                .thenReturn(0L);
        when(appGroupRepository.findByMandatorIdOrderByNameAsc(9L)).thenReturn(List.of());
        when(appGroupRepository.save(any(AppGroup.class))).thenAnswer(invocation -> {
            AppGroup group = invocation.getArgument(0);
            group.setId(77L);
            return group;
        });

        GroupAdminDto result = groupFilterAdminService.createGroup(5L, " Dispo ", false);

        ArgumentCaptor<AppGroup> captor = ArgumentCaptor.forClass(AppGroup.class);
        verify(appGroupRepository).save(captor.capture());
        AppGroup saved = captor.getValue();
        assertThat(saved.getMandatorId()).isEqualTo(9L);
        assertThat(saved.getHeadquartersId()).isEqualTo(5L);
        assertThat(saved.getName()).isEqualTo("Dispo");
        assertThat(saved.getReadonly()).isEqualTo("0");
        assertThat(saved.getGroup()).isEmpty();

        assertThat(result.getId()).isEqualTo(77L);
        assertThat(result.getName()).isEqualTo("Dispo");
        assertThat(result.getHeadquartersId()).isEqualTo(5L);
        assertThat(result.isGlobalVisible()).isFalse();
        assertThat(result.isReadonly()).isFalse();
        assertThat(result.getUsageCount()).isZero();
        assertThat(result.getUsageSummary()).isEqualTo("Keine Zuordnungen");
    }

    @Test
    void deleteFilterRemovesAssignmentsAndQueuesLegacyDeletion() {
        CourierFilter filter = new CourierFilter();
        filter.setId(7L);
        filter.setShortCode("ABC");

        when(courierFilterRepository.findById(7L)).thenReturn(Optional.of(filter));
        when(parameterService.getParameterValue(ParameterKeys.FILTER_TO_BE_DELETED, 0L)).thenReturn("");

        groupFilterAdminService.deleteFilter(7L);

        verify(jdbcTemplate).update(
                eq("UPDATE customer SET cs_filter = REPLACE(cs_filter, ?, ',') WHERE cs_filter LIKE ?"),
                eq(",ABC,"),
                eq("%,ABC,%")
        );
        verify(jdbcTemplate).update(
                eq("UPDATE courier SET cr_filter = REPLACE(cr_filter, ?, ',') WHERE cr_filter LIKE ?"),
                eq(",ABC,"),
                eq("%,ABC,%")
        );
        verify(jdbcTemplate).update(
                eq("UPDATE couriervehicle SET crvh_filter = REPLACE(crvh_filter, ?, ',') WHERE crvh_filter LIKE ?"),
                eq(",ABC,"),
                eq("%,ABC,%")
        );
        verify(parameterService).setParameterValue(ParameterKeys.FILTER_TO_BE_DELETED, ",ABC,", 0L, 0L);
        verify(courierFilterRepository).delete(filter);
    }
}
