@page "/salesdocuments"
@using Domain.Constants
@using Domain.Dtos.Sales
@using Domain.Generics
@using phronCare.UIBlazor.Services.Sales.SalesDocuments
@inject NavigationManager Navigation
@inject ISalesDocumentService SalesDocumentService
@inject IToastService toastService

<div class="card shadow-sm mb-3" style="zoom: 0.8;">
    <div class="card-header py-2">
        <div class="d-flex justify-content-center align-items-center">
            <h3 class="card-title m-0">Consulta de Sales Documents</h3>
        </div>
    </div>
    <div class="card-body pt-2 pb-0">
        <div class="mb-3 row g-2 align-items-end">
            <div class="col-sm">
                <label for="customer">Cliente</label>
                <input id="customer" @bind="Filters.CustomerText" class="form-control form-control-sm" placeholder="Nombre o código" />
            </div>
            <div class="col-sm">
                <label for="quoteId">Presupuesto ID</label>
                <InputNumber id="quoteId" @bind-Value="Filters.QuoteId" class="form-control form-control-sm" />
            </div>
            <div class="col-sm">
                <label for="documentType">Tipo</label>
                <select id="documentType" @bind="Filters.DocumentType" class="form-select form-select-sm">
                    <option value="">— Todos —</option>
                    @foreach (var item in DocumentTypeOptions)
                    {
                        <option value="@item.Value">@item.Label</option>
                    }
                </select>
            </div>
            <div class="col-sm">
                <label for="status">Estado</label>
                <select id="status" @bind="Filters.Status" class="form-select form-select-sm">
                    <option value="">— Todos —</option>
                    @foreach (var item in StatusOptions)
                    {
                        <option value="@item.Value">@item.Label</option>
                    }
                </select>
            </div>
            <div class="col-sm">
                <label for="datefrom">Desde</label>
                <InputDate id="datefrom" @bind-Value="Filters.IssueDateFrom" class="form-control form-control-sm" />
            </div>
            <div class="col-sm">
                <label for="dateto">Hasta</label>
                <InputDate id="dateto" @bind-Value="Filters.IssueDateTo" class="form-control form-control-sm" />
            </div>
            <div class="d-flex justify-content-end gap-2 mt-3">
                <button class="btn btn-primary rounded-pill" @onclick="Search">
                    <i class="fas fa-binoculars me-1"></i> Buscar
                </button>
                <button class="btn btn-secondary rounded-pill ms-1" @onclick="OnClear">
                    <i class="fas fa-eraser me-1"></i> Limpiar
                </button>
                <button class="btn btn-success rounded-pill" @onclick="Create">
                    <i class="fas fa-plus me-1"></i> Nuevo
                </button>
            </div>
        </div>
    </div>
</div>

<div class="card shadow-sm" style="zoom:0.8;">
    <div class="table-responsive" style="zoom:0.8;">
        <table class="table table-sm align-middle mb-0">
            <thead class="table-light">
                <tr>
                    <th>Documento</th>
                    <th>Emisión</th>
                    <th>Cliente</th>
                    <th>Facturar a</th>
                    <th>Presupuesto</th>
                    <th>Tipo</th>
                    <th>Estado</th>
                    <th>Moneda</th>
                    <th>Total</th>
                    <th style="width:80px;">Acciones</th>
                </tr>
            </thead>
            <tbody>
                @if (PagedSalesDocuments?.Items?.Any() == true)
                {
                    @foreach (var document in PagedSalesDocuments.Items)
                    {
                        <tr class="text-center">
                            <td>@(string.IsNullOrWhiteSpace(document.InternalDocumentNumber) ? $"#{document.Id}" : document.InternalDocumentNumber)</td>
                            <td>@FormatDate(document.IssueDate)</td>
                            <td>@document.CustomerName</td>
                            <td>@document.BillToCustomerName</td>
                            <td>@(document.QuoteId?.ToString() ?? "—")</td>
                            <td>@GetDocumentTypeLabel(document.DocumentType)</td>
                            <td><span class="badge @GetStatusBadge(document.Status)">@GetStatusLabel(document.Status)</span></td>
                            <td>@document.Currency</td>
                            <td>@document.TotalAmount.ToString("N2")</td>
                            <td class="text-center align-middle">
                                <button class="btn btn-link btn-lg p-0 text-primary ms-2" title="Ver detalle" @onclick="() => Detail(document.Id)"><i class="fas fa-eye"></i></button>
                                @if (document.Status == (int)SalesDocumentStatus.Draft)
                                {
                                    <button class="btn btn-link btn-lg p-0 text-success ms-2" title="Revisar draft" @onclick="() => Review(document.Id)"><i class="fas fa-clipboard-check"></i></button>
                                }
                            </td>
                        </tr>
                    }
                }
                else if (IsLoading)
                {
                    <tr><td colspan="10" class="text-center text-muted py-4">Cargando...</td></tr>
                }
                else
                {
                    <tr><td colspan="10" class="text-center text-muted py-4">Sin resultados</td></tr>
                }
            </tbody>
        </table>
    </div>
    <div class="d-flex justify-content-center align-items-center px-3 py-2 border-top">
        <div class="btn-group justify-content-center">
            <button class="btn btn-outline-secondary btn-sm rounded-pill" @onclick="PrimeraPagina" disabled="@(Filters.Page == 1)">Primera</button>
            <button class="btn btn-outline-secondary btn-sm rounded-pill" @onclick="AnteriorPagina" disabled="@(!PuedeRetroceder)">Anterior</button>
            <span class="mx-2">Página <strong>@Filters.Page</strong> de <strong>@TotalPaginas</strong></span>
            <button class="btn btn-outline-secondary btn-sm rounded-pill" @onclick="SiguientePagina" disabled="@(!PuedeAvanzar)">Siguiente</button>
            <button class="btn btn-outline-secondary btn-sm rounded-pill" @onclick="UltimaPagina" disabled="@(Filters.Page == TotalPaginas)">Última</button>
            <div class="d-flex align-items-center ms-3">
                <input type="number" class="form-control form-control-sm rounded" style="width: 80px;" min="1" max="@TotalPaginas" @bind="PaginaDeseada" />
            </div>
            <button class="btn btn-outline-secondary btn-sm rounded-pill" @onclick="IrAPagina">
                <i class="fas fa-arrow-right-to-bracket me-1"></i> Ir
            </button>
        </div>
    </div>
