using System.Threading;
using System.Threading.Tasks;
using PolyTrader.Tests.Fakes;
using PolyTraderSharp;
using PolyTraderSharp.Models;
using PolyTraderSharp.Services;
using Xunit;

namespace PolyTrader.Tests
{
    /// <summary>
    /// Slice 2 (Fable-Fixes) – K2 Neustart-Reconciliation: Beim Start werden alle offenen CLOB-Orders
    /// je Live-Account pauschal storniert, damit die Engine gegen keine Waisen-Orders anläuft.
    /// </summary>
    public class StartupOrderReconciliationTests
    {
        private static AccountState LiveAccount(int id, string name)
        {
            return new AccountState
            {
                AccountId = id,
                Name = name,
                IsDemo = false,
                ApiKey = "k",
                ApiSecret = "s",
                ApiPassphrase = "p",
                PrivateKey = "0xabc"
            };
        }

        [Fact]
        public async Task Cancels_all_open_orders_for_live_accounts()
        {
            var state = new TradingState();
            var acc = LiveAccount(1, "Live");
            state.Accounts[acc.AccountId] = acc;

            var clob = new FakeClobClient();
            clob.AllOpenOrders.Add(("o1", "SELL", 0.40m));
            clob.AllOpenOrders.Add(("o2", "BUY", 0.55m));

            var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
            await svc.StartAsync(CancellationToken.None);

            Assert.Equal(new[] { "o1", "o2" }, clob.CanceledOrderIds);
        }

        [Fact]
        public async Task Skips_demo_accounts_and_accounts_without_credentials()
        {
            var state = new TradingState();

            var demo = LiveAccount(1, "Demo");
            demo.IsDemo = true;
            var noCreds = new AccountState { AccountId = 2, Name = "NoCreds", IsDemo = false };
            state.Accounts[demo.AccountId] = demo;
            state.Accounts[noCreds.AccountId] = noCreds;

            var clob = new FakeClobClient();
            clob.AllOpenOrders.Add(("x", "SELL", 0.40m));

            var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
            await svc.StartAsync(CancellationToken.None);

            Assert.Empty(clob.CanceledOrderIds);   // weder Demo noch credential-lose Accounts angefasst
        }

        [Fact]
        public async Task No_open_orders_cancels_nothing()
        {
            var state = new TradingState();
            var acc = LiveAccount(1, "Live");
            state.Accounts[acc.AccountId] = acc;

            var clob = new FakeClobClient();   // AllOpenOrders leer

            var svc = new StartupOrderReconciliationService(state, clob, new TerminalLogger(), new FakeOrderEventLog());
            await svc.StartAsync(CancellationToken.None);

            Assert.Empty(clob.CanceledOrderIds);
        }
    }
}
