using ClosedXML.Excel;
using HospitalManagementSystem.Documents;
using HospitalManagementSystem.Dto;
using HospitalManagementSystem.GlobalEnum;
using HospitalManagementSystem.Patients.Dto;
using HospitalManagementSystem.Permissions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
using Volo.Abp.Domain.Repositories;
using static HospitalManagementSystem.Permissions.HospitalManagementSystemPermissions;


namespace HospitalManagementSystem.Patients
{
    public class PatientAppService : ApplicationService
    {
        private IRepository<PatientRecord, Guid> _patientrecordRepository;
        private IRepository<Patient, Guid> _patientRepository;
        private IRepository<EntityDocument, Guid> _entityDocumentRepository;
        private IRepository<PatientDocument, Guid> _patientDocumentRepository;
        private readonly IWebHostEnvironment _env;
        List<Guid> uniqueid = new List<Guid>();

        public PatientAppService(IRepository<PatientRecord, Guid> patientrecordRepository, IRepository<Patient, Guid> patientRepository, IWebHostEnvironment env, IRepository<EntityDocument, Guid> entityDocumentRepository, IRepository<PatientDocument, Guid> patientDocumentRepository)
        {
            _patientrecordRepository = patientrecordRepository;
            _patientRepository = patientRepository;
            _env = env;
            _entityDocumentRepository = entityDocumentRepository;
            _patientDocumentRepository = patientDocumentRepository;
        }

        #region PatientRecord

        #region Get Patient List with Paging and Searching
        [Authorize(HospitalManagementSystemPermissions.Patient.Default)]
        public async Task<PagedResultDto<PatientRecordDto>> GetPatientRecordListAsync(PagingSortPatientResultDto input, Guid Id)
        {
            var queryable = await _patientrecordRepository.GetQueryableAsync();

            var filteredQuery = queryable
                .Include(x => x.Patients)
                .Include(x => x.LabReportUrl)
                .Include(x => x.MedicationUrl)
                .Include(x => x.MedicationHistoryUrl)
                .WhereIf(!string.IsNullOrEmpty(input.Search), x => x.Patients.Name.ToLower().Contains(input.Search.ToLower()))
                .Where(x => x.Patients.Id == Id);

            var totalCount = await filteredQuery.CountAsync();

            filteredQuery = !string.IsNullOrEmpty(input.Sorting)
                ? filteredQuery.OrderBy(input.Sorting)
                : filteredQuery.OrderBy(x => x.Id);

            var pagedQuery = await filteredQuery
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .ToListAsync();
            var patientrecorddto = ObjectMapper.Map<List<PatientRecord>, List<PatientRecordDto>>(pagedQuery);
            foreach (var pr in patientrecorddto)
            {
                pr.LabReportUrl = filteredQuery.Where(x => x.Id == pr.Id).Select(x => x.LabReportUrl.FilePath).FirstOrDefault();
                pr.MedicationUrl = filteredQuery.Where(x => x.Id == pr.Id).Select(x => x.MedicationUrl.FilePath).FirstOrDefault();
                pr.MedicationHistoryUrl = filteredQuery.Where(x => x.Id == pr.Id).Select(x => x.MedicationHistoryUrl.FilePath).FirstOrDefault();
            }
            return new PagedResultDto<PatientRecordDto>(
                totalCount,
                patientrecorddto
            );

        }
        #endregion

        #region Get Single Patient by Id
        [Authorize(HospitalManagementSystemPermissions.Patient.Default)]
        public async Task<PatientRecordDto> GetPatientRecordByIdAsync(Guid id)
        {
            var patient = await _patientrecordRepository.GetQueryableAsync().Result
                          .Include(x => x.LabReportUrl)
                          .Include(x => x.MedicationUrl)
                          .Include(x => x.MedicationHistoryUrl)
                          .Where(x => x.Id == id).FirstOrDefaultAsync();
            var patientdto = ObjectMapper.Map<PatientRecord, PatientRecordDto>(patient);

            patientdto.LabReportUrl = patient.LabReportUrl != null ? patient.LabReportUrl.FilePath : null;
            patientdto.MedicationUrl = patient.MedicationUrl != null ? patient.MedicationUrl.FilePath : null;
            patientdto.MedicationHistoryUrl = patient.MedicationHistoryUrl != null ? patient.MedicationHistoryUrl.FilePath : null;
            return patientdto;
        }
        #endregion

