using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Channels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PolyTrader.Core.Configuration;
using PolyTrader.Core.Modularity;
using PolyTrader.Core.Streaming;
using PolyTrader.Modules.CopyTrading.Persistence;
using PolyTrader.Modules.CopyTrading.Persistence.Ef;
using PolyTraderSharp;
using PolyTraderSharp.Models;
using PolyTraderSharp.Services;

namespace PolyTrader.Modules.CopyTrading
{
    /// <summary>
    /// Das Copytrading-Modul: registriert seinen eigenen State, seine Channels, sein
    /// Trade-Log-Repository und seine Services selbst. Die App kennt nur den Contract.
    /// </summary>
    public class CopyTradingModule : IPolyTraderModule
    {
        public string Name => "CopyTrading";
        public string DbPrefix => "ct_";

        public void RegisterServices(IServiceCollection services, IConfiguration configuration)
        {
            // Copytrading-Hot-Path-State
            services.AddSingleton<CopyTradingState>();

            // Signal-/Trade-Channels des Moduls
            var copySignalChannel = Channel.CreateUnbounded<CopySignal>();
            var closedTradeChannel = Channel.CreateUnbounded<ClosedTrade>();
            services.AddSingleton(copySignalChannel.Writer);
            services.AddSingleton(copySignalChannel.Reader);
            services.AddSingleton(closedTradeChannel.Writer);
            services.AddSingleton(closedTradeChannel.Reader);

            // Modul-Persistenz: EF Core / Pomelo / MySQL (thread-safer DbContextFactory).
            var conn = configuration["Database:MySqlConnectionString"] ?? string.Empty;
            services.AddDbContextFactory<CopyTradingDbContext>(o => o.UseMySql(conn, DatabaseServerVersion.Value));

            services.AddSingleton<ICopyTradeLogRepository, EfCopyTradeLogRepository>();
            services.AddSingleton<ICopyTradingAccountSettingsRepository, EfCopyTradingAccountSettingsRepository>();
            services.AddSingleton<ITrackedTraderRepository, EfTrackedTraderRepository>();
            services.AddSingleton<IMasterTraderHistoryRepository, EfMasterTraderHistoryRepository>();

            // WSS-Infrastruktur (Core) wird nur vom Copytrading-Blockchain-Listener genutzt.
            services.AddSingleton<IBlockchainWssClientFactory, AlchemyWssClientFactory>();

            // IClobClient-Seam: Leiter/Reconciliation hängen am Interface (mockbar für Integrationstests);
            // die Live-Instanz ist der eine PolymarketClobClient-Singleton aus dem App-Container.
            services.AddSingleton<IClobClient>(sp => sp.GetRequiredService<PolymarketClobClient>());

            // K2 – Neustart-Reconciliation: MUSS als erster Modul-HostedService laufen (nach der
            // State-Hydration, vor TraderMonitor/Engine), damit verwaiste CLOB-Orders vom vorherigen
            // Lauf storniert sind, bevor das erste Signal verarbeitet wird.
            // Muss vor den Trading-Diensten des Moduls laufen (Settings + Trader in den State).
            services.AddHostedService<CopyTradingHydrationService>();
            services.AddHostedService<StartupOrderReconciliationService>();

            // Modul-Services (Signalquelle, Ausführung, Analytics)
            services.AddSingleton<TraderMonitorService>();
            services.AddHostedService(sp => sp.GetRequiredService<TraderMonitorService>());
            services.AddHostedService<CopyTradingEngine>();
            services.AddHostedService<TraderAnalyticsJob>();
            services.AddHostedService<MasterTraderAnalyticsJob>();

            // Persistiert die geschlossenen Copytrades (Modul-Channel -> Modul-Log + Core-Log).
            services.AddHostedService<PersistenceService>();

            // WSS-Listener des Moduls: Blockchain (Alchemy → Master-Trader-Wallets) und
            // Polymarket-Markt-WSS (Auto-Redeem nach Copytrading-Settings).
            services.AddHostedService<AlchemyWebsocketService>();
            services.AddHostedService<PolymarketWssClient>();

            // Phase 0.1: SELL-Eskalationsleiter (preist offene Exit-Limits stufenweise nach).
            // Singleton + Hosted, damit Engine und TraderMonitor StartLadderAsync aufrufen können.
            services.AddSingleton<SellLadderService>();
            services.AddHostedService(sp => sp.GetRequiredService<SellLadderService>());
        }

        /// <summary>
        /// Aktuell ohne Ansicht: Die WinForms-UI wurde mit der Linux-Portierung entfernt, die
        /// Avalonia-Ansicht folgt (Stufe L3/L4). Die Fachlogik dieses Moduls laeuft davon
        /// unabhaengig weiter – die Shell zeigt schlicht kein Fenster fuer das Modul an.
        ///
        /// <para><b>Beim Nachbau zu erhalten</b> (Spezifikation: docs/UI-SPEZIFIKATION-WinForms.md,
        /// Originalcode: Git-Tag <c>winforms-final</c>):</para>
        /// <list type="bullet">
        ///   <item>View-ID <c>copytrading.main</c> (stabil – Launcher-Button und Symbol haengen daran)</item>
        ///   <item>Titel <c>Copytrading</c>, Gruppe <c>CopyTrading</c>, Order <c>100</c></item>
        ///   <item>Ein Fenster fuers ganze Modul: CopyTradingMainForm mit Tabs: Master-Trader / Offene Trades / Geschlossene Trades / Account-Einstellungen</item>
        /// </list>
        /// </summary>
        public void RegisterUi(IModuleUiHost host, IServiceProvider services)
        {
            // Bewusst leer, bis die Avalonia-Ansicht steht (siehe Doku oben).
        }

        public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;

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