</div>

@code {
    private SalesDocumentSearchParams Filters = new() { PageSize = 10 };
    private PagedResult<SalesDocumentSummaryDto>? PagedSalesDocuments;
    private bool IsLoading;
    private int PaginaDeseada = 1;

    private static readonly List<SelectOption> DocumentTypeOptions = Enum.GetValues<SalesDocumentType>()
        .Select(x => new SelectOption((int)x, GetDocumentTypeLabel((int)x)))
        .ToList();

    private static readonly List<SelectOption> StatusOptions = Enum.GetValues<SalesDocumentStatus>()
        .Select(x => new SelectOption((int)x, GetStatusLabel((int)x)))
        .ToList();

    protected override async Task OnInitializedAsync()
    {
        await Search();
    }

    private async Task Search()
    {
        try
        {
            IsLoading = true;
            PagedSalesDocuments = await SalesDocumentService.SearchAsync(Filters);
            PaginaDeseada = Filters.Page;
        }
        catch (Exception ex)
        {
            toastService.ShowError(ex.Message);
        }
        finally
        {
            IsLoading = false;
        }
    }

    private async Task PrimeraPagina() { Filters.Page = 1; await Search(); }
    private async Task UltimaPagina() { Filters.Page = TotalPaginas; await Search(); }
    private async Task SiguientePagina() => await CambiarPagina(1);
    private async Task AnteriorPagina() => await CambiarPagina(-1);

    private async Task CambiarPagina(int delta)
    {
        var nuevaPagina = Filters.Page + delta;
        if (nuevaPagina >= 1 && nuevaPagina <= TotalPaginas)
        {
            Filters.Page = nuevaPagina;
            await Search();
        }
    }

    private async Task IrAPagina()
    {
        if (PaginaDeseada >= 1 && PaginaDeseada <= TotalPaginas)
        {
            Filters.Page = PaginaDeseada;
            await Search();
        }
        else
        {
            toastService.ShowWarning("Número de página fuera de rango.");
        }
    }

    private bool PuedeRetroceder => PagedSalesDocuments != null && Filters.Page > 1;
    private bool PuedeAvanzar => PagedSalesDocuments != null && Filters.Page < TotalPaginas;
    private int TotalPaginas => PagedSalesDocuments is null ? 1 : Math.Max(1, PagedSalesDocuments.TotalPages);

    private void Create() => Navigation.NavigateTo("/salesdocuments/create");
    private void Detail(int id) => Navigation.NavigateTo($"/salesdocuments/{id}");
    private void Review(int id) => Navigation.NavigateTo($"/salesdocuments/{id}/review");

    private void OnClear()
    {
        Filters = new SalesDocumentSearchParams { PageSize = 10 };
        PagedSalesDocuments = null;
        PaginaDeseada = 1;
    }

    private static string FormatDate(DateTime? value) => value.HasValue ? value.Value.ToString("dd/MM/yyyy") : "—";

    private static string GetDocumentTypeLabel(int value) => Enum.IsDefined(typeof(SalesDocumentType), value)
        ? ((SalesDocumentType)value) switch
        {
            SalesDocumentType.Invoice => "Factura",
            SalesDocumentType.DebitNote => "Nota de débito",
            SalesDocumentType.CreditNote => "Nota de crédito",
            SalesDocumentType.CreditInvoice => "Factura crédito",
            SalesDocumentType.CreditDebitNote => "N/D crédito",
            SalesDocumentType.CreditCreditNote => "N/C crédito",
            _ => value.ToString()
        }
        : value.ToString();

    private static string GetStatusLabel(int value) => Enum.IsDefined(typeof(SalesDocumentStatus), value)
        ? ((SalesDocumentStatus)value) switch
        {
            SalesDocumentStatus.Draft => "Borrador",
            SalesDocumentStatus.Validated => "Validado",
            SalesDocumentStatus.Issued => "Emitido",
            SalesDocumentStatus.Cancelled => "Anulado",
            _ => value.ToString()
        }
        : value.ToString();

    private static string GetStatusBadge(int value) => value switch
    {
        (int)SalesDocumentStatus.Draft => "bg-secondary text-white",
        (int)SalesDocumentStatus.Validated => "bg-info text-dark",
        (int)SalesDocumentStatus.Issued => "bg-primary text-white",
        (int)SalesDocumentStatus.Cancelled => "bg-danger text-white",
        _ => "bg-light text-dark"
    };

    private sealed record SelectOption(int Value, string Label);
}
