
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml.Linq;
using System.Linq;
using System.Text;

namespace Nop.Plugin.Misc.FruitBankPlugin.Services
{
    /// <summary>
    /// Service for interacting with InnVoice Invoice API
    /// API Documentation: https://help.innvoice.hu/hc/hu/articles/360003142839
    /// </summary>
    public class InnVoiceApiService
    {
        private readonly HttpClient _httpClient;
        private readonly string _companyName;
        private readonly string _username;
        private readonly string _password;
        private readonly string _baseUrl;

        public InnVoiceApiService(string companyName = "apiteszt", string username = "apiteszt", string password = "dsjfluio4324hjhjfdhkjskjh213kjgsd", string baseUrl = "https://api.innvoice.hu")
        {
            _companyName = companyName ?? throw new ArgumentNullException(nameof(companyName));
            _username = username ?? throw new ArgumentNullException(nameof(username));
            _password = password ?? throw new ArgumentNullException(nameof(password));
            _baseUrl = baseUrl.TrimEnd('/');

            _httpClient = new HttpClient();
            SetupAuthentication();
        }

        private void SetupAuthentication()
        {
            var authToken = Convert.ToBase64String(
                System.Text.Encoding.ASCII.GetBytes($"{_username}:{_password}")
            );
            _httpClient.DefaultRequestHeaders.Authorization =
                new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authToken);
        }

