@page "/ListadoPersonas"
@using System.Net.Http.Headers
@using System.Linq.Expressions
@using Newtonsoft.Json
@using System.Text
@using Serialize.Linq.Serializers
@using RegistroPersonalAN.Models
@using BlazorBootstrap
@using bdAntifraude.db
@using Microsoft.AspNetCore.Components

@rendermode InteractiveServer
@inject IJSRuntime JS
@inject NavigationManager NavigationManager
@inject IHttpClientFactory HttpClientFactory
@inject IHttpContextAccessor HttpContextAccessor
@inject UserState UserState

<div class="pagina">
    <div class="Cabecera">
        <h6><small><i class="fas fa-user"></i><b> Personas</b></small></h6>
    </div>

    @if (personas == null)
    {
        <div id="cargando" class="loadingFrame">
            <div class="loadingImg"></div>
        </div>
    }
    else if (!personas.Any())
    {
        <p>No se encontraron datos para mostrar.</p>
    }
    else
    {
        <div class="botonera col-12 gap-1" style="display:flex;" role="group">
            <button type="button" class="btnOAAFBlack" id="btnNuevaPers" title="Añadir nueva persona" @onclick="NuevaPersona">
                <i class="fa-solid fa-user-plus"></i>
            </button>
            <button type="button" class="btnOAAFBlack" @onclick="btnExportarExcel" id="btnExportarExcel" title="Exportar excel">
                <i class="fa-solid fa-file-export"></i>
            </button>
            <!-- Botón "Ver Todos" con toggle: se asigna btnOAAFAzul cuando está activo -->
            <button type="button" id="btnVerTodos" @onclick="ToggleVerTodos" title="alternar entre ver personas activas y todas" class="@(verTodosActive ? "btnOAAFAzul" : "btnOAAFBlack")">
                <i class="fa-solid fa-eye"></i> Ver Todos
            </button>
            <button type="button" class="btnOAAFBlack" title="listado de personas que cumplen trienio" id="btnCumplimientoTrienios" onclick="window.location.href='/cumplimientoTrienios'">
                <i class="fa-solid fa-hourglass-end"></i> Cumplimiento Trienios
            </button>
        </div>
        <div style="display:flex; justify-content:start; gap:15px;width:100%"></div>
        <div class="form-group mt-4 mb-4">
            <input class="form-control" type="text" placeholder="Filtrar..."
                   @bind-value="Filter" @bind-value:event="oninput" />
        </div>

        <!-- Grid con paginación manual: se muestran los datos de la página actual -->
        <div style="overflow-x:auto;" class="tablaDesk">
            <Grid TItem="bdAntifraude.vistas.VePersonas"
                  Class="table tablaRegPers"
                  Data="@listPersonasPaginada"
                  AllowFiltering="false"
                  AllowPaging="false"
                  AllowSorting="true"
                  EmptyText="No se han encontrado datos"
                  Height="80"
                  PageSizeSelectorVisible="false"
                  Responsive="true"
                  PaginationItemsTextFormat="{0} - {1} de {2} elementos">
                <GridColumns>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="NIF" PropertyName="NIF" FilterButtonCSSClass="hidden" SortKeySelector="item => item.NIF">
                        <NavLink class="btn btn-link" href="@HashRed(context.NIF)">@context.NIF</NavLink>
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Apellidos" PropertyName="Apellidos" TextNoWrap="true" FilterButtonCSSClass="hidden" SortKeySelector="item => item.Apellidos">
                        @context.Apellidos
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Nombre" PropertyName="Nombre" FilterButtonCSSClass="hidden" SortKeySelector="item => item.Nombre">
                        @FormatearNombre(context.Nombre)
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Correo electrónico" PropertyName="CorreoElectronico" TextNoWrap="true" FilterButtonCSSClass="hidden" SortKeySelector="item => item.CorreoElectronico">
                        @context.CorreoElectronico
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Cuerpo" PropertyName="Cuerpo" FilterButtonCSSClass="hidden" SortKeySelector="item => item.Cuerpo">
                        @context.Cuerpo
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Nivel Puesto" PropertyName="NivelPuestoActual" FilterButtonCSSClass="hidden" SortKeySelector="item => item.NivelPuestoActual">
                        @context.NivelPuestoActual
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Caracter ocupación" PropertyName="CargoOcupadoActual" FilterButtonCSSClass="hidden" SortKeySelector="item => item.CargoOcupadoActual">
                        @context.CargoOcupadoActual
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Departamento" PropertyName="departamento" FilterButtonCSSClass="hidden" SortKeySelector="item => item.departamento">
                        @context.departamento
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Puesto actual" PropertyName="PuestoActual" FilterButtonCSSClass="hidden" SortKeySelector="item => item.PuestoActual">
                        @context.PuestoActual
                    </GridColumn>
                    <GridColumn TItem="bdAntifraude.vistas.VePersonas" HeaderText="Situación" PropertyName="LiteralSituacion" FilterButtonCSSClass="hidden">
                        @context.LiteralSituacion
                    </GridColumn>
                </GridColumns>
            </Grid>
        </div>

        <!-- Vista móvil -->
        <div class="tablaMov">
            @foreach (var itm in listPersonasPaginada)
            {
                var collapseId = $"collapse{itm.IdPersona}";
                <div class="card collapse-card Aceptada">
                    <div class="card-header mb-1" data-bs-toggle="collapse" data-bs-target="#@collapseId" aria-expanded="false" aria-controls="@collapseId">
                        <h5 class="mb-0">@itm.NIF - @itm.ApellidosNombre</h5>
                    </div>
                    <div id="@collapseId" class="collapse">
                        <div class="card-body">
                            <dl class="row">
                                <dt class="col-sm-3">NIF</dt>
                                <dd class="col-sm-9"><a href="@HashRed(itm.NIF)">@itm.NIF</a></dd>
                                <dt class="col-sm-3">Apellidos</dt>
                                <dd class="col-sm-9">@itm.Apellidos</dd>
                                <dt class="col-sm-3">Nombre</dt>
                                <dd class="col-sm-9">@FormatearNombre(itm.Nombre)</dd>
                                <dt class="col-sm-3">Correo electrónico</dt>
                                <dd class="col-sm-9">@itm.CorreoElectronico</dd>
                                <dt class="col-sm-3">Cuerpo</dt>
                                <dd class="col-sm-9">@itm.Cuerpo</dd>
                                <dt class="col-sm-3">Nivel puesto</dt>
                                <dd class="col-sm-9">@itm.NivelPuestoActual</dd>
                                <dt class="col-sm-3">Caracter ocupación</dt>
                                <dd class="col-sm-9">@itm.CargoOcupadoActual</dd>
                                <dt class="col-sm-3">Departamento</dt>
                                <dd class="col-sm-9">@itm.departamento</dd>
                                <dt class="col-sm-3">Puesto actual</dt>
                                <dd class="col-sm-9">@itm.PuestoActual</dd>
                                <dt class="col-sm-3">Situación</dt>
                                <dd class="col-sm-9">@itm.LiteralSituacion</dd>
                            </dl>
                        </div>
                    </div>
                </div>
            }
        </div>

        <!-- Controles de paginación + texto de elementos en la misma fila -->
        <div class="d-flex justify-content-between mt-2 align-items-center">
            <!-- Paginación a la izquierda -->
            <div class="custom-pagination">
                <ul>
                    <!-- Botón para ir a la primera página -->
                    <li>
                        <button class="page-button page-link"
                                @onclick="PrimeraPagina"
                                disabled="@(UserState.CurrentPage == 1)">
                            <i id="AR1LR16N3BVAJ" class="bi bi-chevron-double-left"></i>
                        </button>
                    </li>
                    <!-- Botón para ir a la página anterior -->
                    <li>
                        <button class="page-button page-link"
                                @onclick="PaginaAnterior"
                                disabled="@(UserState.CurrentPage == 1)">
                            <i id="AR1LR16N3BVAK" class="bi bi-chevron-left"></i>
                        </button>
                    </li>

                    <!-- Si el primer número a mostrar es mayor que 1, se muestra "1" y puntos -->
                    @if (PageNumbersToDisplay().Any() && PageNumbersToDisplay().First() > 1)
                    {
                        <li>
                            <button class="page-button" @onclick="() => UserState.CurrentPage = 1">
                                1
                            </button>
                        </li>
                        <li><span class="ellipsis">...</span></li>
                    }

                    <!-- Botones de página dinámica -->
                    @foreach (var pageNum in PageNumbersToDisplay())
                    {
                        <li>
                            <button class="page-button page-link @(pageNum == UserState.CurrentPage ? "active" : null)"
                                    @onclick="() => UserState.CurrentPage = pageNum">
                                @pageNum
                            </button>
                        </li>
                    }

                    <!-- Si el último número mostrado es menor que TotalPaginas, se muestran puntos y la última página -->
                    @if (PageNumbersToDisplay().Any() && PageNumbersToDisplay().Last() < TotalPaginas)
                    {
                        <li><button class="page-button page-link" disabled>...</button></li>
                        <li>
                            <button class="page-button" @onclick="() => UserState.CurrentPage = TotalPaginas">
                                @TotalPaginas
                            </button>
                        </li>
                    }

                    <!-- Botón para ir a la página siguiente -->
                    <li>
                        <button class="page-button page-link"
                                @onclick="PaginaSiguiente"
                                disabled="@(UserState.CurrentPage == TotalPaginas)">
                            <i id="AR1LR16N3BVAM" class="bi bi-chevron-right"></i>
                        </button>
                    </li>
                    <!-- Botón para ir a la última página -->
                    <li>
                        <button class="page-button page-link"
                                @onclick="UltimaPagina"
                                disabled="@(UserState.CurrentPage == TotalPaginas)">
                            <i id="AR1LR16N3BVAN" class="bi bi-chevron-double-right"></i>
                        </button>
                    </li>
                </ul>
            </div>

            <!-- Texto de elementos a la derecha -->
            <div style="margin-right: 20px;">
                @FromElement - @ToElement de @listPersonas.Count elementos
            </div>
        </div>
    }
