using Blazorise;
using Microsoft.AspNetCore.Components;
using QuestPDF;
using QuestPDF.Fluent;
using QuestPDF.Infrastructure;
using Server.Components.Dialogs;
using Server.Data;
using Server.Model;

namespace Server.Components.Pages
{
    public partial class InvoicePage
    {
        #region Dependencies

        [Inject]
        private IModalService ModalService { get; set; } = null!;

        [Inject]
        private NavigationManager NavigationManager { get; set; } = null!;

        #endregion

        #region Parameters

        /// <summary>
        ///     Gets or sets the identifier for the invoice.
        /// </summary>
        /// <remarks>
        ///     This property is used to uniquely identify an invoice.
        ///     It is a nullable string which allows handling cases where no invoice ID is provided.
        /// </remarks>
        [Parameter]
        public string? InvoiceId { get; set; }

        #endregion

        #region Private Properties

        private string? AlertMessage { get; set; }

        private InvoiceModel Invoice { get; set; } = new();

        #endregion

        #region Override SetParametersAsync

        //// <inheritdoc />
        public override async Task SetParametersAsync(ParameterView parameters)
        {
            parameters.SetParameterProperties(this);

            // No invoice id
            if (string.IsNullOrWhiteSpace(InvoiceId))
            {
                NavigationManager.NavigateTo("/");
                return;
            }

            // Existing
            var invoice = await InvoiceData.LoadAsync(InvoiceId);
            if (invoice == null)
            {
                NavigationManager.NavigateTo("/");
                return;
            }

            // Found
            Invoice = invoice;

            Settings.License = LicenseType.Community;

            await CustomerData.LoadAsync();

            await base.SetParametersAsync(ParameterView.Empty);
        }

        #endregion

        #region Private Method CreateItemAsync

        /// <summary>
        ///     Asynchronously creates a new item and adds it to the current invoice.
        /// </summary>
        /// <returns>A Task representing the asynchronous operation.</returns>
        private Task CreateItemAsync()
        {
            Invoice.Items.Add(new());
            return Task.CompletedTask;
        }

        #endregion

        #region Private Method Generate

        private async Task Generate()
        {
            var doc = new InvoiceDocument(new()
            {
                InvoiceId = "3129",
                Seller = SettingsData.Instance.SellerAddress,
                PaymentData = SettingsData.Instance.PaymentData,
                Comment = SettingsData.Instance.Comment,
                Customer = new()
                {
                    Name = "DRK-Ortsverein Dreis-Tiefenbach e.V.",
                    Name2 = "Jutta Weber",
                    Street = "Feldwasserstraße 9",
                    Zip = "57250",
                    City = "Netphen"
                },
                Items =
                [
                    new OrderItem
                    {
                        Name = "Schulung DRK-Cloud in Std.",
                        Description = "09.12.2022 - Schulungsgruppe 1",
                        Quantity = 5,
                        TaxType = TaxType.Tax19,
                        PriceNetto = 29
                    },
                    new OrderItem
                    {
                        Name = "Schulung DRK-Cloud in Std.",
                        Description = "10.12.2022 - Schulungsgruppe 2",
                        Quantity = 5,
                        TaxType = TaxType.Tax19,
                        PriceNetto = 29
                    }
                ]
            });

            doc.GeneratePdfAndShow();
        }

        #endregion

        #region Private Method GenerateInvoiceAsync

        private Task GenerateInvoiceAsync()
        {
            var doc = new InvoiceDocument(Invoice);
            doc.GeneratePdfAndShow();
            return Task.CompletedTask;
        }

        #endregion

        #region Private Method SaveInvoiceAsync

        /// <summary>
        ///     Asynchronously saves the current invoice.
        /// </summary>
        /// <returns>A Task representing the asynchronous save operation.</returns>
        private async Task SaveInvoiceAsync()
        {
            AlertMessage = null;

            await InvoiceData.SaveAsync(Invoice);
            NavigationManager.NavigateTo("/invoices");
        }

        #endregion

        #region Private Method SelectCustomerAsync

        private async Task SelectCustomerAsync()
        {
            await AddressSelector.ShowAsync(ModalService, async address =>
            {
                Invoice.Customer = address;
                await InvokeAsync(StateHasChanged);
            });
        }

        #endregion
    }
}