//Visitors
        public async Task <IdentifiedVisitor> CreateVisitorAsync(IdentifiedVisitor identifiedVisitor)
        {
            //TODO: Validate if the visitor exists
            identifiedVisitor.CreatedAt    = DateTime.UtcNow;
            identifiedVisitor.IsActive     = true;
            identifiedVisitor.IsDeleted    = false;
            identifiedVisitor.PartitionKey = string.IsNullOrEmpty(identifiedVisitor.PartitionKey) ? AppConstants.DbColIdentifiedVisitorPartitionKeyValue : identifiedVisitor.PartitionKey;
            identifiedVisitor.Id           = $"{Guid.NewGuid().ToString()}-{identifiedVisitor.PartitionKey}";
            var cognitivePerson = await FaceServiceHelper.CreatePersonAsync(identifiedVisitor.GroupId, identifiedVisitor.Name, identifiedVisitor.Id);

            identifiedVisitor.PersonDetails = cognitivePerson;
            double?age    = null;
            Gender?gender = null;

            foreach (var photo in identifiedVisitor.Photos)
            {
                if (!photo.IsSaved)
                {
                    photoData = photo.PhotoData;
                    var photoFileExtension = Path.GetExtension(photo.Name);
                    var newPhotoFileName   = $"{identifiedVisitor.Id}-{identifiedVisitor.Photos.IndexOf(photo) + 1}{photoFileExtension}";

                    //Only accept photos with single face
                    var detectedFaces = await FaceServiceHelper.DetectWithStreamAsync(GetPhotoStream, returnFaceAttributes : faceAttributes);

                    if (detectedFaces.Count == 0)
                    {
                        photo.Status = "Invalid: No faces detected in photo";
                        continue;
                    }
                    else if (detectedFaces.Count > 1)
                    {
                        photo.Status = "Invalid: More than 1 face detected in photo. Only photos with single face can be used to train";
                        continue;
                    }

                    //Upload the new photo to storage
                    photo.Url = await storageRepo.CreateFileAsync(newPhotoFileName, photo.PhotoData);

                    age    = detectedFaces[0].FaceAttributes.Age;
                    gender = detectedFaces[0].FaceAttributes.Gender;
                    var persistedFace = await AddVisitorPhotoAsync(identifiedVisitor.GroupId, cognitivePerson.PersonId, photo.Url, detectedFaces[0].FaceRectangle);

                    //Update photo details
                    photo.IsSaved = true;
                    photo.Name    = newPhotoFileName;
                    photo.Status  = "Saved";
                }
            }

            //Save the new identified visitor details to database
            identifiedVisitor.Age    = age.HasValue ? age.Value : 0;
            identifiedVisitor.Gender = gender.HasValue ? gender.ToString() : "NA";

            var result = await identifiedVisitorRepo.AddAsync(identifiedVisitor);

            return(result);
        }
        public async Task <IdentifiedVisitor> UpdateVisitorAsync(IdentifiedVisitor identifiedVisitor)
        {
            if (identifiedVisitor == null)
            {
                throw new InvalidDataException("No visitor data");
            }

            if (identifiedVisitor.Photos != null && identifiedVisitor.Photos.Count > 0)
            {
                double?age    = null;
                Gender?gender = null;

                foreach (var photo in identifiedVisitor.Photos)
                {
                    if (!photo.IsSaved)
                    {
                        photoData = photo.PhotoData;
                        var photoFileExtension = Path.GetExtension(photo.Name);
                        var newPhotoFileName   = $"{identifiedVisitor.Id}-{identifiedVisitor.Photos.IndexOf(photo) + 1}{photoFileExtension}";

                        //Only accept photos with single face
                        var detectedFaces = await FaceServiceHelper.DetectWithStreamAsync(GetPhotoStream, returnFaceAttributes : faceAttributes);

                        if (detectedFaces.Count == 0)
                        {
                            photo.Status = "Invalid: No faces detected in photo";
                            continue;
                        }
                        else if (detectedFaces.Count > 1)
                        {
                            photo.Status = "Invalid: More than 1 face detected in photo. Only photos with single face can be used to train";
                            continue;
                        }

                        //Upload the new photo to storage
                        photo.Url = await storageRepo.CreateFileAsync(newPhotoFileName, photo.PhotoData);

                        age    = detectedFaces[0].FaceAttributes.Age;
                        gender = detectedFaces[0].FaceAttributes.Gender;
                        var persistedFace = await AddVisitorPhotoAsync(identifiedVisitor.GroupId, identifiedVisitor.PersonDetails.PersonId, photo.Url, detectedFaces[0].FaceRectangle);

                        //Update photo details
                        photo.IsSaved = true;
                        photo.Name    = newPhotoFileName;
                        photo.Status  = "Saved";
                    }
                }
            }
            await identifiedVisitorRepo.UpdateAsync(identifiedVisitor);

            return(identifiedVisitor);
        }