</div>

@code {
    private List<bdAntifraude.vistas.VePersonas> listPersonas = new List<bdAntifraude.vistas.VePersonas>();
    private List<bdAntifraude.vistas.VePersonas> personas = new List<bdAntifraude.vistas.VePersonas>();
    private string _filter = "";
    public string Filter
    {
        get => _filter;
        set
        {
            if (_filter != value)
            {
                _filter = value;
                AplicarFiltros();
            }
        }
    }

    // Tamaño de página
    private int pageSize = 6;

    // Calcula el total de páginas basado en la lista filtrada
    private int TotalPaginas => (int)Math.Ceiling((double)listPersonas.Count / pageSize);
    // Índice inicial y final de elementos para la página actual
    private int FromElement => listPersonas.Count == 0 ? 0 : (UserState.CurrentPage - 1) * pageSize + 1;
    private int ToElement
    {
        get
        {
            if (listPersonas.Count == 0)
            {
                return 0;
            }
            int last = FromElement + pageSize - 1;
            return last > listPersonas.Count ? listPersonas.Count : last;
        }
    }
    // Sublista de datos para la página actual basada en la lista filtrada
    private List<bdAntifraude.vistas.VePersonas> listPersonasPaginada =>
        listPersonas.Skip((UserState.CurrentPage - 1) * pageSize).Take(pageSize).ToList();
    private void PaginaAnterior()
    {
        if (UserState.CurrentPage > 1)
        {
            UserState.CurrentPage--;
        }
    }
    private void PaginaSiguiente()
    {
        if (UserState.CurrentPage < TotalPaginas)
        {
            UserState.CurrentPage++;
        }
    }
    private void PrimeraPagina() => UserState.CurrentPage = 1;
    private void UltimaPagina() => UserState.CurrentPage = TotalPaginas;
    private void NuevaPersona()
    {
        NavigationManager.NavigateTo("/InfoPersonas", forceLoad: true);
    }
    private string HashRed(string id)
    {
        string link = "/infoPersonas?cl=" + tsUtilidades.crypt.FEncS(
            id,
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*",
            875421649);
        return link;
    }
    // Bandera que indica si se está en modo "Ver Todos"
    private bool verTodosActive = false;
    /// <summary>
    /// Método toggle que cambia entre mostrar todos los registros y solo activos.
    /// </summary>
    private async Task ToggleVerTodos()
    {
        if (!verTodosActive)
        {
            verTodosActive = true;
            var token = UserState.Token;
            var client = HttpClientFactory.CreateClient();
            client.BaseAddress = new Uri(Utilidades.urlSwagger());
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var resultPersonas = await client.GetAsync("/api/vePersonas?activos=false");
            var resultContent = await resultPersonas.Content.ReadAsStringAsync();
            personas = JsonConvert.DeserializeObject<List<bdAntifraude.vistas.VePersonas>>(resultContent)
                       ?? new List<bdAntifraude.vistas.VePersonas>();
        }
        else
        {
            verTodosActive = false;
            var token = UserState.Token;
            var client = HttpClientFactory.CreateClient();
            client.BaseAddress = new Uri(Utilidades.urlSwagger());
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var resultPersonas = await client.GetAsync("/api/vePersonas?activos=true");
            var resultContent = await resultPersonas.Content.ReadAsStringAsync();
            personas = JsonConvert.DeserializeObject<List<bdAntifraude.vistas.VePersonas>>(resultContent)
                       ?? new List<bdAntifraude.vistas.VePersonas>();
        }

        personas = personas
            .OrderBy(x => x.Apellidos)
            .ThenBy(x => x.Nombre)
            .ThenByDescending(x => x.FechaAltaPAR)
            .ToList();

        listPersonas = personas;
        UserState.CurrentPage = 1;
        Filter = "";
    }
    private void AplicarFiltros()
    {
        listPersonas = personas.Where(per =>
            string.IsNullOrEmpty(Filter) ||
            Utilidades.RemoveDiacritics(per.NIF).Contains(Utilidades.RemoveDiacritics(Filter), StringComparison.OrdinalIgnoreCase) ||
            Utilidades.RemoveDiacritics(per.Apellidos).Contains(Utilidades.RemoveDiacritics(Filter), StringComparison.OrdinalIgnoreCase) ||
            Utilidades.RemoveDiacritics(per.Nombre).Contains(Utilidades.RemoveDiacritics(Filter), StringComparison.OrdinalIgnoreCase)
        ).ToList();
        UserState.CurrentPage = 1;
    }
    /// <summary>
    /// Retorna un subconjunto de páginas alrededor de la página actual (±2 páginas).
    /// </summary>
    private IEnumerable<int> PageNumbersToDisplay()
    {
        int range = 2;
        int startPage = Math.Max(1, UserState.CurrentPage - range);
        int endPage = Math.Min(TotalPaginas, UserState.CurrentPage + range);

        for (int i = startPage; i <= endPage; i++)
        {
            yield return i;
        }
    }
    /// <summary>
    /// Formatea el nombre de la persona insertando un salto de línea después de la segunda palabra.
    /// </summary>
    /// <param name="nombre">Nombre a formatear</param>
    /// <returns>MarkupString con el nombre formateado</returns>
    private MarkupString FormatearNombre(string nombre)
    {
        if (string.IsNullOrEmpty(nombre))
        {
            return new MarkupString(string.Empty);
        }
        var palabras = nombre.Split(' ');
        if (palabras.Length > 2)
        {
            string primeraParte = string.Join(" ", palabras.Take(2));
            string resto = string.Join(" ", palabras.Skip(2));
            return new MarkupString($"{primeraParte}<br/>{resto}");
        }
        return new MarkupString(nombre);
    }
    protected override async Task OnInitializedAsync()
    {
        verTodosActive = false;
        var token = UserState.Token;
        var client = HttpClientFactory.CreateClient();
        client.BaseAddress = new Uri(Utilidades.urlSwagger());
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var resultPersonas = await client.GetAsync("/api/vePersonas?activos=true");
        var resultContent = await resultPersonas.Content.ReadAsStringAsync();
        personas = JsonConvert.DeserializeObject<List<bdAntifraude.vistas.VePersonas>>(resultContent)
                   ?? new List<bdAntifraude.vistas.VePersonas>();

        personas = personas
            .OrderBy(x => x.Apellidos)
            .ThenBy(x => x.Nombre)
            .ThenByDescending(x => x.FechaAltaPAR)
            .ToList();

        listPersonas = personas;
    }
    private async Task btnExportarPDF()
    {
        var itm = listPersonas
      .Select(f => new
      {
          NIF = f.NIF,
          Apellidos = f.Apellidos,
          Nombre = f.Nombre,
          Correo_Electrónico = f.CorreoElectronico,
          Cuerpo = f.Cuerpo,
          Nivel_Puesto = f.NivelPuestoActual,
          Caracter_Ocupación = f.CargoOcupadoActual,
         Departamento = f.departamento,
         Puesto_Actual = f.PuestoActual,
         Situación = f.LiteralSituacion
         
      })
      .ToList();
        var logoBytes = await File.ReadAllBytesAsync("wwwroot/Content/imagenes/1oaaflogo.png");

        // Color de cabecera para PDF
        var pdfHeaderColor = new MigraDocCore.DocumentObjectModel.Color(0, 85, 135);

        await Utilidades.ExportarPdfEnBrowser(
            JS,
            itm,
            logoBytes,
            pdfHeaderColor,
        $"Personas.pdf");
    }
    private async Task btnExportarExcel()
    {
        var itm = listPersonas
     .Select(f => new
     {
         NIF = f.NIF,
         Apellidos = f.Apellidos,
         Nombre = f.Nombre,
         Correo_Electrónico = f.CorreoElectronico,
         Cuerpo = f.Cuerpo,
         Nivel_Puesto = f.NivelPuestoActual,
         Caracter_Ocupación = f.CargoOcupadoActual,
         Departamento = f.departamento,
         Puesto_Actual = f.PuestoActual,
         Situación = f.LiteralSituacion

     })
     .ToList();
        // 2) Carga tu logo (por ejemplo desde wwwroot/images/logo.png)
        var logoBytes = await File.ReadAllBytesAsync("wwwroot/Content/imagenes/1oaaflogo.png");

        // 3) Define el color de cabecera para Excel
        var excelHeaderColor = ClosedXML.Excel.XLColor.FromArgb(0, 85, 135);

        // 4) Llama a tu helper pasando logo y color
        await Utilidades.ExportarExcelEnBrowser(
            JS,
            itm,
            logoBytes,
            excelHeaderColor,
            $"Personas.xlsx");

        // await Utilidades.ExportarExcelEnBrowser(JS, itm, $"Puestos_{Persona.APELLIDOS}_{Persona.NOMBRE}.xlsx");

    }
}

@* Helper para descargar archivos desde base64 *@
<script>
    window.saveAsFile = (filename, bytesBase64) => {
        const link = document.createElement('a');
        link.download = filename;
        link.href = 'data:application/octet-stream;base64,' + bytesBase64;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    };
</script>