@page "/GestionZip"
@rendermode InteractiveServer
@using Microsoft.AspNetCore.Components.Forms
@using GestionaDenunciasAN.Models
@using System.Globalization
@inject IHostEnvironment HostEnvironment
@inject IJSRuntime JSRuntime

<PageTitle>Gestión de ZIP</PageTitle>

<h3>Gestión de ZIP</h3>

@if (string.IsNullOrEmpty(zipsPath))
{
    <div class="alert alert-danger">
        La ruta para guardar los ZIP no se encuentra.
    </div>
}
else
{
    <button class="btn btn-primary mb-3" @onclick="TriggerFileInput">Subir nuevo ZIP</button>
    <InputFile id="hiddenFileInput" style="display:none;" OnChange="HandleFileSelected" multiple accept=".zip" />

    @if (!string.IsNullOrEmpty(uploadMessage))
    {
        <div class="alert alert-info">@uploadMessage</div>
    }

    <h4>Archivos ZIP existentes:</h4>
    @if (existingZips == null || !existingZips.Any())
    {
        <p>No hay archivos ZIP subidos.</p>
    }
    else
    {
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>Nombre del ZIP</th>
                    <th>Acciones</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var zipFileName in existingZips)
                {
                    <tr>
                        <td>@zipFileName</td>
                        <td>
                            <button class="btn btn-danger btn-sm" @onclick="() => DeleteZip(zipFileName)">Eliminar</button>
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    }
}

