using Android.Content; using Android.Util; using AutoMapper; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using System.Net.Http.Json; using System.Text; using WorkFlowCheck.Common.DTO; using WorkFlowCheck.MAUI.DataLayer; using WorkFlowCheck.MAUI.DataLayer.Entities; using WorkFlowCheck.MAUI.Handlers; using WorkFlowCheck.MAUI.Services.Interfaces; using static Android.Renderscripts.ScriptGroup; using Location = WorkFlowCheck.MAUI.DataLayer.Entities.Location; namespace WorkFlowCheck.MAUI.Services { public class SyncService : BaseService, ISyncService { private readonly IUserService _userService; public SyncService(HttpClient httpClient, AppDbContext dbContext, IMapper mapper, IUserService userService) : base(httpClient, dbContext, mapper) { _userService = userService; } public async Task SyncDatas(Action reportProgress) { await SyncCheckPoints_Down(reportProgress); await SyncLocations_Down(reportProgress); await SyncEquipments_Down(reportProgress); await SyncCheckListTemplates_Down(reportProgress); await SyncCheckListHeader_Down(reportProgress); await SyncUsers_Down(reportProgress); } public async Task DownloadAPK(Action reportProgress) { try { await PrepareAuthenticatedRequestAsync(); string endpoint = $"{_httpClient.BaseAddress}api/Sync/Download"; string fileName = "com.nuvolar.wfcapp-Signed.apk"; // Az Androidon lévő privát letöltési mappa string downloadFolder = Path.Combine(Android.App.Application.Context.GetExternalFilesDir(null)?.AbsolutePath, "APK"); // Ellenőrizd, hogy a mappa létezik-e, ha nem, hozd létre if (!Directory.Exists(downloadFolder)) { Directory.CreateDirectory(downloadFolder); } string filePath = Path.Combine(downloadFolder, fileName); using (_httpClient) { var response = await _httpClient.GetAsync(endpoint, HttpCompletionOption.ResponseHeadersRead); if (response.IsSuccessStatusCode) { var totalBytes = response.Content.Headers.ContentLength ?? -1L; long receivedBytes = 0; using (var stream = await response.Content.ReadAsStreamAsync()) using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None)) { byte[] buffer = new byte[1024 * 1024] ; int bytesRead; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await fileStream.WriteAsync(buffer, 0, bytesRead); receivedBytes += bytesRead; if (totalBytes != -1) { double progress = (double)receivedBytes / totalBytes * 100; reportProgress(progress, $"APK letöltés..."); } else { reportProgress(-1, $"APK letöltés..."); } } } // Telepítés indítása a FileProvider segítségével //var apkUri = FileProvider.GetUriForFile(Android.App.Application.Context, // $"{Android.App.Application.Context.PackageName}.fileprovider", // new Java.IO.File(filePath)); //var installIntent = new Intent(Intent.ActionView); //installIntent.SetDataAndType(apkUri, "application/vnd.android.package-archive"); //installIntent.AddFlags(ActivityFlags.NewTask); //installIntent.AddFlags(ActivityFlags.GrantReadUriPermission); //Android.App.Application.Context.StartActivity(installIntent); } else { reportProgress(0, $"Letöltési hiba: {response.StatusCode}"); Console.WriteLine($"Letöltési hiba: {response.StatusCode}"); } } } catch (Exception ex) { reportProgress(0, $"Hiba történt: {ex.Message}"); Console.WriteLine($"Hiba történt: {ex.Message}"); } } public async Task SyncCheckPoints_Down(Action reportProgress) { try { string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllCheckPoints"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null) { if (responseList.IsSuccess) { var entityList = await _dbContext.CheckPoints.ToListAsync(); var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList(); var mappedMissingItems = _mapper.Map>(missingItems); _dbContext.CheckPoints.AddRange(mappedMissingItems); await _dbContext.SaveChangesAsync(); } } } catch (Exception ex) { Console.WriteLine($"Hiba történt: {ex.Message}"); } } public async Task> SyncCheckPoints_Up(Action reportProgress) { var retVal = new ApiResponseDTO(); try { await PrepareAuthenticatedRequestAsync(); var checkPointList = await _dbContext.CheckPoints.ToListAsync(); var checkPointListDTO = _mapper.Map>(checkPointList); var endpoint = $"{_httpClient.BaseAddress}api/Sync/UpdateAllCheckPoint"; var json = JsonConvert.SerializeObject(checkPointListDTO, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); var jsonBytes = Encoding.UTF8.GetBytes(json); var jsonStream = new MemoryStream(jsonBytes); var progressContent = new ProgressableStreamContent(jsonStream, 8192, (uploaded, total) => { double percentage = (double)uploaded / total * 100; reportProgress(percentage, "Beküldés..."); }); progressContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsync(endpoint, progressContent)) { httpResponseMessage.EnsureSuccessStatusCode(); var jsonString = await httpResponseMessage.Content.ReadAsStringAsync(); retVal = JsonConvert.DeserializeObject>(jsonString); } } catch (Exception ex) { retVal.IsSuccess = false; retVal.Errors.Add(ex.Message); } return retVal; } public async Task SyncLocations_Down(Action reportProgress) { try { string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllLocations"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null) { if (responseList.IsSuccess) { var entityList = await _dbContext.Locations.ToListAsync(); var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList(); var mappedMissingItems = _mapper.Map>(missingItems); _dbContext.Locations.AddRange(mappedMissingItems); await _dbContext.SaveChangesAsync(); } } } catch (Exception ex) { // Hiba visszaadása } } public async Task SyncEquipments_Down(Action reportProgress) { try { string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllEquipments"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null) { if (responseList.IsSuccess) { var entityList = await _dbContext.Equipments.ToListAsync(); var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList(); var mappedMissingItems = _mapper.Map>(missingItems); _dbContext.Equipments.AddRange(mappedMissingItems); await _dbContext.SaveChangesAsync(); } } } catch (Exception ex) { // Hiba visszaadása } } public async Task SyncCheckListTemplates_Down(Action reportProgress) { try { var userId = _userService.GetCurrentUser()?.Id; string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllCheckListTemplateHeader/{userId}"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null) { if (responseList.IsSuccess) { var checkListTemplateHeaderList = await _dbContext.CheckListTemplateHeaders.ToListAsync(); var missingItems = responseList.Data.Where(f => !checkListTemplateHeaderList.Any(s => s.Id == f.Id)).ToList(); var missingCheckListTemplateHeaders = _mapper.Map>(missingItems); _dbContext.CheckListTemplateHeaders.AddRange(missingCheckListTemplateHeaders); await _dbContext.SaveChangesAsync(); } } } catch (Exception ex) { // Hiba visszaadása } } public async Task SyncCheckListHeader_Down(Action reportProgress) { try { var userId = _userService.GetCurrentUser()?.Id; string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllCheckListHeader/{userId}"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null && responseList.IsSuccess) { var checkListHeaderList = await _dbContext.CheckListHeaders.ToListAsync(); var missingItems = responseList.Data .Where(f => !checkListHeaderList.Any(s => s.GuidNumber == f.GuidNumber)) .ToList(); var missingCheckListHeaders = _mapper.Map>(missingItems); _dbContext.CheckListHeaders.AddRange(missingCheckListHeaders); await _dbContext.SaveChangesAsync(); int i = 1; foreach (var item in missingItems) { double itemPercentage = (double)i / missingItems.Count * 100; reportProgress(itemPercentage, "Adatbázis szinkronizáció..."); // Közvetlen progress jelentés i++; } foreach (var checkListHeaderDTO in responseList.Data) { var checkListHeader = await _dbContext.CheckListHeaders.Where(w => w.Id == checkListHeaderDTO.Id).FirstOrDefaultAsync(); if (checkListHeader != null) { checkListHeader.CheckStatus = checkListHeaderDTO.CheckStatus; await _dbContext.SaveChangesAsync(); //foreach (var checkListRow in checkListHeader.CheckListRows) //{ // var checkListRowDTO = checkListHeaderDTO.CheckListRowDTO.Where(w => w.GuidNumber == checkListRow.GuidNumber).FirstOrDefault(); // if (checklistrow{ // } //} } } } } catch (Exception ex) { Console.WriteLine($"Hiba történt: {ex.Message}"); } } public async Task> SyncCheckListHeader_Up(int Id, Action reportProgress) { var retVal = new ApiResponseDTO(); try { await PrepareAuthenticatedRequestAsync(); var checkListHeader = await _dbContext.CheckListHeaders .Where(w => w.Id == Id) .Include(i => i.CheckListRows) .ThenInclude(i => i.CheckListTemplateRow) .ThenInclude(i => i.CheckPoint) .AsNoTracking() .FirstOrDefaultAsync(); var checkListHeaderDTO = _mapper.Map(checkListHeader); var endpoint = $"{_httpClient.BaseAddress}api/Sync/SendCheckListHeader"; var json = JsonConvert.SerializeObject(checkListHeaderDTO, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); var jsonBytes = Encoding.UTF8.GetBytes(json); var jsonStream = new MemoryStream(jsonBytes); var progressContent = new ProgressableStreamContent(jsonStream, 8192, (uploaded, total) => { double percentage = (double)uploaded / total * 100; reportProgress(percentage, "Beküldés..."); }); progressContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsync(endpoint, progressContent)) { httpResponseMessage.EnsureSuccessStatusCode(); var jsonString = await httpResponseMessage.Content.ReadAsStringAsync(); retVal = JsonConvert.DeserializeObject>(jsonString); } } catch (Exception ex) { retVal.IsSuccess = false; retVal.Errors.Add(ex.Message); } return retVal; } public async Task>> DownloadDataAsync(string endpoint, Action reportProgress) { await PrepareAuthenticatedRequestAsync(); using var response = await _httpClient.GetAsync(endpoint, HttpCompletionOption.ResponseHeadersRead); response.EnsureSuccessStatusCode(); using var stream = await response.Content.ReadAsStreamAsync(); using var memoryStream = new MemoryStream(); var buffer = new byte[8192]; long totalRead = 0; int bytesRead; int chunkCounter = 0; while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) { await memoryStream.WriteAsync(buffer, 0, bytesRead); totalRead += bytesRead; chunkCounter++; // Gyakori progress frissítés if (chunkCounter % 5 == 0) // 5 blokk után { double estimatedProgress = Math.Min((double)totalRead / (8192 * 100) * 100, 99); reportProgress(estimatedProgress, "Letöltés ..."); } } // Végső progress 100%-ra állítása reportProgress(100, "Letöltés ... kész!"); memoryStream.Position = 0; var jsonString = Encoding.UTF8.GetString(memoryStream.ToArray()); // Generikus deszerializálás var responseList = JsonConvert.DeserializeObject>>(jsonString); return responseList; } public async Task> DeviceMessageReadUnreaded(string deviceId) { var deviceIdBase64 = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(deviceId)); string endpoint = $"{_httpClient.BaseAddress}api/Sync/DeviceMessageReadUnreaded/{deviceIdBase64}"; var retVal = new List(); try { var response = await _httpClient.GetFromJsonAsync>>(endpoint); if (response != null) { if (response.IsSuccess) { return response.Data; } } } catch (Exception ex) { } return retVal; } public async Task> DeviceMessageReadUnreadedRole(int roleId) { string endpoint = $"{_httpClient.BaseAddress}api/Sync/DeviceMessageReadUnreadedRole/{roleId}"; var retVal = new List(); try { var response = await _httpClient.GetFromJsonAsync>>(endpoint); if (response != null) { if (response.IsSuccess) { return response.Data; } } } catch (Exception ex) { } return retVal; } public async Task> SyncUsers_Up(Action reportProgress) { var retVal = new ApiResponseDTO(); try { await PrepareAuthenticatedRequestAsync(); var userList = await _dbContext.MobileUsers.ToListAsync(); var mobileUserListDTO = _mapper.Map>(userList); var endpoint = $"{_httpClient.BaseAddress}api/Sync/UpdateAllMobileUser"; var json = JsonConvert.SerializeObject(mobileUserListDTO, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); var jsonBytes = Encoding.UTF8.GetBytes(json); var jsonStream = new MemoryStream(jsonBytes); var progressContent = new ProgressableStreamContent(jsonStream, 8192, (uploaded, total) => { double percentage = (double)uploaded / total * 100; reportProgress(percentage, "Beküldés..."); }); progressContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsync(endpoint, progressContent)) { httpResponseMessage.EnsureSuccessStatusCode(); var jsonString = await httpResponseMessage.Content.ReadAsStringAsync(); retVal = JsonConvert.DeserializeObject>(jsonString); } } catch (Exception ex) { retVal.IsSuccess = false; retVal.Errors.Add(ex.Message); } return retVal; } public async Task SyncUsers_Down(Action reportProgress) { try { string endpoint = $"{_httpClient.BaseAddress}api/Sync/GetAllMobileUsers"; var responseList = DownloadDataAsync(endpoint, reportProgress).Result; if (responseList != null) { if (responseList.IsSuccess) { var entityList = await _dbContext.MobileUsers.ToListAsync(); var missingItems = responseList.Data.Where(f => !entityList.Any(s => s.Id == f.Id)).ToList(); var mappedMissingItems = _mapper.Map>(missingItems); _dbContext.MobileUsers.AddRange(mappedMissingItems); await _dbContext.SaveChangesAsync(); } } } catch (Exception ex) { // Hiba visszaadása } } public async Task> UploadFCMToken(string token) { var retVal = new ApiResponseDTO(); try { string endpoint = $"{_httpClient.BaseAddress}api/fcm/SendFCMToken"; var FCMMessageDTO = new FCMMessageDTO() { Token = token, UserId = _userService.GetCurrentUser()?.Id }; using (HttpResponseMessage httpResponseMessage = await _httpClient.PostAsJsonAsync(endpoint, FCMMessageDTO)) { httpResponseMessage.EnsureSuccessStatusCode(); var jsonString = await httpResponseMessage.Content.ReadAsStringAsync(); var response = JsonConvert.DeserializeObject>(jsonString); return response ?? new ApiResponseDTO { IsSuccess = false, }; } } catch (Exception ex) { // Hiba visszaadása return new ApiResponseDTO { IsSuccess = false }; } } } }