using Elwig.Helpers;
using Elwig.Helpers.Export;
using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using System.Reflection;
using System.Xml;

namespace Tests.UnitTests.HelperTests {
    // see https://www.iso20022.org/iso-20022-message-definitions
    // and https://www.iso20022.org/catalogue-messages/iso-20022-messages-archive?search=pain
    [TestFixture]
    public class EbicsTest {

        public static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_ebics.xml");
        public static readonly string Iban = "AT123456789012345678";

        private static void ValidateSchema(string xmlPath, int version, string? extra = null) {
            XmlDocument xml = new();
            xml.Load(xmlPath);
            var schema = new XmlTextReader(Assembly.GetExecutingAssembly()
                .GetManifestResourceStream($"Tests.Resources.Schemas.pain.001.001.{version:00}{extra}.xsd")!);
            xml.Schemas.Add(null, schema);
            xml.Validate(null);
        }

        private static async Task CreateXmlFile(int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) {
            var v = new PaymentVar() {
                Year = 2020,
                AvNr = 1,
                Name = "Endauszahlung",
                TransferDate = new DateOnly(2021, 6, 15),
                Data = "",
                DateString = "2021-01-31",
            };
            using var ctx = new AppDbContext();
            var members = ctx.Members.ToList();
            Assert.That(members, Has.Count.GreaterThan(0));
            using var exporter = new Ebics(v, FileName, version, mode);
            await exporter.ExportAsync(members.Select(m => new Transaction(m, 1234.56m, "EUR", m.MgNr % 100)));
        }

        [TearDown]
        public static void RemoveXmlFile() {
            File.Delete(FileName);
        }

        [Test]
        [Ignore("Version has no need to be supported")]
        public async Task Test_CustomerCreditTransferInitiationV01() {
            await CreateXmlFile(1);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 1));
        }

        [Test]
        [Ignore("Version has no need to be supported")]
        public async Task Test_CustomerCreditTransferInitiationV02() {
            await CreateXmlFile(2);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 2));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV03() {
            await CreateXmlFile(3);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 3));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV03_AT() {
            await CreateXmlFile(3, Ebics.AddressMode.Lines);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 3, ".AT"));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV04() {
            await CreateXmlFile(4);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 4));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV05() {
            await CreateXmlFile(5);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 5));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV06() {
            await CreateXmlFile(6);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 6));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV07() {
            await CreateXmlFile(7);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 7));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV08() {
            await CreateXmlFile(8);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 8));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV09() {
            await CreateXmlFile(9);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 9));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV10() {
            await CreateXmlFile(10);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 10));
        }

        [Test]
        public async Task Test_CustomerCreditTransferInitiationV11() {
            await CreateXmlFile(11);
            Assert.DoesNotThrow(() => ValidateSchema(FileName, 11));
        }
    }
}