@code {
    private string zipsPath;
    private List<string> existingZips = new();
    private string uploadMessage;
    private const string FIXED_PATH = @"C:\ZipsDenuncias";
    private const string DENUNCIAS_JSON = @"C:\ZipsDenuncias\denuncias.json";
    private const string FICHEROS_JSON = @"C:\ZipsDenuncias\ficheros.json";

    protected override void OnInitialized()
    {
        if (Directory.Exists(FIXED_PATH))
        {
            zipsPath = FIXED_PATH;
        }
        else
        {
            zipsPath = string.Empty;
            uploadMessage = "La ruta para guardar los ZIP no se encuentra.";
        }
        if (!string.IsNullOrEmpty(zipsPath))
        {
            LoadExistingZips();
        }
    }

    private async Task TriggerFileInput()
    {
        await JSRuntime.InvokeVoidAsync("triggerFileInput", "hiddenFileInput");
    }

    private async Task HandleFileSelected(InputFileChangeEventArgs e)
    {
        if (string.IsNullOrEmpty(zipsPath))
        {
            uploadMessage = "No se pudo subir porque la ruta no se encuentra.";
            return;
        }
        try
        {
            int count = 0;
            foreach (var file in e.GetMultipleFiles())
            {
                var fileName = file.Name;
                var finalPath = Path.Combine(zipsPath, fileName);
                using var stream = file.OpenReadStream(long.MaxValue);
                using var fs = new FileStream(finalPath, FileMode.Create);
                await stream.CopyToAsync(fs);
                count++;
            }
            uploadMessage = $"{count} archivo(s) ZIP subido(s) correctamente.";
            LoadExistingZips();
            await ActualizarJsonConZipsAsync();
        }
        catch (Exception ex)
        {
            uploadMessage = $"Error al subir: {ex.Message}";
        }
    }

    private void LoadExistingZips()
    {
        existingZips = Directory.GetFiles(zipsPath, "*.zip")
                            .Select(Path.GetFileName)
                            .ToList();
    }

    private void DeleteZip(string fileName)
    {
        var fullPath = Path.Combine(zipsPath, fileName);
        if (File.Exists(fullPath))
        {
            File.Delete(fullPath);
        }
        LoadExistingZips();
    }

    // Procesa cada ZIP: extrae report.txt y ficheros adjuntos; actualiza o añade registros en los JSON.
    private async Task ActualizarJsonConZipsAsync()
    {
        var registros = new List<DenunciasGestiona>();
        var ficheros = new List<FicherosDenuncias>();

        var zipFiles = Directory.GetFiles(zipsPath, "*.zip");
        foreach (var zipFile in zipFiles)
        {
            var folderName = Path.GetFileNameWithoutExtension(zipFile);
            var extractPath = Path.Combine(zipsPath, folderName);
            if (!Directory.Exists(extractPath))
                Directory.CreateDirectory(extractPath);

            // Extraemos el ZIP (sobrescribe si es necesario)
            System.IO.Compression.ZipFile.ExtractToDirectory(zipFile, extractPath, overwriteFiles: true);

            // Procesamos el reporte
            var reportPath = Path.Combine(extractPath, "report.txt");
            if (File.Exists(reportPath))
            {
                var lines = await File.ReadAllLinesAsync(reportPath);
                var denuncia = ParsearReportTxt(lines);
                if (string.IsNullOrEmpty(denuncia.Expediente_Gestiona))
                    denuncia.Expediente_Gestiona = "Pendiente";
                registros.Add(denuncia);

                // Procesamos ficheros adjuntos
                foreach (var subFolder in new[] { "files", "files_attached_from_recipients" })
                {
                    var subPath = Path.Combine(extractPath, subFolder);
                    if (Directory.Exists(subPath))
                    {
                        foreach (var file in Directory.GetFiles(subPath))
                        {
                            var bytes = await File.ReadAllBytesAsync(file);
                            var fichero = new FicherosDenuncias
                                {
                                    Id_Fichero = 0,
                                    Id_Tipo = 1,
                                    Descripcion = null,
                                    Fecha = DateTime.Now,
                                    Observaciones = "",
                                    Id_Denuncia = denuncia.Id_Denuncia,
                                    NombreFichero = Path.GetFileName(file),
                                    Fichero = bytes
                                };
                            ficheros.Add(fichero);
                        }
                    }
                }
            }
        }
        // Actualizamos el JSON de Denuncias
        List<DenunciasGestiona> existentesDenuncias = new List<DenunciasGestiona>();
        if (File.Exists(DENUNCIAS_JSON))
        {
            var json = await File.ReadAllTextAsync(DENUNCIAS_JSON);
            existentesDenuncias = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DenunciasGestiona>>(json) ?? new List<DenunciasGestiona>();
        }
        foreach (var reg in registros)
        {
            var existente = existentesDenuncias.FirstOrDefault(d => d.Id_Denuncia == reg.Id_Denuncia);
            if (existente != null)
            {
                if (existente.Expediente_Gestiona == "Pendiente")
                {
                    existente.Fecha = reg.Fecha;
                    existente.Etiqueta = reg.Etiqueta;
                    existente.Estado = reg.Estado;
                    existente.Tipo_Denuncia = reg.Tipo_Denuncia;
                    existente.Asunto = reg.Asunto;
                    existente.A_Quien_Denuncia = reg.A_Quien_Denuncia;
                    existente.Descripcion_Denuncia = reg.Descripcion_Denuncia;
                    existente.Denunciado_Ante_Inst = reg.Denunciado_Ante_Inst;
                    existente.Lugar_Hechos = reg.Lugar_Hechos;
                    existente.Fecha_Hechos = reg.Fecha_Hechos;
                    existente.Condiciones = reg.Condiciones;
                    existente.Comments = reg.Comments;
                }
            }
            else
            {
                existentesDenuncias.Add(reg);
            }
        }
        var newJsonDenuncias = Newtonsoft.Json.JsonConvert.SerializeObject(existentesDenuncias, Newtonsoft.Json.Formatting.Indented);
        await File.WriteAllTextAsync(DENUNCIAS_JSON, newJsonDenuncias);

        // Actualizamos el JSON de Ficheros
        List<FicherosDenuncias> existentesFicheros = new List<FicherosDenuncias>();
        if (File.Exists(FICHEROS_JSON))
        {
            var jsonF = await File.ReadAllTextAsync(FICHEROS_JSON);
            existentesFicheros = Newtonsoft.Json.JsonConvert.DeserializeObject<List<FicherosDenuncias>>(jsonF) ?? new List<FicherosDenuncias>();
        }
        // Eliminamos los ficheros de denuncia que vamos a actualizar
        foreach (var reg in registros)
        {
            existentesFicheros.RemoveAll(f => f.Id_Denuncia == reg.Id_Denuncia);
        }
        // Añadimos los nuevos ficheros
        existentesFicheros.AddRange(ficheros);
        var newJsonFicheros = Newtonsoft.Json.JsonConvert.SerializeObject(existentesFicheros, Newtonsoft.Json.Formatting.Indented);
        await File.WriteAllTextAsync(FICHEROS_JSON, newJsonFicheros);
    }

    private DenunciasGestiona ParsearReportTxt(string[] lines)
    {
        var denuncia = new DenunciasGestiona();
        bool leyendoComments = false;
        var commentsBuilder = new System.Text.StringBuilder();

        for (int i = 0; i < lines.Length; i++)
        {
            var line = lines[i].Trim();

            // Si se encuentra la marca de comentarios, todo lo siguiente se agrega a Comments
            if (line.StartsWith("Comments", StringComparison.OrdinalIgnoreCase))
            {
                leyendoComments = true;
                continue;
            }
            if (leyendoComments)
            {
                commentsBuilder.AppendLine(line);
                continue;
            }

            // Campos generales
            if (line.StartsWith("ID:", StringComparison.OrdinalIgnoreCase))
            {
                var idStr = line.Substring("ID:".Length).Trim();
                if (int.TryParse(idStr, out int idNum))
                    denuncia.Id_Denuncia = idNum;
            }
            else if (line.StartsWith("Fecha:", StringComparison.OrdinalIgnoreCase))
            {
                var fechaStr = line.Substring("Fecha:".Length).Trim();
                if (fechaStr.EndsWith("(UTC)"))
                    fechaStr = fechaStr.Substring(0, fechaStr.Length - "(UTC)".Length).Trim();
                // Intentamos primero con un formato específico
                string formato = "dddd dd MMMM yyyy HH:mm";
                if (DateTime.TryParseExact(fechaStr, formato, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out DateTime fechaParsed))
                {
                    denuncia.Fecha = fechaParsed;
                }
                else if (DateTime.TryParse(fechaStr, out DateTime fechaParsed2))
                {
                    denuncia.Fecha = fechaParsed2;
                }
                else
                {
                    denuncia.Fecha = DateTime.MinValue;
                }
            }
            else if (line.StartsWith("Etiqueta:", StringComparison.OrdinalIgnoreCase))
            {
                denuncia.Etiqueta = line.Substring("Etiqueta:".Length).Trim();
            }
            else if (line.StartsWith("Estado:", StringComparison.OrdinalIgnoreCase))
            {
                denuncia.Estado = line.Substring("Estado:".Length).Trim();
            }
            else if (line.StartsWith("Expediente_Gestiona:", StringComparison.OrdinalIgnoreCase))
            {
                denuncia.Expediente_Gestiona = line.Substring("Expediente_Gestiona:".Length).Trim();
            }
            else if (line.StartsWith("¿Qué tipo de denuncia desea realizar?", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Tipo_Denuncia = lines[i + 1].Trim();
            }
            // Sección "Datos de contacto"
            else if (line.Equals("Nombre", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Nombre = lines[i + 1].Trim();
            }
            else if (line.Equals("Apellidos", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Apellidos = lines[i + 1].Trim();
            }
            else if (line.Equals("Sexo", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Sexo = lines[i + 1].Trim();
            }
            else if (line.Equals("DNI", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Dni = lines[i + 1].Trim();
            }
            // Sección "Descripción"
            else if (line.StartsWith("Asunto", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Asunto = lines[i + 1].Trim();
            }
            else if (line.StartsWith("¿A quién denuncia?", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.A_Quien_Denuncia = lines[i + 1].Trim();
            }
            else if (line.StartsWith("Describa su denuncia", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Descripcion_Denuncia = lines[i + 1].Trim();
            }
            else if (line.StartsWith("¿Ha denunciado estos hechos ante otras instituciones", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Denunciado_Ante_Inst = lines[i + 1].Trim();
            }
            // Sección "Lugar y fecha de los hechos"
            else if (line.StartsWith("Lugar en la que ocurrieron los hechos", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Lugar_Hechos = lines[i + 1].Trim();
            }
            else if (line.StartsWith("Fecha de los hechos que denuncia", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                {
                    var fechaHechosStr = lines[i + 1].Trim();
                    // Si el valor es "ayer", se asume la fecha de ayer
                    if (fechaHechosStr.Equals("ayer", StringComparison.OrdinalIgnoreCase))
                        denuncia.Fecha_Hechos = DateTime.Now.AddDays(-1);
                    else if (DateTime.TryParse(fechaHechosStr, out DateTime fechaHechosParsed))
                        denuncia.Fecha_Hechos = fechaHechosParsed;
                }
            }
            // Sección "Notificaciones"
            else if (line.Equals("Correo electrónico", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Correo_Electronico = lines[i + 1].Trim();
            }
            else if (line.Equals("Notificaciones Electrónicas", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Notificacion_Electronica = lines[i + 1].Trim();
            }
            else if (line.Equals("Notificaciones mediante SMS", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Notificacion_Sms = lines[i + 1].Trim();
            }
            else if (line.Equals("Seleccione su preferencia de notificación y seguimiento de su denuncia", StringComparison.OrdinalIgnoreCase)
                  || line.Equals("Notificación Preferencia", StringComparison.OrdinalIgnoreCase))
            {
                if (i + 1 < lines.Length)
                    denuncia.Notificacion_Preferencia = lines[i + 1].Trim();
            }
            // Sección "Condiciones y reglas de uso"
            else if (line.Contains("☑"))
            {
                denuncia.Condiciones = true;
            }
        }

        denuncia.Comments = commentsBuilder.ToString();
        return denuncia;
    }
}



<script>
    // Función JS que dispara el click en el elemento con el ID indicado.
    window.triggerFileInput = (elementId) => {
        document.getElementById(elementId).click();
    };
</script>
