package ru.nbch.credit_tracker.service;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;
import ru.nbch.credit_tracker.service.indic.PhoneService2;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class PhoneService2Test {

    @Mock
    NamedParameterJdbcTemplate jdbcTemplate;

    @Test
    public void defineFidByPhoneTest() {
        PhoneService2 phoneService = new PhoneService2(jdbcTemplate);

        fidsDataWithEqualSinceDt.sort(byDbOrder);
        when(jdbcTemplate.query(anyString(), any(MapSqlParameterSource.class), any(RowMapper.class))).thenReturn(fidsDataWithEqualSinceDt);

        List<PhoneFidMap> phoneFidMap = new ArrayList<>();
        phoneFidMap.add(PhoneFidMap.builder().phone("1111").build());
        phoneFidMap.add(PhoneFidMap.builder().phone("1112").build());
        phoneFidMap.add(PhoneFidMap.builder().phone("1113").build());
        phoneFidMap.add(PhoneFidMap.builder().phone("1114").build());

        Map<Integer, PhoneFidMap> res = phoneService.defineFidByPhone(phoneFidMap);
        Assertions.assertEquals(3, res.size());
        Assertions.assertEquals("1111", res.get(124).getPhone());
        Assertions.assertEquals("1112", res.get(125).getPhone());
        Assertions.assertEquals("1114", res.get(126).getPhone());
    }

    private final List<PhoneService2.FidsData> fidsDataWithEqualSinceDt = new ArrayList<>(
        List.of(
            new PhoneService2.FidsData(123, "91111", LocalDate.of(2025, 9, 10)),
            new PhoneService2.FidsData(124, "91111", LocalDate.of(2025, 9, 10)),
            new PhoneService2.FidsData(125, "91112", LocalDate.of(2024, 10, 10)),
            new PhoneService2.FidsData(126, "91114", LocalDate.of(2024, 10, 11))
        )
    );

    Comparator<PhoneService2.FidsData> byDbOrder =
        Comparator.comparing(PhoneService2.FidsData::getPhone, Comparator.nullsFirst(Comparator.naturalOrder())) // pn.number ASC
            .thenComparing(PhoneService2.FidsData::getFileSinceDate, Comparator.nullsLast(Comparator.reverseOrder())) // file_since_dt DESC
            .thenComparing(PhoneService2.FidsData::getFid, Comparator.reverseOrder());
}
