using Microsoft.Graph; using System.Collections.Generic; using vendorApproverBackend.Dtos; using System.Threading.Tasks; namespace vendorApproverBackend.Services { public class AzureContactsService { private readonly IConfiguration _config; private readonly HttpClient _httpClient; public AzureContactsService(IConfiguration config, HttpClient httpClient) { _config = config; _httpClient = httpClient; } // Initialize Graph Client using user's access token private GraphServiceClient InitializeGraphClientWithUserToken(string userAccessToken) { // Add the authorization header to the HttpClient _httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", userAccessToken); // Create GraphServiceClient with the HttpClient that has the bearer token return new GraphServiceClient(_httpClient); } // Get all contacts for the logged-in user using their access token public async Task> GetUserContactsAsync(string userAccessToken) { try { if (string.IsNullOrEmpty(userAccessToken)) { throw new ArgumentException("User access token is required"); } var graphClient = InitializeGraphClientWithUserToken(userAccessToken); var contacts = await graphClient.Me.Contacts .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Top = 100; }); var contactList = new List(); if (contacts?.Value != null) { foreach (var contact in contacts.Value) { contactList.Add(MapContactToDto(contact)); } } // Handle pagination if there are more contacts while (contacts?.OdataNextLink != null) { var nextPage = await graphClient.Me.Contacts .WithUrl(contacts.OdataNextLink) .GetAsync(); if (nextPage?.Value != null) { foreach (var contact in nextPage.Value) { contactList.Add(MapContactToDto(contact)); } } contacts = nextPage; } return contactList; } catch (Exception ex) { throw new Exception($"Error fetching contacts: {ex.Message}", ex); } } // Search contacts by name or email using user's access token public async Task> SearchContactsAsync(string userAccessToken, string searchTerm) { try { if (string.IsNullOrEmpty(userAccessToken)) { throw new ArgumentException("User access token is required"); } var graphClient = InitializeGraphClientWithUserToken(userAccessToken); var contacts = await graphClient.Me.Contacts .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Filter = $"startsWith(displayName, '{EscapeFilterValue(searchTerm)}') or startsWith(emailAddresses/any(a:a/address), '{EscapeFilterValue(searchTerm)}')"; requestConfiguration.QueryParameters.Top = 50; }); var contactList = new List(); if (contacts?.Value != null) { foreach (var contact in contacts.Value) { contactList.Add(MapContactToDto(contact)); } } return contactList; } catch (Exception ex) { throw new Exception($"Error searching contacts: {ex.Message}", ex); } } // Get user's profile information using their access token public async Task GetUserProfileAsync(string userAccessToken) { try { if (string.IsNullOrEmpty(userAccessToken)) { throw new ArgumentException("User access token is required"); } var graphClient = InitializeGraphClientWithUserToken(userAccessToken); var user = await graphClient.Me.GetAsync(); return new AzureUserProfileDto { Id = user.Id, DisplayName = user.DisplayName, Mail = user.Mail, UserPrincipalName = user.UserPrincipalName, JobTitle = user.JobTitle, Department = user.Department, MobilePhone = user.MobilePhone }; } catch (Exception ex) { throw new Exception($"Error fetching user profile: {ex.Message}", ex); } } // Map Contact object to DTO private AzureContactDto MapContactToDto(Microsoft.Graph.Models.Contact contact) { return new AzureContactDto { Id = contact.Id, DisplayName = contact.DisplayName, GivenName = contact.GivenName, Surname = contact.Surname, Email = contact.EmailAddresses?.FirstOrDefault()?.Address ?? string.Empty, Phone = contact.BusinessPhones?.FirstOrDefault() ?? string.Empty, JobTitle = contact.JobTitle, Department = contact.Department, Company = contact.CompanyName }; } // Escape special characters in filter values private string EscapeFilterValue(string value) { if (string.IsNullOrEmpty(value)) return string.Empty; return value.Replace("'", "''"); } } }