package ru.soune.nocopy.service.statistic;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ru.soune.nocopy.dto.statistic.TokenStatisticResponse;
import ru.soune.nocopy.repository.PaymentRepository;
import ru.soune.nocopy.repository.TokenOperationRepository;
import ru.soune.nocopy.util.PercentileCalculator;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class TokenStatisticService {
    private final PaymentRepository paymentRepository;

    private final TokenOperationRepository tokenOperationRepository;

    private static final int PERCENTILE_5 = 5;

    private static final int PERCENTILE_50 = 50;

    private static final int PERCENTILE_95 = 95;

    public TokenStatisticResponse getTokenStatistics() {
        Long totalBought = paymentRepository.getTotalTokensBought();
        Long totalSpent = tokenOperationRepository.getTotalTokensSpent();

        List<Object[]> boughtData = paymentRepository.getTokensBoughtPerUser();
        List<Long> boughtValues = extractTokenValues(boughtData);

        List<Object[]> spentData = tokenOperationRepository.getTokensSpentPerUser();
        List<Long> spentValues = extractTokenValues(spentData);

        PercentileCalculator.PercentilesResult boughtPercentiles =
                PercentileCalculator.calculatePercentiles(boughtValues, PERCENTILE_5, PERCENTILE_50, PERCENTILE_95);
        PercentileCalculator.PercentilesResult spentPercentiles =
                PercentileCalculator.calculatePercentiles(spentValues, PERCENTILE_5, PERCENTILE_50, PERCENTILE_95);

        return TokenStatisticResponse.builder()
                .totalBought(totalBought != null ? totalBought : 0L)
                .totalSpent(totalSpent != null ? totalSpent : 0L)
                .boughtPerUser(new TokenStatisticResponse.Percentiles(
                        boughtPercentiles.getP5(),
                        boughtPercentiles.getP50(),
                        boughtPercentiles.getP95()
                ))
                .spentPerUser(new TokenStatisticResponse.Percentiles(
                        spentPercentiles.getP5(),
                        spentPercentiles.getP50(),
                        spentPercentiles.getP95()
                ))
                .build();
    }

    private List<Long> extractTokenValues(List<Object[]> data) {
        return data.stream()
                .map(row -> row[1] != null ? ((Number) row[1]).longValue() : 0L)
                .filter(value -> value > 0)
                .collect(Collectors.toList());
    }
}
