@page "/inventur/scannen"
@attribute [Authorize]
@using WerksverkaufScanner.Data
@using WerksverkaufScanner.Services
@using Microsoft.AspNetCore.Components.Web
@inject StammdatenCache Cache
@inject InventurService Inventur
@inject IJSRuntime JS

<h2>Inventur – Scannen / Eingeben</h2>

@if (needsSetup)
{
    <div class="alert alert-warning d-flex align-items-center" role="alert">
        <div>
            Es fehlt die Filial-Id. Bitte auf der Seite <a href="/einstellungen" class="alert-link">Einstellungen</a> die Filial-Id prüfen.
        </div>
    </div>
}
else
{
    <!-- 1) Barcode ODER Artikelnummer -->
    <input @ref="barcodeRef" id="barcode"
           class="form-control form-control-lg mb-2"
           placeholder="Barcode scannen oder Artikelnummer eingeben"
           @bind="scanText" @bind:event="oninput"
           @onkeydown="OnScanKey"
           @onfocus="FeldMengeLeeren" />

  @if (gefunden is not null)
{
    <div class="alert alert-info py-2 mb-2">
        <strong>@gefunden.Bezeichnung</strong>
        <span class="text-muted">
            · @gefunden.ArtikelNummer
            @* Variante nur anzeigen, wenn wirklich eindeutig *@
            @if (varianten is null)
            {
                <text>· @GetVarianteLabel(gefunden)</text>
                @* Nur anzeigen, wenn NUR eine Variante existiert bzw. gewählt wurde *@
            }
            @if (!string.IsNullOrWhiteSpace(gefunden.Text))
            {
                <text> · @gefunden.Text-Artikel</text>
            }
        </span>
    </div>
}


    @if (varianten is { Count: > 1 })
    {
        <div class="mb-3">
            <div class="mb-1">Varianten gefunden – bitte auswählen:</div>
            <div class="d-flex flex-wrap gap-2">
                @foreach (var art in varianten)
                {
                    var isActive = ReferenceEquals(gefunden, art);
                    <button type="button"
                            class="btn btn-lg"
                            style="@GetButtonStyle(art, isActive)"
                            @onclick="@(() => VarianteAuswaehlen(art))">
                        @GetVarianteLabel(art)
                    </button>
                }
            </div>
        </div>
    }

    // Mengenfeld nur anzeigen, wenn EINDEUTIG Variante gewählt!
    if (gefunden is not null && varianten == null)
    {
        <input @ref="mengeRef" id="menge"
               class="form-control form-control-lg mb-2"
               placeholder="Menge"
               @bind="mengeText" @bind:event="oninput"
               @onkeydown="OnMengeKey"
               inputmode="numeric" pattern="[0-9]*" />
    }
}

@if (!string.IsNullOrEmpty(status))
{
    <div class="mt-2 @(ok ? "text-success" : "text-danger")">@status</div>
}