        #region Export Patient Data to Excel
        public async Task<FileDownloadDto> GetExportPatientRecordAsync()
        {
            var patientrecord = await _patientrecordRepository.GetQueryableAsync().Result.Include(x => x.Patients).ToListAsync();

            var folderPath = Path.Combine(_env.WebRootPath, "temp");
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath); // Ensure the folder exists
            }

            var filename = "Patients_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".xlsx";
            var filePath = Path.Combine(folderPath, filename);

            // Create a workbook and worksheet
            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("Patients");

                // Add headers
                worksheet.Cell(1, 1).Value = "Full Name";
                worksheet.Cell(1, 2).Value = "Gender";
                worksheet.Cell(1, 3).Value = "Date of Admission";
                worksheet.Cell(1, 4).Value = "Diagnosis";
                worksheet.Cell(1, 5).Value = "Next Follow-Up";
                worksheet.Cell(1, 6).Value = "InsuranceProvider";
                worksheet.Cell(1, 7).Value = "InsuranceProvider";
                worksheet.Cell(1, 8).Value = "InsuranceProvider";
                worksheet.Cell(1, 9).Value = "Status";

                for (int i = 0; i < patientrecord.Count; i++)
                {
                    worksheet.Cell(i + 2, 1).Value = patientrecord[i].Patients.Name;
                    worksheet.Cell(i + 2, 2).Value = patientrecord[i].Patients.Gender.ToString();
                    worksheet.Cell(i + 2, 3).Value = patientrecord[i].DateOfAdmission.ToShortDateString();
                    worksheet.Cell(i + 2, 4).Value = patientrecord[i].Diagnosis;
                    worksheet.Cell(i + 2, 5).Value = patientrecord[i].NextFollowUp?.ToShortDateString();
                    worksheet.Cell(i + 2, 6).Value = patientrecord[i].InsuranceProvider;
                    worksheet.Cell(i + 2, 7).Value = patientrecord[i].InsuranceProvider;
                    worksheet.Cell(i + 2, 8).Value = patientrecord[i].InsuranceProvider;
                    worksheet.Cell(i + 2, 9).Value = patientrecord[i].Status.ToString();
                }

