package pl.polskalokalnie.lead;

import java.util.List;
import org.springframework.stereotype.Service;

/**
 * Wylicza czlonkow grupy docelowej (dynamicznego segmentu) na podstawie zapisanych kryteriow.
 * Puste kryterium = brak ograniczenia. Nie wyklucza tu rezygnacji (opt-out) ani braku adresu -
 * to robi budowa kampanii, bo zalezy od kanalu (e-mail vs SMS).
 */
@Service
public class LeadQueryService {

    private final LeadRepository leadRepository;

    public LeadQueryService(LeadRepository leadRepository) {
        this.leadRepository = leadRepository;
    }

    public List<Lead> resolve(TargetGroup group) {
        return leadRepository.findAll().stream()
                .filter(lead -> matches(lead, group))
                .toList();
    }

    public long count(TargetGroup group) {
        return leadRepository.findAll().stream()
                .filter(lead -> matches(lead, group))
                .count();
    }

    private boolean matches(Lead lead, TargetGroup group) {
        if (group.getSources() != null && !group.getSources().isEmpty()
                && !group.getSources().contains(lead.getSource())) {
            return false;
        }
        if (hasText(group.getCity())
                && (lead.getCity() == null || !lead.getCity().trim().equalsIgnoreCase(group.getCity().trim()))) {
            return false;
        }
        if (hasText(group.getTag()) && !containsTagIgnoreCase(lead.getTags(), group.getTag().trim())) {
            return false;
        }
        if (group.getStatus() != null && lead.getStatus() != group.getStatus()) {
            return false;
        }
        if (group.isRequireEmail() && !hasText(lead.getEmail())) {
            return false;
        }
        if (group.isRequirePhone() && !hasText(lead.getPhone())) {
            return false;
        }
        if (group.isRequireEmailConsent() && !lead.isEmailConsent()) {
            return false;
        }
        if (group.isRequireSmsConsent() && !lead.isSmsConsent()) {
            return false;
        }
        return true;
    }

    private static boolean containsTagIgnoreCase(List<String> tags, String tag) {
        if (tags == null) {
            return false;
        }
        for (String candidate : tags) {
            if (candidate != null && candidate.trim().equalsIgnoreCase(tag)) {
                return true;
            }
        }
        return false;
    }

    private static boolean hasText(String value) {
        return value != null && !value.trim().isEmpty();
    }
}
