using System.Net.Http.Json;
using System.Text;
using AyCode.Interfaces.StorageHandlers;
using Newtonsoft.Json;
using TIAM.Entities.Users;
using TIAM.Models.Dtos.Users;
using TIAMWebApp.Shared.Application.Interfaces;
using TIAMWebApp.Shared.Application.Models;
using TIAMWebApp.Shared.Application.Models.ClientSide;
using TIAMWebApp.Shared.Application.Models.PageModels;

namespace TIAMMobileApp.Services
{
    public class UserDataServiceMobile : IUserDataService
    {
        private readonly HttpClient http;
        private readonly ISecureStorageHandler secureStorageHandler;        
        private readonly IServiceProviderDataService _serviceProviderDataService;

        public Dictionary<int, string> userRoleTypes { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public UserDataServiceMobile(HttpClient http, ISecureStorageHandler secureStorageHandler, IServiceProviderDataService serviceProviderDataService)
        {
            this.http = http;
            this.secureStorageHandler = secureStorageHandler;
            _serviceProviderDataService = serviceProviderDataService;
        }


        public List<RoleType> roleTypes = new List<RoleType>
    {
        new RoleType { Id = 1, RoleName = "Login" },
        new RoleType { Id = 2, RoleName = "Member" },
        new RoleType { Id = 4, RoleName = "Vip" },
        new RoleType { Id = 8, RoleName = "Uvip" },
        new RoleType { Id = 16, RoleName = "Volunteer" },
        new RoleType { Id = 32, RoleName = "Guide" },
        new RoleType { Id = 64, RoleName = "Protector" },
        new RoleType { Id = 128, RoleName = "Admin" },
        new RoleType { Id = 256, RoleName = "SuperAdmin" },
        new RoleType { Id = 512, RoleName = "God" }
    };


        public async Task<UserSessionModel> IsLoggedInAsync(Guid id)
        {
            var dbUser = await GetUserByIdAsync(id);

                if (dbUser != null)
                {

                    var hasProperties = await _serviceProviderDataService.GetPropertiesByOwnerIdAsync(dbUser.Id);
                    var user = new UserSessionModel(dbUser.Id, UserType.User, dbUser.Profile?.Name, hasProperties, 1);

                    return user;
                }
                else
                {
                    
                    return null;
                }
        }

        public async Task<string> TestUserApi(int Param)
        {
            var url = APIUrls.UserTest;
            var response = await http.PostAsJsonAsync(url, Param);
            var result = await response.Content.ReadAsStringAsync();
            return result;
        }

        public async Task<string> AuthenticateUser(LoginModel loginModel)
        {



            string result = string.Empty;
            var url = APIUrls.AuthenticateUser;

            var response = await http.PostAsJsonAsync(url, loginModel);

            if (response.IsSuccessStatusCode)
            {
                result = await response.Content.ReadAsStringAsync();
            }
            else
            {
                result = await response.Content.ReadAsStringAsync();
            }

            //result = await response.Content.ReadAsStringAsync();
            return result;


        }

        public async Task<(bool isSuccess, string ErrorMessage)> CreateUser(RegistrationModel regModel)
        {

            bool isSuccess = true;
            string result = string.Empty;
            var url = APIUrls.CreateUser;

            var response = await http.PostAsJsonAsync(url, regModel);
            result = await response.Content.ReadAsStringAsync();
            /*if (response.IsSuccessStatusCode)
            {
                isSuccess = true;
                result = await response.Content.ReadAsStringAsync();
            }
            else
            {
                isSuccess = false;
                result = await response.Content.ReadAsStringAsync();
            }*/


            return (isSuccess, result);
        }

        public async Task<IEnumerable<UserModelDto>?> GetUsersAsync()
        {
            return await http.GetFromJsonAsync<IEnumerable<UserModelDto>>(APIUrls.GetUsers);
        }

        public async Task<UserModelDto?> GetUserByEmailAsync(string email)
        {
            return await http.GetFromJsonAsync<UserModelDto?>(APIUrls.GetUserByEmail);
        }
        public async Task<User?> GetUserByIdAsync(Guid Id)
        {
            return await http.GetFromJsonAsync<User?>(APIUrls.GetUserById);
        }

        public async Task<bool> RefreshToken()
        {            
            bool isTokenRefreshed = false;
            using (var client = new HttpClient())
            {
                var url = APIUrls.RefreshToken;

                var serializedStr = JsonConvert.SerializeObject(new AuthenticateRequestAndResponse
                {
                    RefreshToken = Setting.UserBasicDetails.RefreshToken,
                    AccessToken = Setting.UserBasicDetails.AccessToken
                });

                try
                {
                    var response = await client.PostAsync(url, new StringContent(serializedStr, Encoding.UTF8, "application/json"));
                    if (response.IsSuccessStatusCode)
                    {
                        string contentStr = await response.Content.ReadAsStringAsync();
                        var mainResponse = JsonConvert.DeserializeObject<MainResponse>(contentStr);
                        if (mainResponse.IsSuccess)
                        {
                            var tokenDetails = JsonConvert.DeserializeObject<AuthenticateRequestAndResponse>(mainResponse.Content.ToString());
                            Setting.UserBasicDetails.AccessToken = tokenDetails.AccessToken;
                            Setting.UserBasicDetails.RefreshToken = tokenDetails.RefreshToken;

                            string userDetailsStr = JsonConvert.SerializeObject(Setting.UserBasicDetails);
                            await secureStorageHandler.SaveToSecureStorageAsync(nameof(Setting.UserBasicDetails), userDetailsStr);
                            isTokenRefreshed = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    string msg = ex.Message;
                }


            }
            return isTokenRefreshed;
        }


        public Task<Dictionary<int, string>> GetUserRolesAsync(UserModel userModel)
        {
            //TODO Finish this
            //get the userModel's roles
            int role = userModel.UserRoles;

            foreach (var roleType in roleTypes)
            {
                if ((role & roleType.Id) == roleType.Id)
                {

                    //add the role to the dictionary
                    userRoleTypes.Add(roleType.Id, roleType.RoleName);

                }
            }
            return Task.FromResult(userRoleTypes);

        }
    }
}

