using Orleans;
using Orleans.Concurrency;
using static Managing.Common.Enums;

namespace Managing.Application.Abstractions.Grains;

/// <summary>
/// Grain interface for managing platform-wide summary metrics
/// </summary>
public interface IPlatformSummaryGrain : IGrainWithStringKey
{
    /// <summary>
    /// Gets the current platform summary data
    /// </summary>
    Task<PlatformSummaryGrainState> GetPlatformSummaryAsync();

    /// <summary>
    /// Forces a refresh of all platform data
    /// </summary>
    Task RefreshDataAsync();

    // Event handlers for immediate updates
    /// <summary>
    /// Updates the active strategy count
    /// </summary>
    [OneWay]
    Task UpdateActiveStrategyCountAsync(int newActiveCount);

    /// <summary>
    /// Increments the total agent count when a new agent is activated
    /// </summary>
    [OneWay]
    Task RefreshAgentCountAsync();

    [OneWay]
    Task OnPositionClosedAsync(PositionClosedEvent evt);

    [OneWay]
    Task OnPositionOpenAsync(PositionOpenEvent evt);
}

/// <summary>
/// Base class for platform metrics events
/// </summary>
[GenerateSerializer]
public abstract class PlatformMetricsEvent
{
    [Id(0)] public DateTime Timestamp { get; set; } = DateTime.UtcNow;
}

/// <summary>
/// Event fired when a position is closed
/// </summary>
[GenerateSerializer]
public class PositionClosedEvent : PlatformMetricsEvent
{
    [Id(1)] public Guid PositionIdentifier { get; set; }

    [Id(2)] public Ticker Ticker { get; set; }

    [Id(3)] public decimal RealizedPnL { get; set; }

    [Id(4)] public decimal Volume { get; set; }
}

/// <summary>
/// Event fired when a trade is executed
/// </summary>
[GenerateSerializer]
public class PositionOpenEvent : PlatformMetricsEvent
{
    [Id(1)] public Ticker Ticker { get; set; }

    [Id(2)] public decimal Volume { get; set; }

    [Id(3)] public decimal Fee { get; set; }

    [Id(4)] public TradeDirection Direction { get; set; }
    [Id(5)] public Guid PositionIdentifier { get; set; }
}

[GenerateSerializer]
public class PositionUpdatedEvent : PlatformMetricsEvent
{
    [Id(1)] public Guid PositionIdentifier { get; set; }
}