package ru.nbch.credit_tracker.service.indic;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import ru.nbch.credit_tracker.entities.dto.PhoneFidMap;

import java.time.LocalDate;
import java.util.*;

@Slf4j
@Service
public class PhoneService2 {

    private static final String SELCT_FIDS = """
            SELECT
                pn.number,
                pn.fid,
                pn.file_since_dt
            FROM PHONE_NORM pn
                JOIN (SELECT DISTINCT fid FROM NAME) nf
                ON nf.fid = pn.fid
            WHERE number in (:phones)
            ORDER BY
                pn.number ASC,
                pn.file_since_dt DESC,
                pn.fid DESC
            WITH UR
            """;

    private final NamedParameterJdbcTemplate jdbcTemplate;

    public PhoneService2(@Qualifier("jdbcTemplateIndic") NamedParameterJdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * Ищет фиды по номерам телефона
     *
     * @return Map: key - fid; value - {@link PhoneFidMap}
     */
    public Map<Integer, PhoneFidMap> defineFidByPhone(List<PhoneFidMap> subjects) {
        Map<Integer, PhoneFidMap> phoneFidMap = new HashMap<>();

        List<String> phones = subjects.stream().
                map(subject -> "9" + subject.getPhone())
                .toList();

        subjects.sort(
                Comparator.comparing(
                        PhoneFidMap::getPhone,
                        Comparator.naturalOrder()
                )
        );

        MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue("phones", phones);

        List<FidsData> phonesByFid = jdbcTemplate.query(SELCT_FIDS, params, (rs, rowNum) ->
                new FidsData(rs.getInt("fid"), rs.getString("number"), rs.getObject("file_since_dt", LocalDate.class))
        );

        log.debug("Start merging fids");
        for (PhoneFidMap phoneFid : subjects) {
            Iterator<FidsData> iterator = phonesByFid.iterator();
            while (iterator.hasNext()) {
                FidsData fidsData = iterator.next();
                if (fidsData.getPhone().equals(9 + phoneFid.getPhone())) {
                    //fixme доступ по ссылке, страшно, придумать что-то еще
                    phoneFidMap.put(fidsData.getFid(), phoneFid);
                    iterator.remove();
                    break;
                }
            }
        }
        log.debug("End merging fids");

        return phoneFidMap;
    }

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public static class FidsData {
        private Integer fid;
        private String phone;
        private LocalDate fileSinceDate;
    }
}
