@page "/stock/products"
@using Blazored.Typeahead
@using phronCare.UIBlazor.Services.Stock
@using phronCare.UIBlazor.Services.Lookups
@using Domain.Entities
@using Domain.Generics
@inject IToastService toastService
@inject NavigationManager Navigation
@inject LSProductService productService
@inject IStockLookUpService lookUpService

<div class="card" style="zoom:80%">
    <div class="card-header d-flex justify-content-center align-items-center" style="zoom:80%;">
        <h3 class="card-title m-0">Catálogo de Productos Médicos</h3>
    </div>
    <div class="card-body px-4">
        <!-- FILTROS -->
        <div class="mb-3 row g-2 align-items-end">
            <div class="col-md-1">
                <label for="code">Código</label>
                <input id="code" class="form-control form-control-sm" style="height: 38px;" placeholder="Código interno o externo" @bind="SearchParams.Code" />
            </div>
            <div class="col-sm">
                <label for="description">Nombre o descripción</label>
                <input id="description" class="form-control form-control-sm" style="height: 38px;" placeholder="Nombre o descripción" @bind="SearchParams.Description" />
            </div>
            <div class="col-sm">
                <label for="division">División</label>
                <BlazoredTypeahead id="division" TItem="ELookUpItem" TValue="ELookUpItem"
                                   SearchMethod="@(filter => lookUpService.GetProductDivisionsAsync(filter).ContinueWith(t => t.Result.AsEnumerable()))"
                                   Value="_selectedDivision" ValueChanged="OnDivisionSelected"
                                   ValueExpression="@(() => _selectedDivision)"
                                   Placeholder="Buscar división..." TextProperty="Nombre" MaximumSuggestions="5"
                                   class="form-control form-control-sm" style="height: 38px;">
                    <ResultTemplate Context="item">@item.Nombre</ResultTemplate>
                    <SelectedTemplate Context="item">@item.Nombre</SelectedTemplate>
                </BlazoredTypeahead>
            </div>
            <div class="col-sm-2">
                <label for="unitmeasure">Unidad</label>
                <BlazoredTypeahead id="unitmeasure" TItem="ELookUpItem" TValue="ELookUpItem"
                                   SearchMethod="@(filter => lookUpService.GetUnitsOfMeasureAsync(filter).ContinueWith(t => t.Result.AsEnumerable()))"
                                   Value="_selectedUnit" ValueChanged="OnUnitSelected"
                                   ValueExpression="@(() => _selectedUnit)"
                                   Placeholder="Buscar unidad..." TextProperty="Nombre" MaximumSuggestions="5"
                                   class="form-control form-control-sm" style="height: 38px;">
                    <ResultTemplate Context="item">@item.Nombre</ResultTemplate>
                    <SelectedTemplate Context="item">@item.Nombre</SelectedTemplate>
                </BlazoredTypeahead>
            </div>
            <div class="col-sm-2">
                <label for="type">Tipo</label>

                <InputSelect id="type" class="form-select form-control-sm" style="height: 38px;" @bind-Value="SearchParams.ProductType">
                    <option value="">Tipo</option>
                    <option value="1">Implantable</option>
                    <option value="2">Instrumental</option>
                    <option value="3">Inyectable</option>
                </InputSelect>
            </div>
            <div class="col-sm">
                <label for="traceability">División</label>

                <InputSelect id="traceability" class="form-select form-control-sm" style="height: 38px;" @bind-Value="SearchParams.TraceabilityType">
                    <option value="">Trazabilidad</option>
                    <option value="1">No aplica</option>
                    <option value="2">Por cantidad</option>
                    <option value="3">Por lote y vencimiento</option>
                </InputSelect>
            </div>
            <div class="col-sm">
                <div class="form-check form-switch">
                    <input type="checkbox" class="form-check-input me-2" id="plusProcess" @bind="SearchParams.PlusProcess" />
                <label class="form-check-label" for="plusProcess">Esterilizable</label>
                </div>
            </div>
        </div>
        <!-- BOONES DE BUSQUEDA -->
        <div class="mb-3 d-flex justify-content-end gap-2">
            <button class="btn btn-primary rounded-pill" @onclick="Buscar">
                <i class="fas fa-binoculars me-1"></i> Buscar
            </button>
            <button class="btn btn-success rounded-pill" @onclick="NuevoProducto">
                <i class="fas fa-plus me-1"></i> Nuevo
            </button>
            <button class="btn btn-warning rounded-pill" @onclick="ImportarProductos">
                <i class="fas fa-file-upload me-1"></i> Importar
            </button>
            <button class="btn btn-success rounded-pill" @onclick="ExportarExcel">
                <i class="fas fa-file-excel me-1"></i> Excel
            </button>
            <button class="btn btn-secondary rounded-pill" @onclick="Cancelar">
                <i class="fas fa-arrow-left me-1"></i> Volver
            </button>
        </div>
        <hr />
        <div style="zoom:90%;">
            @if (TablaProductos != null && TablaProductos.Any())
            {
                <PhTable Columns="TableColumns"
                         Data="TablaProductos"
                         SelectionField="Id"
                         RowsPerPage="SearchParams.PageSize"
                         RenderButtons="true"
                         Buttons="botones"
                         ShowPageButtons="false"
                         ShowQuickSearch="false"
                         RenderSelect="false" />
            }
            else
            {
                <p>No hay resultados.</p>
            }
        </div>
    </div>

    <div class="card-footer d-flex justify-content-center align-items-end" style="zoom:80%;">
        <div class="d-flex align-items-center gap-3">
            <button class="btn btn-secondary rounded-pill" @onclick="PrimeraPagina" disabled="@(SearchParams.Page == 1)">« Primera</button>
            <button class="btn btn-secondary rounded-pill" @onclick="AnteriorPagina" disabled="@(!PuedeRetroceder)">‹ Anterior</button>
            <span class="mx-2">Página <strong>@SearchParams.Page</strong> de <strong>@TotalPaginas</strong></span>
            <button class="btn btn-secondary rounded-pill" @onclick="SiguientePagina" disabled="@(!PuedeAvanzar)">Siguiente ›</button>
            <button class="btn btn-secondary rounded-pill" @onclick="UltimaPagina" disabled="@(SearchParams.Page == TotalPaginas)">Última »</button>
            <input type="number" class="form-control form-control-sm rounded ms-3" style="width: 80px;" min="1" max="@TotalPaginas" @bind="PaginaDeseada" />
            <button class="btn btn-outline-primary btn-sm rounded-pill ms-2" @onclick="IrAPagina">Ir</button>
        </div>
    </div>
