using AyCode.Services.Nav;
using AyCode.Services.Nav.Ekaer.Models;
using FruitBank.Common;
using FruitBank.Common.Entities;
using FruitBankHybrid.Shared.Services.SignalRs;

namespace FruitBankHybrid.Shared.Tests
{
    [TestClass]
    public sealed class FruitBankEkaerTests
    {
        private FruitBankSignalRClient _signalRClient = null!;

        [TestInitialize]
        public void TestInit()
        {
            if (!FruitBankConstClient.BaseUrl.Contains("localhost:")) throw new Exception("NEM LOCALHOST-ON TESZTELÜNK!");

            _signalRClient = TestSignalRClientFactory.Create(nameof(FruitBankEkaerTests));
        }

        #region EkaerHistory / Create

        /// <summary>
        /// Backfill: minden meglévő szállítólevélre létrehozza az EkaerHistory rekordot (Pending, XML nélkül).
        /// A generálás a grid Generate gombjával, kézzel történik. Idempotens: újrafuttatva nem duplikál.
        /// </summary>
        [TestMethod]
        public async Task CreateEkaerHistoryForAllShippingDocumentsTest()
        {
            var shippingDocuments = await _signalRClient.GetShippingDocuments();

            Assert.IsNotNull(shippingDocuments);
            Assert.IsNotEmpty(shippingDocuments);

            foreach (var shippingDocument in shippingDocuments)
            {
                var ekaerHistory = await _signalRClient.CreateEkaerHistory(shippingDocument.Id, false);

                Console.WriteLine($"doc#{shippingDocument.Id}: EkaerHistory Id: {(ekaerHistory == null ? "NULL VÁLASZ!" : ekaerHistory.Id.ToString())}; Status: {ekaerHistory?.Status}");

                Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
                Assert.IsGreaterThan(0, ekaerHistory.Id, $"shippingDocument.Id: {shippingDocument.Id}");
                Assert.IsFalse(ekaerHistory.IsOutgoing);
                Assert.IsNotNull(ekaerHistory.Mappings, $"Mappings null (loadRelations?); shippingDocument.Id: {shippingDocument.Id}");
                Assert.AreEqual(shippingDocument.Id, ekaerHistory.Mappings.Single().ForeignKey, $"A mapping nem a forrás-dokumentumra mutat; shippingDocument.Id: {shippingDocument.Id}");
            }

            // Idempotencia: a második hívás a meglévőt adja vissza, nem duplikál.
            var firstDocumentId = shippingDocuments[0].Id;
            var again = await _signalRClient.CreateEkaerHistory(firstDocumentId, false);
            var histories = await _signalRClient.GetEkaerHistoriesByForeignKey(firstDocumentId);

            Assert.IsNotNull(again);
            Assert.IsNotNull(histories);
            Assert.AreEqual(1, histories.Count(h => !h.IsOutgoing), $"Duplikált bejövő EkaerHistory; shippingDocumentId: {firstDocumentId}");
        }

        #endregion EkaerHistory / Create

        #region EkaerHistory / Generate

        /// <summary>
        /// Backfill + teljes Generate-út teszt: minden meglévő szállítólevélre legenerálja az EKÁER XML-t
        /// (rekord upsert a szerveren), így a grid valós adatot kap és a Generate gomb útvonala tesztelt.
        /// </summary>
        //[TestMethod] //Kikommentezve: a generálás a grid Generate gombjával, kézzel történik — a teszt később még kelleni fog.
        public async Task GenerateEkaerXmlDocumentForAllShippingDocumentsTest()
        {
            var shippingDocuments = await _signalRClient.GetShippingDocuments();

            Assert.IsNotNull(shippingDocuments);
            Assert.IsNotEmpty(shippingDocuments);

            foreach (var shippingDocument in shippingDocuments)
            {
                // A generálás mostantól EkaerHistory-Id alapú → előbb a (mapping-elt) rekordot hozzuk létre.
                var created = await _signalRClient.CreateEkaerHistory(shippingDocument.Id, false);
                Assert.IsNotNull(created, $"CreateEkaerHistory null; shippingDocument.Id: {shippingDocument.Id}");
                var ekaerHistory = await _signalRClient.GenerateEkaerXmlDocument(created.Id);

                // A szerver által visszaadott állapot/hibalista logolása — az assertek ELŐTT, hogy hibánál is látsszon.
                Console.WriteLine($"doc#{shippingDocument.Id}: Status: {(ekaerHistory == null ? "NULL VÁLASZ!" : ekaerHistory.Status.ToString())}");
                if (!string.IsNullOrWhiteSpace(ekaerHistory?.ErrorText)) Console.WriteLine($"  ErrorText: {ekaerHistory.ErrorText}");

                Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
                Assert.IsFalse(ekaerHistory.IsOutgoing);
                Assert.AreEqual(shippingDocument.Id, ekaerHistory.Mappings!.Single().ForeignKey, $"A mapping nem a forrás-dokumentumra mutat; shippingDocument.Id: {shippingDocument.Id}");
                Assert.IsFalse(string.IsNullOrWhiteSpace(ekaerHistory.XmlDoc), $"XmlDoc üres; shippingDocument.Id: {shippingDocument.Id}");
                Assert.IsTrue(ekaerHistory.Status is EkaerStatus.Generated or EkaerStatus.ValidationError,
                    $"Status: {ekaerHistory.Status}; shippingDocument.Id: {shippingDocument.Id}; ErrorText: {ekaerHistory.ErrorText}");

                // A grid útvonala: az XmlDoc visszaolvasható tradeCard-dá.
                var tradeCard = NavXmlHelper.Deserialize<TradeCardType>(ekaerHistory.XmlDoc!);

                Assert.IsNotNull(tradeCard);
                Console.WriteLine($"  items: {tradeCard.Items.Count}");
            }
        }

        /// <summary>Idempotencia: az újragenerálás NEM duplikál — dokumentumonként egy bejövő rekord marad.</summary>
        //[TestMethod] //Kikommentezve: a generálás a grid Generate gombjával, kézzel történik — a teszt később még kelleni fog.
        public async Task GenerateEkaerXmlDocumentIsIdempotentTest()
        {
            var shippingDocuments = await _signalRClient.GetShippingDocuments();

            Assert.IsNotNull(shippingDocuments);
            Assert.IsNotEmpty(shippingDocuments);

            var shippingDocumentId = shippingDocuments[0].Id;

            // Generálás EkaerHistory-Id alapján → előbb a rekord (mapping-gel), majd kétszeri generálás ugyanarra az Id-ra.
            var created = await _signalRClient.CreateEkaerHistory(shippingDocumentId, false);
            Assert.IsNotNull(created);

            var first = await _signalRClient.GenerateEkaerXmlDocument(created.Id);
            var second = await _signalRClient.GenerateEkaerXmlDocument(created.Id);

            Assert.IsNotNull(first);
            Assert.IsNotNull(second);
            Assert.AreEqual(first.Id, second.Id, "Az újragenerálás új rekordot hozott létre frissítés helyett!");

            var histories = await _signalRClient.GetEkaerHistoriesByForeignKey(shippingDocumentId);

            Assert.IsNotNull(histories);
            Assert.AreEqual(1, histories.Count(h => !h.IsOutgoing), $"Duplikált bejövő EkaerHistory; shippingDocumentId: {shippingDocumentId}");
        }

        #endregion EkaerHistory / Generate
    }
}