                worksheet.Columns().AdjustToContents();
                workbook.SaveAs(filePath);
            }

            byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
            File.Delete(filePath);

            return new FileDownloadDto
            {
                FileName = filename,
                FileContent = Convert.ToBase64String(fileBytes) // Use Base64 encoding for file content
            };
        }

        #endregion

        #region Create Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Create)]
        public async Task<PatientRecordDto> CreatePatientRecordAsync(CreateUpdatePatientRecordDto input)
        {
            var patientEntity = await _patientRepository.GetAsync(input.PatientId); // Get Patient from DB
            var patientRecord = ObjectMapper.Map<CreateUpdatePatientRecordDto, PatientRecord>(input);
            patientRecord.Patients = patientEntity;
            List<EntityDocument> entitydocument = new List<EntityDocument>();

            if (input.LabReportUrlID != Guid.Empty)
                uniqueid.Add(input.LabReportUrlID.Value);
            if (input.MedicationUrlID != Guid.Empty)
                uniqueid.Add(input.MedicationUrlID.Value);
            if (input.MedicationHistoryUrlID != Guid.Empty)
                uniqueid.Add(input.MedicationHistoryUrlID.Value);
            if (uniqueid.Count > 0)
            {
                entitydocument = await SaveFileToDocument(patientEntity, uniqueid);
                foreach (var entity in entitydocument)
                {
                    switch (entity.TagName)
                    {
                        case "Lab-Report":
                            patientRecord.LabReportUrl = entity;
                            break;
                        case "Medication":
                            patientRecord.MedicationUrl = entity;
                            break;
                        case "Medication-History":
                            patientRecord.MedicationHistoryUrl = entity;
                            break;
                    }
                }
            }
            patientRecord = await _patientrecordRepository.InsertAsync(patientRecord);

            return ObjectMapper.Map<PatientRecord, PatientRecordDto>(patientRecord);
        }
        #endregion

        #region Update Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Edit)]
        public async Task<PatientRecordDto> UpdatePatientRecordAsync(Guid id, CreateUpdatePatientRecordDto input)
        {
            try
            {
                var patientRecord = await _patientrecordRepository.GetQueryableAsync().Result.Include(x => x.Patients).Where(x => x.Id == id).FirstOrDefaultAsync();
                List<EntityDocument> entitydocument = new List<EntityDocument>();
                if (patientRecord.Patients.Id != input.PatientId) // If PatientId is updated, fetch new Patient
                {
                    var newPatient = await _patientRepository.GetAsync(input.PatientId);
                    patientRecord.Patients = newPatient;
                }
                ObjectMapper.Map(input, patientRecord);
                if (input.LabReportUrlID != Guid.Empty)
                    uniqueid.Add(input.LabReportUrlID.Value);
                if (input.MedicationUrlID != Guid.Empty)
                    uniqueid.Add(input.MedicationUrlID.Value);
                if (input.MedicationHistoryUrlID != Guid.Empty)
                    uniqueid.Add(input.MedicationHistoryUrlID.Value);
                if (uniqueid.Count > 0)
                {
                    entitydocument = await SaveFileToDocument(patientRecord.Patients, uniqueid);
                    foreach (var entity in entitydocument)
                    {
                        switch (entity.TagName)
                        {
                            case "Lab-Report":
                                patientRecord.LabReportUrl = entity;
                                break;
                            case "Medication":
                                patientRecord.MedicationUrl = entity;
                                break;
                            case "Medication-History":
                                patientRecord.MedicationHistoryUrl = entity;
                                break;
                        }
                    }
                }
                patientRecord = await _patientrecordRepository.UpdateAsync(patientRecord);

                return ObjectMapper.Map<PatientRecord, PatientRecordDto>(patientRecord);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }
        #endregion

        #region Delete Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Delete)]
        public async Task DeletePatientRecordAsync(Guid id)
        {
            await _patientrecordRepository.DeleteAsync(id);
        }
        #endregion
        #endregion

        #region Patient

        #region Get Patient List with Paging and Searching
        [Authorize(HospitalManagementSystemPermissions.Patient.Default)]
        public async Task<PagedResultDto<PatientDto>> GetPatientListAsync(PagingSortPatientResultDto input)
        {
            List<Patient> query;

            if (!string.IsNullOrEmpty(input.Search))
            {
                query = _patientRepository.GetQueryableAsync().Result
                    .Where(x => x.Name.ToLower().Contains(input.Search.ToLower()))
                    .OrderBy(input.Sorting ?? (nameof(Patient.Id) + " asc"))
                    .Skip(input.SkipCount)
                    .Take(input.MaxResultCount)
                    .ToList();
            }
            else
            {
                query = await _patientRepository.GetPagedListAsync(
                    input.SkipCount,
                    input.MaxResultCount,
                    input.Sorting ?? nameof(Patient.Name)
                );
            }

            var totalCount = await _patientRepository.CountAsync();
            return new PagedResultDto<PatientDto>(
                totalCount,
                ObjectMapper.Map<List<Patient>, List<PatientDto>>(query)
            );
        }
        #endregion

        #region Get Single Patient by Id
        [Authorize(HospitalManagementSystemPermissions.Patient.Default)]
        public async Task<PatientDto> GetPatientByIdAsync(Guid id)
        {
            var patient = await _patientRepository.GetQueryableAsync().Result.Include(x => x.Images).Where(x => x.Id == id).FirstOrDefaultAsync();
            var patientdto = ObjectMapper.Map<Patient, PatientDto>(patient);
            patientdto.Imagepath = patient.Images != null ? patient.Images.FilePath : null;
            return patientdto;
        }
        #endregion

        #region Export Patient Data to Excel
        public async Task<FileDownloadDto> GetExportPatientDataAsync()
        {
            var patients = await _patientRepository.GetListAsync();

            var folderPath = Path.Combine(_env.WebRootPath, "temp");
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }

            var filename = "Patients_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".xlsx";
            var filePath = Path.Combine(folderPath, filename);

            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("Patients");

                // Add headers
                worksheet.Cell(1, 1).Value = "Name";
                worksheet.Cell(1, 2).Value = "Gender";
                worksheet.Cell(1, 3).Value = "Age";
                worksheet.Cell(1, 4).Value = "BloodGroup";
                worksheet.Cell(1, 5).Value = "Treatment";
                worksheet.Cell(1, 6).Value = "Doctor Assigned";
                worksheet.Cell(1, 7).Value = "Admission Date";
                worksheet.Cell(1, 8).Value = "Discharge Date";
                worksheet.Cell(1, 9).Value = "Status";

                // Add data rows
                for (int i = 0; i < patients.Count; i++)
                {
                    worksheet.Cell(i + 2, 1).Value = patients[i].Name;
                    worksheet.Cell(i + 2, 2).Value = patients[i].Gender.ToString();
                    worksheet.Cell(i + 2, 3).Value = patients[i].Age;
                    worksheet.Cell(i + 2, 4).Value = patients[i].BloodGroup;
                    worksheet.Cell(i + 2, 5).Value = patients[i].Treatment;
                    worksheet.Cell(i + 2, 6).Value = patients[i].DoctorAssigned;
                    worksheet.Cell(i + 2, 7).Value = patients[i].AdmissionDate.ToShortDateString();
                    worksheet.Cell(i + 2, 8).Value = patients[i].DischargeDate?.ToShortDateString();
                    worksheet.Cell(i + 2, 9).Value = patients[i].Status.ToString();
                }

                worksheet.Columns().AdjustToContents();
                workbook.SaveAs(filePath);
            }

            byte[] fileBytes = await File.ReadAllBytesAsync(filePath);
            File.Delete(filePath);

            return new FileDownloadDto
            {
                FileName = filename,
                FileContent = Convert.ToBase64String(fileBytes)
            };
        }
        #endregion

        #region Create Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Create)]
        public async Task<PatientDto> CreatePatientAsync(CreateUpdatePatientDto input)
        {
            var patient = ObjectMapper.Map<CreateUpdatePatientDto, Patient>(input);

            patient = await _patientRepository.InsertAsync(patient);
            if (input.ImageID != Guid.Empty)
            {
                uniqueid.Add(input.ImageID);
                var entitydocument = await SaveFileToDocument(patient, uniqueid, true);
                foreach (var entity in entitydocument)
                {
                    if (entity.TagName == "Image")
                    {
                        patient.Images = entity;
                    }
                }
            }

            return ObjectMapper.Map<Patient, PatientDto>(patient);
        }
        #endregion

        #region Update Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Edit)]
        public async Task<PatientDto> UpdatePatientAsync(Guid id, CreateUpdatePatientDto input)
        {
            var patient = await _patientRepository.GetQueryableAsync().Result.Include(x => x.Images).Where(x => x.Id == id).FirstOrDefaultAsync();
            List<EntityDocument> entitydocument = new List<EntityDocument>();
            ObjectMapper.Map(input, patient);
            if (input.ImageID != Guid.Empty)
            {
                uniqueid.Add(input.ImageID);
                entitydocument = await SaveFileToDocument(patient, uniqueid);
                foreach (var entity in entitydocument)
                {
                    if (entity.TagName == "Image")
                    {
                        patient.Images = entity;
                    }
                }
            }

            patient = await _patientRepository.UpdateAsync(patient);
            return ObjectMapper.Map<Patient, PatientDto>(patient);
        }
        #endregion

        #region Delete Patient
        [Authorize(HospitalManagementSystemPermissions.Patient.Delete)]
        public async Task DeletePatientAsync(Guid id)
        {
            await _patientRepository.DeleteAsync(id);
        }
        #endregion

        #endregion

        #region Get Status Dropdown
        public async Task<List<DropDownItems>> GetStatusDropdownAsync()
        {
            List<DropDownItems> statuslist = new List<DropDownItems>();

            statuslist = Enum.GetValues(typeof(Status))
                .Cast<Status>()
                .Select(e => new DropDownItems
                {
                    Label = e.ToString(),
                    Value = (int)e
                })
                .ToList();
            statuslist.Add(new DropDownItems
            {
                Label = "Select a Status",
                Value = 0
            });
            statuslist = statuslist.OrderBy(x => x.Value).ToList();

            return await Task.FromResult(statuslist);
        }
        #endregion

        #region UploadFile
        public async Task<Guid> UploadFileAsync(string TagName, IRemoteStreamContent file)
        {
            if (file == null)
            {
                throw new Exception("File cannot be null");
            }
            string patientFolder = Path.Combine(_env.WebRootPath, "temp");
            Guid uniqueId = Guid.NewGuid();
            if (!Directory.Exists(patientFolder))
            {
                Directory.CreateDirectory(patientFolder);
            }

            string fileExtension = Path.GetExtension(file.FileName);
            string fileName = $"{uniqueId}({TagName}){fileExtension}";
            string filePath = Path.Combine(patientFolder, fileName);

            using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                await file.GetStream().CopyToAsync(fileStream);
            }

            var metadata = new
            {
                OriginalFileName = file.FileName,
                FileName = fileName,
                FileSize = new FileInfo(filePath).Length.ToString(),
                FilePath = filePath,
                UploadDate = DateTime.UtcNow,
                FileType = fileExtension,
                TagName = TagName,
            };

            string jsonFileName = $"{uniqueId}({TagName}).json";
            string jsonFilePath = Path.Combine(patientFolder, jsonFileName);
            await File.WriteAllTextAsync(jsonFilePath, JsonSerializer.Serialize(metadata, new JsonSerializerOptions { WriteIndented = true }));

            return uniqueId;
        }
        #endregion

        #region SaveFileToDocument
        //public async Task<List<EntityDocument>> SaveFileToDocument(Patient Patients, Guid ImageId, bool IsNew = false)
        //{
        //    try
        //    {
        //        //string patientFolder = Path.Combine(_env.WebRootPath, "uploads", PatientId.ToString());
        //        string patientFolder = Path.Combine(_env.WebRootPath, "uploads", $"{Patients.Id}({Patients.Name})");
        //        string ImageFolder = Path.Combine(_env.WebRootPath, "uploads", $"{ImageId}({Patients.Name})");
        //        List<string>? jsonFiles;

        //        if (IsNew)
        //        {
        //            jsonFiles = Directory.EnumerateFiles(ImageFolder, "*.json").Where(x => Path.GetFileName(x).StartsWith(ImageId.ToString())).ToList();
        //        }
        //        else
        //        {
        //            jsonFiles = Directory.EnumerateFiles(patientFolder, "*.json").Where(x => Path.GetFileName(x).StartsWith(Patients.Id.ToString())).ToList();
        //        }

        //        List<EntityDocument> savedDocuments = new List<EntityDocument>();

        //        // Iterate over all matching JSON files and save data to the database
        //        foreach (var jsonFilePath in jsonFiles)
        //        {
        //            string jsonContent = await File.ReadAllTextAsync(jsonFilePath);
        //            var metadata = JsonSerializer.Deserialize<dynamic>(jsonContent);

        //            var document = new EntityDocument
        //            {
        //                OriginalFileName = metadata.GetProperty("OriginalFileName").GetString(),
        //                GeneratedFileName = metadata.GetProperty("FileName").GetString(),
        //                FileSize = metadata.GetProperty("FileSize").GetString(),
        //                FilePath = metadata.GetProperty("FilePath").GetString(),
        //                FileType = metadata.GetProperty("FileType").GetString(),
        //                TagName = metadata.GetProperty("TagName").GetString(),
        //                UploadDate = metadata.GetProperty("UploadDate").GetDateTime() // Use GetDateTime()
        //            };

        //            // Save document record to the database
        //            await _entityDocumentRepository.InsertAsync(document);
        //            savedDocuments.Add(document);
        //            var patientidexist = await _patientDocumentRepository.GetQueryableAsync().Result.Include(x => x.Patients).Include(x => x.EntityDocuments)
        //                                 .Where(x => x.Patients.Id == Patients.Id && x.TagName == document.TagName).FirstOrDefaultAsync();
        //            var patientDocument = new PatientDocument
        //            {
        //                Patients = Patients,
        //                EntityDocuments = document,
        //                TagName = metadata.GetProperty("TagName").GetString()
        //            };
        //            if (patientidexist != null)
        //            {
        //                await _patientDocumentRepository.UpdateAsync(patientDocument);
        //            }
        //            else
        //            {
        //                await _patientDocumentRepository.InsertAsync(patientDocument);
        //            }
        //            File.Delete(jsonFilePath);
        //        }
        //        return savedDocuments;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw new Exception(ex.Message);
        //    }
        //}
        public async Task<List<EntityDocument>> SaveFileToDocument(Patient patient, List<Guid> uniqueIds, bool isNew = false)
        {
            try
            {
                string tempFolder = Path.Combine(_env.WebRootPath, "temp");
                string patientFolder = Path.Combine(_env.WebRootPath, "uploads", $"{patient.Id}({patient.Name})");

                if (!Directory.Exists(patientFolder))
                {
                    Directory.CreateDirectory(patientFolder);
                }

                List<EntityDocument> savedDocuments = new List<EntityDocument>();

                foreach (var uniqueId in uniqueIds)
                {
                    // Fetch all matching JSON metadata files for the current uniqueId
                    foreach (var jsonFilePath in Directory.EnumerateFiles(tempFolder, $"{uniqueId}(*).json"))
                    {
                        string jsonContent = await File.ReadAllTextAsync(jsonFilePath);
                        var metadata = JsonSerializer.Deserialize<JsonElement>(jsonContent);

                        string originalFileName = metadata.GetProperty("OriginalFileName").GetString();
                        string generatedFileName = metadata.GetProperty("FileName").GetString();
                        string fileSize = metadata.GetProperty("FileSize").GetString();
                        string filePath = metadata.GetProperty("FilePath").GetString();
                        string fileType = metadata.GetProperty("FileType").GetString();
                        string tagName = metadata.GetProperty("TagName").GetString();
                        DateTime uploadDate = metadata.GetProperty("UploadDate").GetDateTime();

                        // Move the file from temp folder to patient folder
                        string newFilePath = Path.Combine(patientFolder, generatedFileName);
                        if (File.Exists(filePath))
                        {
                            File.Move(filePath, newFilePath, true);
                        }
                        newFilePath = newFilePath.Split("wwwroot")[1];
                        var document = new EntityDocument
                        {
                            OriginalFileName = originalFileName,
                            GeneratedFileName = generatedFileName,
                            FileSize = fileSize,
                            FilePath = newFilePath,
                            FileType = fileType,
                            TagName = tagName,
                            UploadDate = uploadDate
                        };
                        savedDocuments.Add(document);

                        // Delete JSON file after processing
                        File.Delete(jsonFilePath);
                    }
                }

                // Batch insert entity documents
                if (savedDocuments.Any())
                {
                    await _entityDocumentRepository.InsertManyAsync(savedDocuments);
                }

                // Fetch existing patient documents in one query
                var existingPatientDocs = await _patientDocumentRepository.GetQueryableAsync()
                    .Result.Where(x => x.Patients.Id == patient.Id)
                    .ToListAsync();

                List<PatientDocument> patientDocuments = new List<PatientDocument>();

                foreach (var document in savedDocuments)
                {
                    var existingDoc = existingPatientDocs.FirstOrDefault(x => x.TagName == document.TagName);

                    var patientDocument = new PatientDocument
                    {
                        Patients = patient,
                        EntityDocuments = document,
                        TagName = document.TagName
                    };

                    if (existingDoc != null)
                    {
                        existingDoc.EntityDocuments = document; // Update reference
                        await _patientDocumentRepository.UpdateAsync(existingDoc);
                    }
                    else
                    {
                        patientDocuments.Add(patientDocument);
                    }
                }

                // Batch insert new patient documents
                if (patientDocuments.Any())
                {
                    await _patientDocumentRepository.InsertManyAsync(patientDocuments);
                }
                uniqueid.Clear();
                return savedDocuments;
            }
            catch (Exception ex)
            {
                uniqueid.Clear();
                throw new Exception($"Error saving files for patient {patient.Id}: {ex.Message}", ex);
            }
        }


        #endregion
    }
}
