
using AyCode.Utils.Extensions;
using Microsoft.AspNetCore.Mvc;
using Nop.Core;
using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Catalog;
using Nop.Services.Common;
using Nop.Services.Customers;
using Nop.Services.Directory;
using Nop.Services.Orders;
using Nop.Web.Framework;
using Nop.Web.Framework.Controllers;
using Nop.Web.Framework.Mvc.Filters;

namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
{
    [Area(AreaNames.ADMIN)]
    [AuthorizeAdmin]
    //[AutoValidateAntiforgeryToken]
    public class InvoiceController : BasePluginController
    {
        private readonly IOrderService _orderService;
        private readonly IWorkContext _workContext;
        private readonly IStoreContext _storeContext;
        private readonly ICustomerService _customerService;
        private readonly ICountryService _countryService;
        private readonly IStateProvinceService _stateProvinceService;
        // Add your InnVoice API service        
        private readonly InnVoiceApiService _innVoiceApiService;
        private readonly IProductService _productService;
        private readonly FruitBankAttributeService _fruitBankAttributeService;

        public InvoiceController(
            IOrderService orderService,
            IWorkContext workContext,
            IStoreContext storeContext,
            ICustomerService customerService,
            ICountryService countryService,
            IStateProvinceService stateProvinceService,
            InnVoiceApiService innVoiceApiService,
            IProductService productService,
            FruitBankAttributeService fruitBankAttributeService)
        {
            _orderService = orderService;
            _workContext = workContext;
            _storeContext = storeContext;
            _customerService = customerService;
            _countryService = countryService;
            _stateProvinceService = stateProvinceService;
            _innVoiceApiService = innVoiceApiService;
            _productService = productService;
            _fruitBankAttributeService = fruitBankAttributeService;
        }

        [HttpPost]
        public async Task<IActionResult> CreateInvoice(int orderId)
        {
            try
            {
                var order = await _orderService.GetOrderByIdAsync(orderId);
                if (order == null)
                    return Json(new { success = false, message = "Order not found" });

                var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId);

                var billingAddress = await _customerService.GetCustomerBillingAddressAsync(customer);
                if (billingAddress == null)
                    return Json(new { success = false, message = "Billing address not found" });

                var country = await _countryService.GetCountryByAddressAsync(billingAddress);
                var countryCode = country?.TwoLetterIsoCode ?? "HU";

                // Create invoice request
                var invoiceRequest = new InvoiceCreateRequest
                {
                    VevoNev = $"{billingAddress.FirstName} {billingAddress.LastName}",
                    VevoIrsz = billingAddress.ZipPostalCode ?? "",
                    VevoTelep = billingAddress.City ?? "",
                    VevoOrszag = countryCode,
                    VevoUtcaHsz = $"{billingAddress.Address1} {billingAddress.Address2}".Trim(),
                    SzamlatombID = 1, // Configure this based on your setup
                    SzamlaKelte = DateTime.Now,
                    TeljesitesKelte = DateTime.Now,
                    Hatarido = DateTime.Now.AddDays(15), // 15 days payment term
                    Devizanem = "Ft",
                    FizetesiMod = order.PaymentMethodSystemName.IsNullOrWhiteSpace() ? "Átutalás" : order.PaymentMethodSystemName,
                    Felretett = false,
                    Proforma = true,
                    Email = billingAddress.Email,
                    MegrendelesSzamStr = order.CustomOrderNumber,
                    Telefon = billingAddress.PhoneNumber
                };

                // Add order items
                var orderItems = await _orderService.GetOrderItemsAsync(order.Id);
                foreach (var item in orderItems)
                {
                    var product = await _productService.GetProductByIdAsync(item.ProductId);

                    invoiceRequest.AddItem(new InvoiceItem
                    {
                        TetelNev = product?.Name ?? "Product",
                        AfaSzoveg = "27%", // Configure VAT rate as needed
                        Brutto = true,
                        EgysegAr = item.UnitPriceInclTax,
                        Mennyiseg = item.Quantity,
                        MennyisegEgyseg = "db",
                        CikkSzam = product?.Sku
                    });
                }

                // Create invoice via API
                var response = await _innVoiceApiService.CreateInvoiceAsync(invoiceRequest);

                if (response.IsSuccess)
                {
                    // TODO: Save invoice details to your database for future reference
                    // You might want to create a custom table to store:
                    // - OrderId
                    // - InnVoice TableId
                    // - Invoice Number
                    // - PDF URL
                    // - Created Date

                    await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Order, string>(orderId, nameof(InvoiceCreateResponse.TechId), response.TechId);

                    return Json(new
                    {
                        success = true,
                        message = "Invoice created successfully",
                        data = new
                        {
                            tableId = response.TableId,
                            invoiceNumber = response.Sorszam,
                            sorszam = response.Sorszam,
                            printUrl = response.PrintUrl
                        }
                    });
                }
                else
                {
                    return Json(new
                    {
                        success = false,
                        message = $"InnVoice API Error: {response.Message}"
                    });
                }
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    success = false,
                    message = $"Error: {ex.Message}"
                });
            }
        }

        [HttpGet]
        public async Task<IActionResult> GetInvoiceStatus(int orderId)
        {
            try
            {
                // Get the invoice from InnVoice using the saved TechId
                var techId = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, string>(
                    orderId,
                    nameof(InvoiceCreateResponse.TechId),
                    _storeContext.GetCurrentStore().Id
                );

                if (string.IsNullOrEmpty(techId))
                {
                    return Json(new
                    {
                        success = false,
                        message = "No invoice TechId found for this order"
                    });
                }

                var invoices = await _innVoiceApiService.GetInvoiceByTechIdAsync(techId);

                if (invoices != null && invoices.Count > 0)
                {
                    var invoice = invoices.FirstOrDefault();
                    return Json(new
                    {
                        success = true,
                        data = new
                        {
                            tableId = invoice.TableId,
                            invoiceNumber = invoice.InvoiceNumberFormatted, // or invoice.InvoiceNumber
                            sorszam = invoice.InvoiceNumberFormatted,
                            printUrl = invoice.PrintUrl,
                            customerName = invoice.CustomerName,
                            totalGross = invoice.TotalGross,
                            currency = invoice.Currency,
                            isProforma = invoice.IsProforma,
                            isDraft = invoice.IsDraft
                        }
                    });
                }

                return Json(new
                {
                    success = false,
                    message = "No invoice found for this order"
                });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    success = false,
                    message = $"Error: {ex.Message}"
                });
            }
        }
    }
}