// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using FloraMultiPlatformFrontend.Data.Repositories;
using FloraMultiPlatformFrontend.Presentation.Models.Charts;
using FloraMultiPlatformFrontend.Presentation.Models.Filter;
using FloraMultiPlatformFrontend.Presentation.Models.ServiceResult;

namespace FloraMultiPlatformFrontend.Data.Repositories.Interfaces;

public interface IDashboardRepository
{
    Task<double?> GetAverageRingBuildingTimeAsync(DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);
    Task<double?> GetAverageRingsPerDayAsync(DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);
    Task<IEnumerable<TagAverageResult>> GetTagAveragesAsync(IEnumerable<int> tagIds, DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);
    Task<IDictionary<int, double>> GetTagAveragesDictionaryAsync(IEnumerable<int> tagIds, DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);
    Task<IEnumerable<ChartDataPoint>> GetTagHistoryAsync(int tagId, DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);

    Task<Range<int>?> GetRingRangeForDateRangeAsync(DateTime startDate, DateTime endDate, string machineCode);
    Task<Range<double>?> GetChainageRangeForDateRangeAsync(DateTime startDate, DateTime endDate, string machineCode);
    Task<Range<int>?> GetStrokeRangeForDateRangeAsync(DateTime startDate, DateTime endDate, string machineCode);
    Task<Range<DateTime>?> GetDateRangeForRingRangeAsync(int startRing, int endRing, string machineCode);
    Task<Range<DateTime>?> GetDateRangeForChainageRangeAsync(double startChainage, double endChainage, string machineCode);

    /// <summary>
    /// Gets all raw tag data for multiple tags within a date range (no bucketing)
    /// </summary>
    Task<IDictionary<int, IEnumerable<ChartDataPoint>>> GetMultipleTagsRawDataAsync(IEnumerable<int> tagIds, DateTime startDate, DateTime endDate, string machineCode, CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets time-weighted aggregated history for a tag within a date range.
    /// Uses time-weighted averaging for sparse change-only data.
    /// </summary>
    Task<IEnumerable<ChartDataPoint>> GetTimeWeightedAggregatedHistoryAsync(
        int tagId,
        DateTime startDate,
        DateTime endDate,
        long bucketSizeMs,
        string machineCode,
        CancellationToken cancellationToken = default);

    Task<IEnumerable<ChartDataPoint>> GetAggregatedDataWithCacheAsync(int tagId, DateTime startDate, DateTime endDate, long bucketSizeMs, string machineCode, CancellationToken cancellationToken);

    /// <summary>
    /// Gets pre-aggregated weighted values from AValueData table for conditional average calculation.
    /// </summary>
    Task<IDictionary<int, IEnumerable<DashboardRepository.AValueDataPoint>>> GetAValueDataAsync(
        IEnumerable<int> tagIds,
        DateTime startDate,
        DateTime endDate,
        string machineCode,
        decimal conditionValue = 2.0m,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// Gets ring-based weighted averages from AValueDataAverage table.
    /// </summary>
    Task<IDictionary<int, IEnumerable<DashboardRepository.AValueDataAveragePoint>>> GetAValueDataAverageAsync(
        IEnumerable<int> tagIds,
        DateTime startDate,
        DateTime endDate,
        string machineCode,
        int? ringNumberStart = null,
        int? ringNumberEnd = null,
        CancellationToken cancellationToken = default);
}