</div>

@code {
    private LSProductSearchParams SearchParams = new() { Page = 1, PageSize = 10 };
    private List<Dictionary<string, object>> TablaProductos = new();
    private PagedResult<ELSProduct>? PagedResult;
    private int PaginaDeseada = 1;
    private ELookUpItem? _selectedDivision;
    private ELookUpItem? _selectedUnit;
    List<PhTable.ButtonOptions> botones = new();

    private List<string> TableColumns = new()
    {
        "Id", "Código Fábrica", "Código Externo", "Código Regulatorio", "Nombre", "Descripción", "División", "Unidad", "Tipo", "Trazabilidad", "Esteriliza"
    };

    protected override async Task OnInitializedAsync()
    {
        botones = new List<PhTable.ButtonOptions>
        {
            new PhTable.ButtonOptions
            {
                Caption =  "<i class='fas fa-pen'></i>",
                ElementClass = "btn btn-success btn-sm",
                UrlAction = "/stock/productform/",
                OnClickAction = async (id) =>
                {
                    if (int.TryParse(id, out var pid))
                        Navigation.NavigateTo($"/stock/productform/{pid}");
                }
            }
        };
    }

    private async Task Buscar()
    {
        SearchParams.PageSize = 13;
        SearchParams.Page = 1;
        await CargarPaginaActual();
    }

    private async Task CargarPaginaActual()
    {
        SearchParams.DivisionId = _selectedDivision?.Id;
        SearchParams.UnitId = _selectedUnit?.Id;
        PagedResult = await productService.SearchAsync(SearchParams);
        TablaProductos = PagedResult?.Items.Select(p => new Dictionary<string, object>
        {
            { "Id", p.Id },
            { "Código Fábrica", p.FactoryCode },
            { "Código Externo", p.ExternalCode?? string.Empty },
            { "Código Regulatorio", p.RegulatoryCode?? string.Empty },
            { "Nombre", p.Name?? string.Empty },
            { "Descripción", p.Descripcion },
            { "División", p.Division?.Name ?? "" },
            { "Unidad", p.Unit?.Name ?? "" },
            { "Tipo", ObtenerTipoProducto(p.ProductType) },
            { "Trazabilidad", ObtenerTipoTrazabilidad(p.TraceabilityType) },
            { "Esteriliza", p.PlusProcess ? "Sí" : "No" }
        }).ToList() ?? [];
    }

    private void OnDivisionSelected(ELookUpItem item) => _selectedDivision = item;
    private void OnUnitSelected(ELookUpItem item) => _selectedUnit = item;

    private string ObtenerTipoProducto(int? tipo) => tipo switch
    {
        1 => "Implantable",
        2 => "Instrumental",
        3 => "Inyectable",
        _ => ""
    };

    private string ObtenerTipoTrazabilidad(int? tipo) => tipo switch
    {
        1 => "No aplica",
        2 => "Por cantidad",
        3 => "Por lote/vencimiento",
        _ => ""
    };

    private async Task PrimeraPagina() { SearchParams.Page = 1; await CargarPaginaActual(); }
    private async Task UltimaPagina() { SearchParams.Page = TotalPaginas; await CargarPaginaActual(); }
    private async Task SiguientePagina() => await CambiarPagina(1);
    private async Task AnteriorPagina() => await CambiarPagina(-1);
    private async Task CambiarPagina(int delta)
    {
        var nueva = SearchParams.Page + delta;
        if (nueva >= 1 && nueva <= TotalPaginas)
        {
            SearchParams.Page = nueva;
            await CargarPaginaActual();
        }
    }

    private async Task IrAPagina()
    {
        if (PaginaDeseada >= 1 && PaginaDeseada <= TotalPaginas)
        {
            SearchParams.Page = PaginaDeseada;
            await CargarPaginaActual();
        }
        else
        {
            toastService.ShowWarning("Página fuera de rango.");
        }
    }

    private async Task ExportarExcel()
    {
        SearchParams.Page = 1;
        SearchParams.PageSize = int.MaxValue; // Exportar todos los resultados
        try
        {
            await productService.ExportFilteredAsync(SearchParams);
            toastService.ShowSuccess("Exportación completada.");
        }
        catch (Exception ex)
        {
            toastService.ShowError($"Error: {ex.Message}");
        }
    }

    private void NuevoProducto() => Navigation.NavigateTo("/stock/productform");

    private void ImportarProductos() => Navigation.NavigateTo("/stock/productimport");

    private void Cancelar() => Navigation.NavigateTo("/DashboardPanel");

    private int TotalPaginas => PagedResult is null ? 1 : (int)Math.Ceiling(PagedResult.TotalItems / (double)SearchParams.PageSize);
    private bool PuedeRetroceder => SearchParams.Page > 1;
    private bool PuedeAvanzar => PagedResult != null && SearchParams.Page < TotalPaginas;
}
