package com.cameleer.server.core.search;

import com.cameleer.server.core.storage.SearchIndex;
import com.cameleer.server.core.storage.StatsStore;

import java.time.Instant;
import java.util.List;
import java.util.Map;

public class SearchService {

    private final SearchIndex searchIndex;
    private final StatsStore statsStore;

    public SearchService(SearchIndex searchIndex, StatsStore statsStore) {
        this.searchIndex = searchIndex;
        this.statsStore = statsStore;
    }

    public SearchResult<ExecutionSummary> search(SearchRequest request) {
        return searchIndex.search(request);
    }

    public long count(SearchRequest request) {
        return searchIndex.count(request);
    }

    public List<String> distinctAttributeKeys(String environment) {
        return searchIndex.distinctAttributeKeys(environment);
    }

    public ExecutionStats stats(Instant from, Instant to) {
        return statsStore.stats(from, to, null);
    }

    public ExecutionStats stats(Instant from, Instant to, String environment) {
        return statsStore.stats(from, to, environment);
    }

    public ExecutionStats statsForApp(Instant from, Instant to, String applicationId) {
        return statsStore.statsForApp(from, to, applicationId, null);
    }

    public ExecutionStats statsForApp(Instant from, Instant to, String applicationId, String environment) {
        return statsStore.statsForApp(from, to, applicationId, environment);
    }

    public ExecutionStats statsForRoute(Instant from, Instant to, String routeId, String applicationId) {
        return statsStore.statsForRoute(from, to, routeId, applicationId, null);
    }

    public ExecutionStats statsForRoute(Instant from, Instant to, String routeId, String applicationId, String environment) {
        return statsStore.statsForRoute(from, to, routeId, applicationId, environment);
    }

    public StatsTimeseries timeseries(Instant from, Instant to, int bucketCount) {
        return statsStore.timeseries(from, to, bucketCount, null);
    }

    public StatsTimeseries timeseries(Instant from, Instant to, int bucketCount, String environment) {
        return statsStore.timeseries(from, to, bucketCount, environment);
    }

    public StatsTimeseries timeseriesForApp(Instant from, Instant to, int bucketCount, String applicationId) {
        return statsStore.timeseriesForApp(from, to, bucketCount, applicationId, null);
    }

    public StatsTimeseries timeseriesForApp(Instant from, Instant to, int bucketCount, String applicationId, String environment) {
        return statsStore.timeseriesForApp(from, to, bucketCount, applicationId, environment);
    }

    public StatsTimeseries timeseriesForRoute(Instant from, Instant to, int bucketCount,
                                       String routeId, String applicationId) {
        return statsStore.timeseriesForRoute(from, to, bucketCount, routeId, applicationId, null);
    }

    public StatsTimeseries timeseriesForRoute(Instant from, Instant to, int bucketCount,
                                       String routeId, String applicationId, String environment) {
        return statsStore.timeseriesForRoute(from, to, bucketCount, routeId, applicationId, environment);
    }

    // ── Dashboard-specific queries ────────────────────────────────────────

    public Map<String, StatsTimeseries> timeseriesGroupedByApp(Instant from, Instant to, int bucketCount) {
        return statsStore.timeseriesGroupedByApp(from, to, bucketCount, null);
    }

    public Map<String, StatsTimeseries> timeseriesGroupedByApp(Instant from, Instant to, int bucketCount, String environment) {
        return statsStore.timeseriesGroupedByApp(from, to, bucketCount, environment);
    }

    public Map<String, StatsTimeseries> timeseriesGroupedByRoute(Instant from, Instant to,
                                                                   int bucketCount, String applicationId) {
        return statsStore.timeseriesGroupedByRoute(from, to, bucketCount, applicationId, null);
    }

    public Map<String, StatsTimeseries> timeseriesGroupedByRoute(Instant from, Instant to,
                                                                   int bucketCount, String applicationId, String environment) {
        return statsStore.timeseriesGroupedByRoute(from, to, bucketCount, applicationId, environment);
    }

    public double slaCompliance(Instant from, Instant to, int thresholdMs,
                                String applicationId, String routeId) {
        return statsStore.slaCompliance(from, to, thresholdMs, applicationId, routeId, null);
    }

    public double slaCompliance(Instant from, Instant to, int thresholdMs,
                                String applicationId, String routeId, String environment) {
        return statsStore.slaCompliance(from, to, thresholdMs, applicationId, routeId, environment);
    }

    public Map<String, long[]> slaCountsByApp(Instant from, Instant to, int defaultThresholdMs) {
        return statsStore.slaCountsByApp(from, to, defaultThresholdMs, null);
    }

    public Map<String, long[]> slaCountsByApp(Instant from, Instant to, int defaultThresholdMs, String environment) {
        return statsStore.slaCountsByApp(from, to, defaultThresholdMs, environment);
    }

    public Map<String, long[]> slaCountsByRoute(Instant from, Instant to,
                                                  String applicationId, int thresholdMs) {
        return statsStore.slaCountsByRoute(from, to, applicationId, thresholdMs, null);
    }

    public Map<String, long[]> slaCountsByRoute(Instant from, Instant to,
                                                  String applicationId, int thresholdMs, String environment) {
        return statsStore.slaCountsByRoute(from, to, applicationId, thresholdMs, environment);
    }

    public List<TopError> topErrors(Instant from, Instant to, String applicationId,
                                     String routeId, int limit) {
        return statsStore.topErrors(from, to, applicationId, routeId, limit, null);
    }

    public List<TopError> topErrors(Instant from, Instant to, String applicationId,
                                     String routeId, int limit, String environment) {
        return statsStore.topErrors(from, to, applicationId, routeId, limit, environment);
    }

    public int activeErrorTypes(Instant from, Instant to, String applicationId) {
        return statsStore.activeErrorTypes(from, to, applicationId, null);
    }

    public int activeErrorTypes(Instant from, Instant to, String applicationId, String environment) {
        return statsStore.activeErrorTypes(from, to, applicationId, environment);
    }

    public List<StatsStore.PunchcardCell> punchcard(Instant from, Instant to, String applicationId) {
        return statsStore.punchcard(from, to, applicationId, null);
    }

    public List<StatsStore.PunchcardCell> punchcard(Instant from, Instant to, String applicationId, String environment) {
        return statsStore.punchcard(from, to, applicationId, environment);
    }
}
