using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using PolyTrader.Modules.CopyTrading.Logic;
using PolyTrader.Modules.CopyTrading.Persistence;
using PolyTraderSharp.Models;

namespace PolyTraderSharp.Services
{
    /// <summary>
    /// Hydriert den Copytrading-Zustand beim Start: Account-Settings (legt fehlende Default-Einträge
    /// an) und die verfolgten Master-Trader. Läuft nach <see cref="CoreStateHydrationService"/>,
    /// weil er die dort geladenen Accounts braucht – die Reihenfolge ergibt sich aus der
    /// Registrierungsreihenfolge (Core zuerst, dann Module).
    ///
    /// <para>Zuvor Teil des modulübergreifenden <c>StartupHydrationService</c> der WinForms-App.</para>
    /// </summary>
    public sealed class CopyTradingHydrationService : IHostedService
    {
        private readonly TradingState _state;
        private readonly CopyTradingState _copyState;
        private readonly ICopyTradingAccountSettingsRepository _accountSettingsRepo;
        private readonly ITrackedTraderRepository _traderRepo;
        private readonly TerminalLogger _logger;

        public CopyTradingHydrationService(TradingState state, CopyTradingState copyState,
            ICopyTradingAccountSettingsRepository accountSettingsRepo,
            ITrackedTraderRepository traderRepo, TerminalLogger logger)
        {
            _state = state;
            _copyState = copyState;
            _accountSettingsRepo = accountSettingsRepo;
            _traderRepo = traderRepo;
            _logger = logger;
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            try
            {
                HydrateAccountSettings(_state.Accounts.Values.ToList());

                foreach (var trd in _traderRepo.GetAll())
                    _copyState.Traders[trd.Id] = trd;

                _logger.Info($"Copytrading-Hydration abgeschlossen: {_copyState.Traders.Count} Trader geladen.");
            }
            catch (System.Exception ex)
            {
                _logger.Error($"Copytrading-Hydration fehlgeschlagen: {ex.Message}");
            }

            return Task.CompletedTask;
        }

        /// <summary>
        /// Lädt die Copytrading-Account-Settings in den State. Existiert für einen Account noch
        /// kein Eintrag, wird ein Default-Eintrag angelegt und persistiert.
        /// </summary>
        private void HydrateAccountSettings(List<AccountState> accounts)
        {
            var existing = _accountSettingsRepo.GetAll().ToDictionary(s => s.AccountId);
            int created = 0;

            foreach (var acc in accounts)
            {
                if (existing.TryGetValue(acc.AccountId, out var s))
                {
                    _copyState.AccountSettings[acc.AccountId] = s;
                    // Konfig-Plausibilität: BUY-Preisabstand ≥ SELL-Floor → Leiter startet am Floor.
                    if (SellLogic.IsLadderConfigInverted(s.MaxPriceDifference, s.SellFloorPct))
                        _logger.Warning($"⚠️ [Settings] {acc.Name}: Max. Preisabstand ({s.MaxPriceDifference:F1}%) ≥ SELL-Floor " +
                                        $"({s.SellFloorPct:F1}%) – die SELL-Leiter startet direkt am Floor (keine echte Eskalation). Floor erhöhen oder Abstand senken.");
                    continue;
                }

                var settings = new CopyTradingAccountSettings { AccountId = acc.AccountId };
                _accountSettingsRepo.Upsert(settings);
                _copyState.AccountSettings[acc.AccountId] = settings;
                created++;
            }

            if (created > 0)
                _logger.Info($"Copytrading-Account-Settings: {created} Default-Eintrag/-Einträge angelegt.");
        }

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