@using Groceries.Data
@using Microsoft.EntityFrameworkCore

@inject AppDbContext DbContext

<form method="post" @attributes="AdditionalAttributes">
    @* Ensure form action/method are used for implicit submission instead of barcode button *@
    <button type="submit" hidden></button>

    <div data-controller="transaction-item-form">
        <div class="form-field" data-transaction-item-form-target="barcodeFormField" hidden>
            <label class="form-field__label" for="transactionItemBarcode">Barcode</label>
            <div class="form-field__control input">
                <input type="hidden" name="barcodeFormat" value="@barcode?.Format" data-transaction-item-form-target="barcodeFormat" />
                <input class="input__control" id="transactionItemBarcode" name="barcodeData" value="@barcode?.BarcodeData" data-transaction-item-form-target="barcodeData" />
                <button class="input__addon button" type="submit" formmethod="get" formnovalidate data-action="transaction-item-form#scanBarcode" data-transaction-item-form-target="barcodeButton">
                    @* Barcode scanner icon *@
                    <svg class="icon icon--sm" xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M40-120v-200h80v120h120v80H40Zm680 0v-80h120v-120h80v200H720ZM160-240v-480h80v480h-80Zm120 0v-480h40v480h-40Zm120 0v-480h80v480h-80Zm120 0v-480h120v480H520Zm160 0v-480h40v480h-40Zm80 0v-480h40v480h-40ZM40-640v-200h200v80H120v120H40Zm800 0v-120H720v-80h200v200h-80Z" /></svg>
                </button>
            </div>
        </div>

        <fieldset class="form-field">
            <legend class="form-field__label">Item</legend>
            <div class="form-field__control input">
                <input class="input__control flex-2" name="brand" value="@selectedItem?.Brand" placeholder="Brand" list="itemBrands" autocomplete="off" required autofocus data-action="transaction-item-form#filterNames transaction-item-form#setPriceAndQuantity" data-transaction-item-form-target="brand" />
                <input class="input__control flex-5" name="name" value="@selectedItem?.Name" placeholder="Name" list="itemNames" autocomplete="off" required data-action="transaction-item-form#setPriceAndQuantity" />

                <datalist id="itemBrands">
                    @foreach (var item in items.DistinctBy(item => item.Brand))
                    {
                        <option value="@item.Brand" />
                    }
                </datalist>

                <datalist id="itemNames">
                    @foreach (var item in items)
                    {
                        <option value="@item.Name" data-transaction-item-form-target="option" data-brand="@item.Brand" data-price="@item.Price" data-quantity="@item.Quantity" />
                    }
                </datalist>
            </div>
        </fieldset>

        <div class="form-field">
            <label class="form-field__label" for="transactionItemPrice">Price</label>
            <div class="form-field__control input">
                @*<span class="input__inset">@CultureInfo.CurrentCulture.NumberFormat.CurrencySymbol</span>*@
                <input class="input__control" id="transactionItemPrice" name="price" value="@price" type="number" min="0" step="0.01" required data-transaction-item-form-target="price" />
            </div>
        </div>

        <div class="form-field">
            <label class="form-field__label" for="transactionItemQuantity">Quantity</label>
            <div class="form-field__control input">
                <input class="input__control" id="transactionItemQuantity" name="quantity" value="@quantity" type="number" min="1" required data-transaction-item-form-target="quantity" />
            </div>
        </div>
    </div>

    @ChildContent
</form>

@code {
    [Parameter]
    public TransactionItem? TransactionItem { get; set; }

    [Parameter]
    public RenderFragment? ChildContent { get; set; }

    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object>? AdditionalAttributes { get; set; }

    private record ItemModel(Guid Id, string Brand, string Name, decimal? Price, int? Quantity);

    private ItemBarcode? barcode;

    private ItemModel[] items = [];
    private ItemModel? selectedItem;

    private decimal? price;
    private int quantity;

    protected override async Task OnParametersSetAsync()
    {
        barcode = TransactionItem?.Item?.Barcodes.FirstOrDefault();

        items = await DbContext.Items
            .OrderBy(item => item.Brand)
            .ThenBy(item => item.Name)
            .GroupJoin(
                DbContext.ItemPurchases.Where(purchase => purchase.IsLastPurchase),
                item => item.Id,
                lastPurchase => lastPurchase.ItemId,
                (item, purchases) => new { item, purchases })
            .SelectMany(
                group => group.purchases.DefaultIfEmpty(),
                (group, lastPurchase) => new ItemModel(
                    group.item.Id,
                    group.item.Brand,
                    group.item.Name,
                    lastPurchase != null ? lastPurchase.Price : null,
                    lastPurchase != null ? lastPurchase.Quantity : null))
            .ToArrayAsync();

        selectedItem = items.SingleOrDefault(item => item.Id == TransactionItem?.ItemId);

        price = TransactionItem?.Price >= 0 ? TransactionItem.Price : selectedItem?.Price;
        quantity = TransactionItem?.Quantity >= 1 ? TransactionItem.Quantity : (selectedItem?.Quantity ?? 1);
    }
}