@code {
    // --- Konfig aus localStorage ---
    private bool needsSetup;
    private string? filialId;
    private int? inventurId;
    private string? currentUser;

    // Eingaben/Status
    private string? scanText;
    private string? mengeText;
    private Artikel? gefunden;
    private List<Artikel>? varianten;
    private string? status;
    private bool ok;

    // Fokussteuerung
    private ElementReference barcodeRef, mengeRef;
    private bool focusBarcode = true;
    private bool focusMenge;

    protected override async Task OnInitializedAsync()
    {
        if (Cache.GetArtikel().Count == 0)
            await Cache.RefreshAsync();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        try
        {
            var f = await JS.InvokeAsync<string?>("localStorage.getItem", "scannerpilot.filialId");
            if (!string.IsNullOrWhiteSpace(f))
            {
                await LoadConfigAsync();
                if (focusBarcode)
                {
                    focusBarcode = false;
                    await barcodeRef.FocusAsync();
                }
                if (focusMenge)
                {
                    focusMenge = false;
                    await mengeRef.FocusAsync();
                }
            }
            else
            {
                needsSetup = true;
            }
        }
        catch
        {
            needsSetup = true;
            filialId = null;
        }
    }

    private async Task LoadConfigAsync()
    {
        try
        {
            var f = await JS.InvokeAsync<string?>("localStorage.getItem", "scannerpilot.filialId");
            var u = await JS.InvokeAsync<string?>("localStorage.getItem", "scannerpilot.user");
            filialId = f?.Trim('"');
            currentUser = u?.Trim('"');
            needsSetup = string.IsNullOrWhiteSpace(filialId);
        }
        catch
        {
            needsSetup = true;
            filialId = null;
            currentUser = null;
        }
    }

    private async Task OnScanKey(KeyboardEventArgs e)
    {
        if (e.Key == "Enter" && !needsSetup)
            await SucheArtikelAsync();
    }

    private void FeldMengeLeeren(FocusEventArgs e)
    {
        mengeText = null;
        gefunden = null;
        varianten = null;
        StateHasChanged();
        scanText = null; 
    }

    private async Task SucheArtikelAsync()
    {
        status = null;
        ok = false;
        gefunden = null;
        varianten = null;
        mengeText = null; // Mengenfeld leeren bei neuem Scan

        var input = scanText?.Trim();
        // scanText = string.Empty;

        if (string.IsNullOrWhiteSpace(input))
        {
            focusBarcode = true;
            StateHasChanged();
            return;
        }

        if (Cache.GetArtikel().Count == 0)
            await Cache.RefreshAsync();

        var alle = Cache.GetArtikel();
        var matches = alle
            .Where(a =>
                string.Equals(a.Barcode, input, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(a.ArtikelNummer, input, StringComparison.OrdinalIgnoreCase))
            .OrderBy(a => a.Variante)
            .ThenBy(a => a.ArtikelVariantenId)
            .ToList();

        if (matches.Count == 0)
        {
            status = $"Kein Artikel gefunden für „{input}“.";
            focusBarcode = true;
            scanText = null;
        }
        else if (matches.Count == 1)
        {
            gefunden = matches[0];
            varianten = null;
            focusBarcode = false;
            focusMenge = true;
        }
        else
        {
            gefunden = matches[0]; // Zeige immer den ersten Artikel im Info-Kasten
            varianten = matches;
            focusMenge = false;
            focusBarcode = false;

            await JS.InvokeVoidAsync("removeFocus", barcodeRef);
        }

        StateHasChanged();
    }

    private void VarianteAuswaehlen(Artikel art)
    {
        gefunden = art;
        varianten = null;
        focusBarcode = false;
        focusMenge = true;
        StateHasChanged();
    }

    private async Task OnMengeKey(KeyboardEventArgs e)
    {
        if (e.Key == "Enter")
            await SpeichernAsync();
    }

    private async Task SpeichernAsync()
    {
        status = null;
        ok = false;

        if (needsSetup)
        {
            status = "Bitte zuerst die Inventur vorbereiten (QR-Code scannen).";
            return;
        }

        if (gefunden is null)
        {
            status = "Bitte zuerst Barcode scannen und eine Variante auswählen.";
            focusBarcode = true;
            StateHasChanged();
            return;
        }

        if (!int.TryParse(mengeText, out var menge) || menge <= 0 || menge >= 100000)
        {
            status = "Ungültige Menge. Bitte eine natürliche Zahl (1,2 - 99999) eingeben.";
            focusMenge = true;
            StateHasChanged();
            return;
        }

        try
        {
            if (filialId is null)
                await LoadConfigAsync();

            if (string.IsNullOrWhiteSpace(filialId))
                throw new InvalidOperationException("Filial-ID fehlt.");

            var rows = await Inventur.SaveAsync(
                filialId,
                gefunden.ArtikelId,
                gefunden.ArtikelVariantenId,
                gefunden.Variante,
                menge,
                currentUser ?? string.Empty
            );

            ok = rows > 0;
            status = ok
                ? $"Gespeichert: Artikel {gefunden.Bezeichnung} ({gefunden.ArtikelNummer}) mit Menge {menge} als {GetVarianteLabel(gefunden)}-Artikel."
                : "Nichts gespeichert.";

            mengeText = null;
            gefunden = null;
            varianten = null;
            focusBarcode = true;
            scanText = null;
        }
        catch (Exception ex)
        {
            ok = false;
            status = "Fehler beim Speichern: " + ex.Message;
            focusMenge = true;
        }

        StateHasChanged();
    }

    // ---------- Hilfsfunktionen für Button-Darstellung ----------

    private string GetVarianteLabel(Artikel art)
    {
        if (!string.IsNullOrWhiteSpace(art.Text))
            return art.Text;

        if (!string.IsNullOrWhiteSpace(art.Farbe))
            return art.Farbe;

        if (art.Variante == 0)
        {
            return "Standard";
        }
        return $"Variante {art.Variante}";
    }

    private string GetButtonStyle(Artikel art, bool isActive)
    {
        var bg = GetCssColorFromFarbe(art.Farbe);
        var border = isActive ? "3px solid black" : "1px solid #666";
        var color = NeedsDarkText(art.Farbe) ? "black" : "white";
        return $"background-color:{bg};color:{color};border:{border};min-width:6rem;";
    }

    private string GetCssColorFromFarbe(string? farbe)
    {
        if (string.IsNullOrWhiteSpace(farbe))
            return "#e0e0e0";
        switch (farbe.Trim().ToLowerInvariant())
        {
            case "rot": return "#dc3545";
            case "blau": return "#007bff";
            case "gruen":
            case "grün": return "#28a745";
            case "gelb": return "#ffc107";
            case "orange": return "#fd7e14";
            case "lila": return "#6f42c1";
            default: return "#e0e0e0"; // neutral
        }
    }

    private bool NeedsDarkText(string? farbe)
    {
        if (string.IsNullOrWhiteSpace(farbe))
            return true;
        var f = farbe.Trim().ToLowerInvariant();
        return f is "gelb" or "orange";
    }
}
