using Amazon.SimpleSystemsManagement.Model;
using Amazon.SimpleSystemsManagement;
using DataBase.Entities.Models;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using MySqlConnector;
using Serilog;
using System.Data;
using System.Diagnostics.CodeAnalysis;
using User.Insight.Tracker.Common;
using Amazon;
using User.Insight.Tracker.DataProviders;

namespace User.Insight.Tracker.Services
{
    [ExcludeFromCodeCoverage]
    public class AzureSyncingService : IAzureSyncingService
    {
        private readonly IConfiguration _configuration;
        public readonly string _connectionString;
        public static IHostEnvironment HostEnvironment { get; private set; }
        private readonly IAzureSyncingServiceProvider _azureServiceProvider;
        [ExcludeFromCodeCoverage]
        public AzureSyncingService(IConfiguration configuration, IHostEnvironment hostEnvironment, IAzureSyncingServiceProvider azureSyncingService)
        {
            this._configuration = configuration;
            this._connectionString = this._configuration.GetConnectionString("DefaultConnection");
            HostEnvironment = hostEnvironment;
            _azureServiceProvider = azureSyncingService;
        }

        [ExcludeFromCodeCoverage]
        public void AzureADReadService()
        {
            var parameterService = new AwsParameterStoreService();
            string tenantId, clientId, clientSecret;

            // Pick values either from appsettings.json or from AWS Parameter Store
            if (HostEnvironment?.IsDevelopment() == true)
            {
                clientId = _configuration["AzureAd:ClientId"];
                clientSecret = _configuration["AzureAd:ClientSecret"];
                tenantId = _configuration["AzureAd:TenantId"];
            }
            else
            {
                tenantId = parameterService.GetParameterValueAsync("/prod/userinsighttracking/AzureAd/TenantId").Result;
                clientId = parameterService.GetParameterValueAsync("/prod/userinsighttracking/AzureAd/ClientId").Result;
                clientSecret = parameterService.GetParameterValueAsync("/prod/userinsighttracking/AzureAd/ClientSecret").Result;
            }

            // Pass values to get authenticated Graph client
            GraphServiceClient graphClient = GetAuthenticatedGraphClient(tenantId, clientId, clientSecret);

            List<UserModels> objUserList = new List<UserModels>();
            List<UserModels> objAssignedLicensesUserList = new List<UserModels>();

            List<QueryOption> options = new List<QueryOption>
            {
                new QueryOption("$filter", "accountEnabled eq true and UserType eq 'Member'")
            };

            var users = new List<Microsoft.Graph.User>();
            var pageRequest = graphClient.Users
                .Request(options)
                .Select("UserPrincipalName,ID,Manager,department,Country,Company,DisplayName,AccountEnabled,UsageLocation,AssignedLicenses,UserType,Surname,Grade,GivenName,BusinessPhones,Mail,EmployeeId,OnPremisesSamAccountName,jobTitle,usageLocation,officeLocation,userType,employeeHireDate,employeeType")
                .Expand("manager")
                .Top(200);

            while (true)
            {
                var response = pageRequest.GetAsync();
                users.AddRange(response.Result.CurrentPage);

                if (response.Result.NextPageRequest == null)
                {
                    break;
                }
                pageRequest = response.Result.NextPageRequest;
            }

            foreach (var item in users)
            {
                string strManager = string.Empty;
                var managerEmail = item.Manager;

                if (managerEmail != null)
                {
                    var manager = graphClient.Users[managerEmail.Id].Request().GetAsync();
                    strManager = manager.Result.Mail;
                }

                var objUser = new UserModels
                {
                    Manager = strManager,
                    Email = item.UserPrincipalName,
                    FirstName = item.GivenName,
                    LastName = item.Surname,
                    Department = item.Department,
                    Country = item.Country,
                    DisplayName = item.DisplayName,
                    UserType = item.UserType,
                    EmployeeId = item.EmployeeId,
                    JobTitle = item.JobTitle,
                    OfficeLocation = item.OfficeLocation,
                    PremisesSamAccountName = item.OnPremisesSamAccountName,
                };
                objUserList.Add(objUser);
                objAssignedLicensesUserList.Add(objUser);

            }

            foreach (var item in objUserList)
            {
                if (!string.IsNullOrEmpty(item.EmployeeId))
                {
                    _ = _azureServiceProvider.InsertActiveUser(item);

                }
            }
        }
        [ExcludeFromCodeCoverage]
        private static GraphServiceClient GetAuthenticatedGraphClient(string tenantId, string clientId, string clientSecret)
        {
            var authenticationProvider = CreateAuthorizationProvider(tenantId, clientId, clientSecret);
            var _graphServiceClient = new GraphServiceClient(authenticationProvider);
            return _graphServiceClient;
        }
        [ExcludeFromCodeCoverage]
        private static IAuthenticationProvider CreateAuthorizationProvider(string tenantId, string clientId, string clientSecret)
        {
            var authority = $"https://login.microsoftonline.com/{tenantId}/v2.0";
            List<string> scopes = new List<string> { "https://graph.microsoft.com/.default" };

            var cca = ConfidentialClientApplicationBuilder.Create(clientId)
                                                          .WithAuthority(authority)
                                                          .WithClientSecret(clientSecret)
                                                          .Build();
            return new MsalAuthenticationProvider(cca, scopes.ToArray());
        }


        [ExcludeFromCodeCoverage]
        public class AwsParameterStoreService
        {
            private readonly IAmazonSimpleSystemsManagement _ssmClient;

            public AwsParameterStoreService()
            {
                _ssmClient = new AmazonSimpleSystemsManagementClient(RegionEndpoint.APSouth1); // Change region as per your setup
            }

            public async Task<string> GetParameterValueAsync(string parameterKey)
            {
                try
                {
                    var request = new GetParameterRequest
                    {
                        Name = parameterKey,
                        WithDecryption = true
                    };

                    var response = await _ssmClient.GetParameterAsync(request);
                    return response.Parameter.Value;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error fetching parameter {parameterKey}: {ex.Message}");
                    return null;
                }
            }
        }
    }
}
