using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using PolyTrader.Core.Persistence;
using PolyTraderSharp.Models;

namespace PolyTraderSharp.Services
{
    /// <summary>
    /// Hydriert den Core-<see cref="TradingState"/> EINMALIG beim Start: Accounts und – bei
    /// Demo-Konten – deren offene Positionen. Muss als ERSTER IHostedService laufen, damit die
    /// Trading-BackgroundServices nicht gegen einen leeren State anlaufen (Startup-Race).
    ///
    /// <para>Zuvor erledigte das der modulübergreifende <c>StartupHydrationService</c> der WinForms-App.
    /// Der ist mit der Linux-Portierung aufgeteilt worden: Der Core-Anteil steht jetzt hier, der
    /// Copytrading-Anteil im Modul (<c>CopyTradingHydrationService</c>). Das behebt nebenbei einen
    /// latenten Fehler – bei deaktiviertem Copytrading-Modul wären die Accounts vorher gar nicht
    /// mehr hydriert worden, obwohl sie zum Core gehören.</para>
    /// </summary>
    public sealed class CoreStateHydrationService : IHostedService
    {
        private readonly TradingState _state;
        private readonly IAccountRepository _accountRepo;
        private readonly IPositionRepository _positionRepo;
        private readonly TerminalLogger _logger;

        public CoreStateHydrationService(TradingState state, IAccountRepository accountRepo,
            IPositionRepository positionRepo, TerminalLogger logger)
        {
            _state = state;
            _accountRepo = accountRepo;
            _positionRepo = positionRepo;
            _logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            try
            {
                foreach (var acc in _accountRepo.GetAll())
                {
                    if (acc.IsDemo)
                        foreach (var pos in _positionRepo.GetDemo(acc.AccountId))
                            acc.OpenPositions.TryAdd(pos.TokenId, pos);

                    _state.Accounts[acc.AccountId] = acc;
                }

                _logger.Info($"Core-Hydration abgeschlossen: {_state.Accounts.Count} Accounts geladen.");
            }
            catch (System.Exception ex)
            {
                _logger.Error($"Core-Hydration fehlgeschlagen: {ex.Message}");
            }

            return Task.CompletedTask;
        }

        public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
    }
}
