namespace QuantEngine.Core.Interfaces;

/// <summary>
/// Data collection storage abstraction layer.
/// Maps Python data_collection_store_v1.py contracts to .NET.
/// Supports PostgreSQL backend for production.
/// </summary>
public interface IDataCollectionStore
{
    /// <summary>
    /// Initialize storage tables and schema (idempotent).
    /// </summary>
    Task InitializeAsync();

    /// <summary>
    /// Insert or update collection run record.
    /// </summary>
    Task UpsertRunAsync(CollectionRunRecord run);

    /// <summary>
    /// Insert collection snapshot record.
    /// </summary>
    Task UpsertSnapshotAsync(CollectionSnapshotRecord snapshot);

    /// <summary>
    /// Append error record from collection attempt.
    /// </summary>
    Task AppendErrorAsync(CollectionErrorRecord error);

    /// <summary>
    /// Fetch recent collection runs for dashboard.
    /// </summary>
    /// <param name="limit">Max number of runs to return</param>
    Task<List<CollectionRunRecord>> FetchRecentRunsAsync(int limit = 20);

    /// <summary>
    /// Fetch latest snapshots for a ticker/dataset combination.
    /// </summary>
    Task<List<CollectionSnapshotRecord>> FetchLatestSnapshotsAsync(string ticker, string? datasetName = null, int limit = 10);

    /// <summary>
    /// Get collection pipeline dashboard state.
    /// </summary>
    Task<CollectionDashboardStateRecord> GetDashboardStateAsync();
}

public interface ICollectionWriteRepository
{
    Task SaveRunAsync(CollectionRunRecord run);
    Task UpdateRunStatusAsync(string runId, string status, string? finishedAt = null, int? totalSnapshots = null, int? totalErrors = null);
    Task SaveSnapshotAsync(CollectionSnapshotRecord snapshot);
    Task SaveErrorAsync(CollectionErrorRecord error);
    Task SavePriceHistoryDailyAsync(PriceHistoryDailyRecord record);
}

public interface ICollectionReadRepository
{
    Task<List<CollectionRunRecord>> GetRecentRunsAsync(int limit = 20);
    Task<List<CollectionSnapshotRecord>> GetRunSnapshotsAsync(string runId);
    Task<List<CollectionErrorRecord>> GetRunErrorsAsync(string runId, int limit = 50);
    Task<CollectionDashboardStateRecord> GetDashboardStateAsync();
    Task<List<CollectionSnapshotRecord>> GetLatestSnapshotsForTickerAsync(string ticker, int limit = 10);
    Task<List<PriceHistorySummaryRecord>> GetPriceHistorySummaryAsync();
}

public interface ICollectionSchemaInitializer
{
    Task InitializeAsync();
}

/// <summary>
/// Collection run record (maps Python CollectionRun).
/// </summary>
public record CollectionRunRecord(
    string RunId,
    string Status,
    string StartedAt,
    string? FinishedAt = null,
    int? TotalSnapshots = null,
    int? TotalErrors = null,
    string UpdatedAt = ""
);

/// <summary>
/// Collection snapshot record (maps Python CollectionSnapshot).
/// </summary>
public record CollectionSnapshotRecord(
    string RunId,
    string DatasetName,
    string Ticker,
    string SourceName,
    string PayloadJson,
    string CapturedAt,
    string CreatedAt = ""
);

/// <summary>
/// Collection error record (maps Python CollectionSourceError).
/// </summary>
public record CollectionErrorRecord(
    string RunId,
    string SourceName,
    string ErrorKind,
    string ErrorMessage,
    string Ticker = "",
    string CreatedAt = ""
);

/// <summary>
/// Dashboard state summary.
/// </summary>
public record CollectionDashboardStateRecord(
    string? LastRunId,
    string? LastRunStatus,
    string? LastFinishedAt,
    int TotalSnapshots,
    int TotalErrors,
    List<CollectionErrorRecord> RecentErrors
);

/// <summary>
/// Daily price history record (OHLCV bar).
/// </summary>
public record PriceHistoryDailyRecord(
    string Ticker,
    DateOnly TradeDate,
    decimal Open,
    decimal High,
    decimal Low,
    decimal Close,
    long Volume,
    string Source,
    string? ProvenanceJson = null
);

/// <summary>
/// Price history summary (per-ticker aggregation).
/// </summary>
public record PriceHistorySummaryRecord(
    string Ticker,
    int RowCount,
    DateOnly FirstDate,
    DateOnly LastDate
);