        /// <summary>
        /// Get all invoices
        /// Rate limit: 20 times per hour without ID parameter
        /// </summary>
        public async Task<List<Invoice>> GetAllInvoicesAsync()
        {
            var url = $"{_baseUrl}/{_companyName}/invoice";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoice by internal table ID
        /// </summary>
        public async Task<Invoice> GetInvoiceByIdAsync(int tableId)
        {
            var url = $"{_baseUrl}/{_companyName}/invoice/id/{tableId}";
            var invoices = await GetInvoicesFromUrlAsync(url);
            return invoices.Count > 0 ? invoices[0] : null;
        }

        /// <summary>
        /// Get invoice by invoice number
        /// </summary>
        public async Task<List<Invoice>> GetInvoiceByNumberAsync(string invoiceNumber)
        {
            var url = $"{_baseUrl}/{_companyName}/invoice/invoicenumber/{Uri.EscapeDataString(invoiceNumber)}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoice by invoice number
        /// </summary>
        public async Task<List<Invoice>> GetInvoiceByTechIdAsync(string techId)
        {
            //api.innvoice.hu/%regnev%/invoice/techid/%TECHID%
            var url = $"{_baseUrl}/{_companyName}/invoice/techid/{Uri.EscapeDataString(techId)}";
            return await GetInvoicesFromUrlAsync(url);
        }


        /// <summary>
        /// Get invoices by creation date
        /// Format: YYYYMMDD
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByCreationDateAsync(DateTime date)
        {
            var dateStr = date.ToString("yyyyMMdd");
            var url = $"{_baseUrl}/{_companyName}/invoice/created/{dateStr}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoices by fulfillment date
        /// Format: YYYYMMDD
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByFulfillmentDateAsync(DateTime date)
        {
            var dateStr = date.ToString("yyyyMMdd");
            var url = $"{_baseUrl}/{_companyName}/invoice/fulfillment/{dateStr}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoices by due date
        /// Format: YYYYMMDD
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByDueDateAsync(DateTime date)
        {
            var dateStr = date.ToString("yyyyMMdd");
            var url = $"{_baseUrl}/{_companyName}/invoice/duedate/{dateStr}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoices by payment date
        /// Format: YYYYMMDD
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByPaymentDateAsync(DateTime date)
        {
            var dateStr = date.ToString("yyyyMMdd");
            var url = $"{_baseUrl}/{_companyName}/invoice/paymentdate/{dateStr}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoices by customer tax number
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByCustomerTaxNumberAsync(string taxNumber)
        {
            var url = $"{_baseUrl}/{_companyName}/invoice/taxnumber/{Uri.EscapeDataString(taxNumber)}";
            return await GetInvoicesFromUrlAsync(url);
        }

        /// <summary>
        /// Get invoices modified since a specific timestamp
        /// Format: YYYYMMDDHHmmss (year, month, day, hour, minute, second)
        /// Recommended for tracking changes every 10 minutes
        /// Rate limit: Full queries or queries older than current month limited to 10 times per 30 days
        /// Recommended: Only use current month dates
        /// </summary>
        public async Task<List<Invoice>> GetInvoicesByUpdateTimeAsync(DateTime updateTime)
        {
            var timeStr = updateTime.ToString("yyyyMMddHHmmss");
            var url = $"{_baseUrl}/{_companyName}/invoice/updatedtime/{timeStr}";
            return await GetInvoicesFromUrlAsync(url);
        }

        private async Task<List<Invoice>> GetInvoicesFromUrlAsync(string url)
        {
            try
            {
                var response = await _httpClient.GetAsync(url);
                response.EnsureSuccessStatusCode();

                var content = await response.Content.ReadAsStringAsync();

                // Parse XML response
                return ParseInvoicesFromXml(content);
            }
            catch (HttpRequestException ex)
            {
                throw new InnVoiceApiException($"Error calling InnVoice API: {ex.Message}", ex);
            }
            catch (Exception ex)
            {
                throw new InnVoiceApiException($"Error parsing API response: {ex.Message}", ex);
            }
        }



        private List<Invoice> ParseInvoicesFromXml(string xml)
        {
            var invoices = new List<Invoice>();

            try
            {
                var doc = XDocument.Parse(xml);
                var invoiceElements = doc.Descendants("invoice");

                foreach (var invoiceElement in invoiceElements)
                {
                    var invoice = new Invoice
                    {
                        TableId = GetIntValue(invoiceElement, "TABLE_ID"),
                        VevoID = GetIntValue(invoiceElement, "VevoID"),
                        CustomerName = GetStringValue(invoiceElement, "VevoNev"),
                        CustomerZipCode = GetStringValue(invoiceElement, "VevoIrsz"),
                        CustomerCity = GetStringValue(invoiceElement, "VevoTelep"),
                        CustomerAddress = GetStringValue(invoiceElement, "VevoUtcaHsz"),
                        CustomerCountry = GetStringValue(invoiceElement, "VevoOrszag"),
                        CustomerTaxNumber = GetStringValue(invoiceElement, "VevoAdoszam"),
                        CustomerGroupTaxNumber = GetStringValue(invoiceElement, "VevoCsAdoszam"),
                        PaymentMethod = GetStringValue(invoiceElement, "FizetesiMod"),
                        FulfillmentDate = GetStringValue(invoiceElement, "TeljesitesKelte"),
                        InvoiceDate = GetStringValue(invoiceElement, "SzamlaKelte"),
                        DueDate = GetStringValue(invoiceElement, "Hatarido"),
                        Notes = GetStringValue(invoiceElement, "Megjegyzes"),
                        Currency = GetStringValue(invoiceElement, "Devizanem"),
                        IsDraft = GetIntValue(invoiceElement, "Felretett") == 1,
                        IsCancelled = GetIntValue(invoiceElement, "Storno") == 1,
                        IsAdvance = GetIntValue(invoiceElement, "Eloleg") == 1,
                        IsProforma = GetIntValue(invoiceElement, "Proforma") == 1,
                        TotalNet = GetDecimalValue(invoiceElement, "NettoErtek"),
                        TotalVAT = GetDecimalValue(invoiceElement, "AFAErtek"),
                        TotalGross = GetDecimalValue(invoiceElement, "BruttoErtek"),
                        OutstandingAmount = GetDecimalValue(invoiceElement, "Hatralek"),
                        OverdueAmount = GetDecimalValue(invoiceElement, "LejartHatralek"),
                        PaidAmount = GetDecimalValue(invoiceElement, "Befizetes"),
                        InvoiceNumber = GetStringValue(invoiceElement, "Sorszam"),
                        InvoiceNumberFormatted = GetStringValue(invoiceElement, "SorszamFormatted"),
                        InvoiceId = GetIntValue(invoiceElement, "SzamlaID"),
                        UniqueId = GetStringValue(invoiceElement, "_UniqueID"),
                        ExchangeRate = GetDecimalValue(invoiceElement, "Arfolyam"),
                        InvoiceBookId = GetIntValue(invoiceElement, "SzamlatombID"),
                        InvoiceBookName = GetStringValue(invoiceElement, "SzamlatombNev"),
                        IsElectronic = GetIntValue(invoiceElement, "Eszamla") == 1,
                        Phone = GetStringValue(invoiceElement, "Telefon"),
                        Email = GetStringValue(invoiceElement, "Email"),
                        UpdateTime = GetStringValue(invoiceElement, "_UpdateTime"),
                        QueryTime = GetStringValue(invoiceElement, "QueryTime"),
                        OrderNumber = GetStringValue(invoiceElement, "MegrendelesSzamStr"),
                        OrderDate = GetStringValue(invoiceElement, "MegrendelesIdopontStr"),
                        ShippingName = GetStringValue(invoiceElement, "SzallNev"),
                        ShippingZipCode = GetStringValue(invoiceElement, "SzallIrsz"),
                        ShippingCity = GetStringValue(invoiceElement, "SzallTelep"),
                        ShippingAddress = GetStringValue(invoiceElement, "SzallUtcaHsz"),
                        ShippingCountry = GetStringValue(invoiceElement, "SzallOrszag"),
                        PrintUrl = GetStringValue(invoiceElement, "PrintLink"),
                        InvoiceLink = GetStringValue(invoiceElement, "SzamlaLink"),
                        HealthFundName = GetStringValue(invoiceElement, "VevoEPNev"),
                        HealthFundCode = GetStringValue(invoiceElement, "VevoEPKod")
                    };

                    // Parse line items
                    var itemElements = invoiceElement.Descendants("tetel");
                    foreach (var itemElement in itemElements)
                    {
                        invoice.Items.Add(new InvoiceLineItem
                        {
                            TableId = GetIntValue(itemElement, "TABLE_ID"),
                            ItemName = GetStringValue(itemElement, "TetelNev"),
                            ArticleNumber = GetStringValue(itemElement, "CikkSzam"),
                            VTSZSZJ = GetStringValue(itemElement, "VTSZSZJ"),
                            VATText = GetStringValue(itemElement, "AfaSzoveg"),
                            VATRate = GetDecimalValue(itemElement, "AfaKulcs"),
                            IsGross = GetIntValue(itemElement, "Brutto") == 1,
                            UnitPrice = GetDecimalValue(itemElement, "EgysegAr"),
                            Quantity = GetDecimalValue(itemElement, "Mennyiseg"),
                            Unit = GetStringValue(itemElement, "MennyisegEgyseg"),
                            ProductId = GetIntValue(itemElement, "TermekID"),
                            DiscountAmount = GetDecimalValue(itemElement, "KedvezmenyOsszeg")
                        });
                    }

                    invoices.Add(invoice);
                }
            }
            catch (Exception ex)
            {
                throw new InnVoiceApiException($"Error parsing XML: {ex.Message}", ex);
            }

            return invoices;
        }

        private string GetStringValue(XElement element, string name)
        {
            return element.Element(name)?.Value?.Trim() ?? string.Empty;
        }

        private int GetIntValue(XElement element, string name)
        {
            var value = GetStringValue(element, name);
            return int.TryParse(value, out var result) ? result : 0;
        }

        private decimal GetDecimalValue(XElement element, string name)
        {
            var value = GetStringValue(element, name);
            return decimal.TryParse(value, out var result) ? result : 0m;
        }


        /// <summary>
        /// Create a new invoice
        /// </summary>
        public async Task<InvoiceCreateResponse> CreateInvoiceAsync(InvoiceCreateRequest request)
        {
            var url = $"{_baseUrl}/{_companyName}/invoice";

            var xml = request.ToXml();
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("data", xml)
            });

            try
            {
                var response = await _httpClient.PostAsync(url, content);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();
                return InvoiceCreateResponse.FromXml(responseContent);
            }
            catch (HttpRequestException ex)
            {
                throw new InnVoiceApiException($"Error creating invoice: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// Update an existing invoice
        /// </summary>
        public async Task<InvoiceCreateResponse> UpdateInvoiceAsync(int tableId, InvoiceCreateRequest request)
        {
            // Set the VevoID if updating customer information
            var url = $"{_baseUrl}/{_companyName}/invoice";

            var xml = request.ToXml();
            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("data", xml),
                new KeyValuePair<string, string>("id", tableId.ToString())
            });

            try
            {
                var response = await _httpClient.PostAsync(url, content);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();
                return InvoiceCreateResponse.FromXml(responseContent);
            }
            catch (HttpRequestException ex)
            {
                throw new InnVoiceApiException($"Error updating invoice: {ex.Message}", ex);
            }
        }

    }

    // Models
    public class Invoice
    {
        public int TableId { get; set; }
        public int VevoID { get; set; }
        public string CustomerName { get; set; }
        public string CustomerZipCode { get; set; }
        public string CustomerCity { get; set; }
        public string CustomerAddress { get; set; }
        public string CustomerCountry { get; set; }
        public string CustomerTaxNumber { get; set; }
        public string CustomerGroupTaxNumber { get; set; }
        public string PaymentMethod { get; set; }
        public string FulfillmentDate { get; set; }
        public string InvoiceDate { get; set; }
        public string DueDate { get; set; }
        public string Notes { get; set; }
        public string Currency { get; set; }
        public bool IsDraft { get; set; }
        public bool IsCancelled { get; set; }
        public bool IsAdvance { get; set; }
        public bool IsProforma { get; set; }
        public decimal TotalNet { get; set; }
        public decimal TotalVAT { get; set; }
        public decimal TotalGross { get; set; }
        public decimal OutstandingAmount { get; set; }
        public decimal OverdueAmount { get; set; }
        public decimal PaidAmount { get; set; }
        public string InvoiceNumber { get; set; }
        public string InvoiceNumberFormatted { get; set; }
        public int InvoiceId { get; set; }
        public string UniqueId { get; set; }
        public decimal ExchangeRate { get; set; }
        public int InvoiceBookId { get; set; }
        public string InvoiceBookName { get; set; }
        public bool IsElectronic { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string UpdateTime { get; set; }
        public string QueryTime { get; set; }
        public string OrderNumber { get; set; }
        public string OrderDate { get; set; }
        public string ShippingName { get; set; }
        public string ShippingZipCode { get; set; }
        public string ShippingCity { get; set; }
        public string ShippingAddress { get; set; }
        public string ShippingCountry { get; set; }
        public string PrintUrl { get; set; }
        public string InvoiceLink { get; set; }
        public string HealthFundName { get; set; }
        public string HealthFundCode { get; set; }

        public List<InvoiceLineItem> Items { get; set; } = new List<InvoiceLineItem>();
    }

    public class InvoiceLineItem
    {
        public int TableId { get; set; }
        public string ItemName { get; set; }
        public string ArticleNumber { get; set; }
        public string VTSZSZJ { get; set; }
        public string VATText { get; set; }
        public decimal VATRate { get; set; }
        public bool IsGross { get; set; }
        public decimal UnitPrice { get; set; }
        public decimal Quantity { get; set; }
        public string Unit { get; set; }
        public int ProductId { get; set; }
        public decimal DiscountAmount { get; set; }
    }


    // Invoice Creation Models
    public class InvoiceCreateRequest
    {
        public int VevoID { get; set; } = 0;
        public string VevoNev { get; set; }
        public string VevoIrsz { get; set; }
        public string VevoOrszag { get; set; }
        public string VevoTelep { get; set; }
        public string VevoUtcaHsz { get; set; }
        public string VevoEPNev { get; set; }
        public string VevoEPKod { get; set; }
        public string SzallNev { get; set; }
        public string SzallIrsz { get; set; }
        public string SzallTelep { get; set; }
        public string SzallUtcaHsz { get; set; }
        public string SzallOrszag { get; set; }
        public int SzamlatombID { get; set; }
        public DateTime SzamlaKelte { get; set; }
        public DateTime TeljesitesKelte { get; set; }
        public DateTime Hatarido { get; set; }
        public string Devizanem { get; set; }
        public string FizetesiMod { get; set; }
        public string Megjegyzes { get; set; }
        public string Nyelv1 { get; set; }
        public string Nyelv2 { get; set; }
        public decimal? Arfolyam { get; set; }
        public string ArfolyamDeviza { get; set; }
        public bool Fizetve { get; set; }
        public bool Eszamla { get; set; }
        public string VevoAdoszam { get; set; }
        public string VevoCsAdoszam { get; set; }
        public string Telefon { get; set; }
        public string Email { get; set; }
        public string MegrendelesSzamStr { get; set; }
        public string MegrendelesIdopontStr { get; set; }
        public bool Felretett { get; set; }
        public bool Proforma { get; set; }
        public bool AutomatikusAr { get; set; }
        public bool Eloleg { get; set; }
        public bool Sendmail { get; set; }
        public string MailSubject { get; set; }
        public string MailBody { get; set; }
        public string Eredetiszamla { get; set; }

        public List<InvoiceItem> Items { get; set; } = new List<InvoiceItem>();

        public void AddItem(InvoiceItem item)
        {
            Items.Add(item);
        }

        public string ToXml()
        {
            var invoices = new XElement("invoices");
            var invoice = new XElement("invoice");

            if (VevoID > 0)
                invoice.Add(new XElement("VevoID", new XCData(VevoID.ToString())));

            invoice.Add(new XElement("VevoNev", new XCData(VevoNev ?? "")));
            invoice.Add(new XElement("VevoIrsz", new XCData(VevoIrsz ?? "")));
            invoice.Add(new XElement("VevoTelep", new XCData(VevoTelep ?? "")));
            invoice.Add(new XElement("VevoOrszag", new XCData(VevoOrszag ?? "")));
            invoice.Add(new XElement("VevoUtcaHsz", new XCData(VevoUtcaHsz ?? "")));

            if (!string.IsNullOrEmpty(VevoEPNev))
                invoice.Add(new XElement("VevoEPNev", new XCData(VevoEPNev)));
            if (!string.IsNullOrEmpty(VevoEPKod))
                invoice.Add(new XElement("VevoEPKod", new XCData(VevoEPKod)));
            if (!string.IsNullOrEmpty(SzallNev))
                invoice.Add(new XElement("SzallNev", new XCData(SzallNev)));
            if (!string.IsNullOrEmpty(SzallIrsz))
                invoice.Add(new XElement("SzallIrsz", new XCData(SzallIrsz)));
            if (!string.IsNullOrEmpty(SzallTelep))
                invoice.Add(new XElement("SzallTelep", new XCData(SzallTelep)));
            if (!string.IsNullOrEmpty(SzallUtcaHsz))
                invoice.Add(new XElement("SzallUtcaHsz", new XCData(SzallUtcaHsz)));
            if (!string.IsNullOrEmpty(SzallOrszag))
                invoice.Add(new XElement("SzallOrszag", new XCData(SzallOrszag)));

            invoice.Add(new XElement("SzamlatombID", new XCData(SzamlatombID.ToString())));
            invoice.Add(new XElement("SzamlaKelte", new XCData(SzamlaKelte.ToString("yyyy.MM.dd."))));
            invoice.Add(new XElement("TeljesitesKelte", new XCData(TeljesitesKelte.ToString("yyyy.MM.dd."))));
            invoice.Add(new XElement("Hatarido", new XCData(Hatarido.ToString("yyyy.MM.dd."))));
            invoice.Add(new XElement("Devizanem", new XCData(Devizanem ?? "")));
            invoice.Add(new XElement("FizetesiMod", new XCData(FizetesiMod ?? "")));

            if (!string.IsNullOrEmpty(Megjegyzes))
                invoice.Add(new XElement("Megjegyzes", new XCData(Megjegyzes)));
            if (!string.IsNullOrEmpty(Nyelv1))
                invoice.Add(new XElement("Nyelv1", new XCData(Nyelv1)));
            if (!string.IsNullOrEmpty(Nyelv2))
                invoice.Add(new XElement("Nyelv2", new XCData(Nyelv2)));
            if (Arfolyam.HasValue)
                invoice.Add(new XElement("Arfolyam", new XCData(Arfolyam.Value.ToString())));
            if (!string.IsNullOrEmpty(ArfolyamDeviza))
                invoice.Add(new XElement("ArfolyamDeviza", new XCData(ArfolyamDeviza)));

            invoice.Add(new XElement("Fizetve", Fizetve ? "1" : "0"));
            invoice.Add(new XElement("Eszamla", Eszamla ? "1" : "0"));

            if (!string.IsNullOrEmpty(VevoAdoszam))
                invoice.Add(new XElement("VevoAdoszam", new XCData(VevoAdoszam)));
            if (!string.IsNullOrEmpty(VevoCsAdoszam))
                invoice.Add(new XElement("VevoCsAdoszam", new XCData(VevoCsAdoszam)));
            if (!string.IsNullOrEmpty(Telefon))
                invoice.Add(new XElement("Telefon", new XCData(Telefon)));
            if (!string.IsNullOrEmpty(Email))
                invoice.Add(new XElement("Email", new XCData(Email)));
            if (!string.IsNullOrEmpty(MegrendelesSzamStr))
                invoice.Add(new XElement("MegrendelesSzamStr", new XCData(MegrendelesSzamStr)));
            if (!string.IsNullOrEmpty(MegrendelesIdopontStr))
                invoice.Add(new XElement("MegrendelesIdopontStr", new XCData(MegrendelesIdopontStr)));

            invoice.Add(new XElement("Felretett", Felretett ? "1" : "0"));
            invoice.Add(new XElement("Proforma", Proforma ? "1" : "0"));

            if (AutomatikusAr)
                invoice.Add(new XElement("AutomatikusAr", "1"));
            if (Eloleg)
                invoice.Add(new XElement("Eloleg", "1"));
            if (Sendmail)
            {
                invoice.Add(new XElement("Sendmail", "1"));
                if (!string.IsNullOrEmpty(MailSubject))
                    invoice.Add(new XElement("MailSubject", new XCData(MailSubject)));
                if (!string.IsNullOrEmpty(MailBody))
                    invoice.Add(new XElement("MailBody", new XCData(MailBody)));
            }
            if (!string.IsNullOrEmpty(Eredetiszamla))
                invoice.Add(new XElement("Eredetiszamla", new XCData(Eredetiszamla)));

            // Add items
            foreach (var item in Items)
            {
                var tetel = new XElement("tetel");
                tetel.Add(new XElement("TetelNev", new XCData(item.TetelNev ?? "")));
                tetel.Add(new XElement("AfaSzoveg", item.AfaSzoveg ?? ""));
                tetel.Add(new XElement("Brutto", item.Brutto ? "1" : "0"));
                tetel.Add(new XElement("EgysegAr", item.EgysegAr.ToString()));
                tetel.Add(new XElement("Mennyiseg", item.Mennyiseg.ToString()));
                tetel.Add(new XElement("MennyisegEgyseg", new XCData(item.MennyisegEgyseg ?? "")));

                if (item.KedvezmenyOsszeg.HasValue)
                    tetel.Add(new XElement("KedvezmenyOsszeg", item.KedvezmenyOsszeg.Value.ToString()));
                if (item.TermekID.HasValue)
                    tetel.Add(new XElement("TermekID", item.TermekID.Value.ToString()));
                if (!string.IsNullOrEmpty(item.Megjegyzes))
                    tetel.Add(new XElement("Megjegyzes", new XCData(item.Megjegyzes)));
                if (!string.IsNullOrEmpty(item.CikkSzam))
                    tetel.Add(new XElement("CikkSzam", new XCData(item.CikkSzam)));
                if (!string.IsNullOrEmpty(item.VTSZSZJ))
                    tetel.Add(new XElement("VTSZSZJ", new XCData(item.VTSZSZJ)));
                if (item.ElolegSzamlaTABLE_ID.HasValue)
                    tetel.Add(new XElement("ElolegSzamlaTABLE_ID", item.ElolegSzamlaTABLE_ID.Value.ToString()));
                if (!string.IsNullOrEmpty(item.ElolegSzamlaSorszam))
                    tetel.Add(new XElement("ElolegSzamlaSorszam", new XCData(item.ElolegSzamlaSorszam)));

                invoice.Add(tetel);
            }

            invoices.Add(invoice);
            return new XDeclaration("1.0", "UTF-8", null).ToString() + "\n" + invoices.ToString();
        }
    }

    public class InvoiceItem
    {
        public string TetelNev { get; set; }
        public string AfaSzoveg { get; set; }
        public bool Brutto { get; set; }
        public decimal EgysegAr { get; set; }
        public decimal Mennyiseg { get; set; }
        public string MennyisegEgyseg { get; set; }
        public decimal? KedvezmenyOsszeg { get; set; }
        public int? TermekID { get; set; }
        public string Megjegyzes { get; set; }
        public string CikkSzam { get; set; }
        public string VTSZSZJ { get; set; }
        public int? ElolegSzamlaTABLE_ID { get; set; }
        public string ElolegSzamlaSorszam { get; set; }
    }

    public class InvoiceCreateResponse
    {
        public string ErrorCode { get; set; }
        public string Message { get; set; }
        public int? TableId { get; set; }
        public int? VevoID { get; set; }
        public string TechId { get; set; }
        public string Sorszam { get; set; }
        public string PrintUrl { get; set; }

        public bool IsSuccess => ErrorCode == "200";

        public static InvoiceCreateResponse FromXml(string xml)
        {
            var doc = XDocument.Parse(xml);
            var invoice = doc.Descendants("invoice").FirstOrDefault();

            if (invoice == null)
            {
                throw new InnVoiceApiException("Invalid XML response format");
            }

            return new InvoiceCreateResponse
            {
                ErrorCode = invoice.Element("error")?.Value,
                Message = invoice.Element("message")?.Value?.Trim(),
                TableId = int.TryParse(invoice.Element("TABLE_ID")?.Value?.Trim(), out var tid) ? tid : (int?)null,
                VevoID = int.TryParse(invoice.Element("VevoID")?.Value?.Trim(), out var vid) ? vid : (int?)null,
                TechId = invoice.Element("techid")?.Value?.Trim(),
                Sorszam = invoice.Element("Sorszam")?.Value?.Trim(),
                PrintUrl = invoice.Element("PrintUrl")?.Value?.Trim()
            };
        }
    }
}