using BBM.ChatGLM.Dtos;
using Lion.AbpPro.BasicManagement.Roles;
using Lion.AbpPro.BasicManagement.Users;
using NetTopologySuite.Mathematics;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
using System.Text.Json;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Identity;

namespace BBM.ChatGLM.User
{
    [Authorize]
    public class UsersAppService : ChatGLMAppService, IUsersAppService
    {
        private readonly IdentityUserManager _userManager;
        private readonly IUserAppService _userAppService;
        private readonly UsersManager _usersManager;
        private readonly IRoleAppService _roleAppService;
        private readonly IConfiguration _configuration;
        public UsersAppService(IdentityUserManager userManager, IUserAppService userAppService, UsersManager usersManager, IConfiguration configuration)
        {
            _userManager = userManager;
            _userAppService = userAppService;
            _usersManager = usersManager;
            _configuration = configuration;
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Query)]
        public async Task<PagedResultDto<UserDto>> PageAsync(UserPageInput input)
        {
            var result = new PagedResultDto<UserDto>
            {
                TotalCount = await _usersManager.CountAsync(input.Name, input.Enabled)
            };
            result.Items = await _usersManager.PageAsync(input.Name, input.PageSize, input.PageIndex, input.Enabled);
            return result;
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Create)]
        public async Task<IdentityUserDto> CreateAsync(UserCreateInput input)
        {
            var identityUser = new IdentityUserCreateDto
            {
                UserName = input.UserName,
                Password = input.Password,
                Name = input.Name,
                RoleNames = new string[] { input.Role },
                Email = "zs@baibaomen.com"
            };
            return await _userAppService.CreateAsync(identityUser);
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Update)]
        public async Task<IdentityUserDto> UpdateAsync(UserUpdateInput input)
        {
            var user = await _userManager.GetByIdAsync(input.Id);
            await _userManager.SetRolesAsync(user, new string[] { input.Role });

            var u = await _userManager.FindByIdAsync(input.Id.ToString());
            u.Name = input.Name;
            u.SetIsActive(input.IsActive);
            await _userManager.UpdateAsync(u);

            return ObjectMapper.Map<IdentityUser, IdentityUserDto>(user);
        }

        [Authorize(ChatGLMPermissions.UsersManagement.ResetPassword)]
        public async Task<bool> ResetPasswordAsync(UserResetPasswordInput input)
        {
            var user = await _userManager.GetByIdAsync(input.Id);
            var token = await _userManager.GeneratePasswordResetTokenAsync(user);
            var result = await _userManager.ResetPasswordAsync(user, token, input.Password);
            return result.Succeeded;
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Delete)]
        public async Task<bool> DeleteAsync(GuidIdInput input)
        {
            var user = await _userManager.FindByIdAsync(input.Id.ToString());
            if (user == null)
            {
                return false;
            }
            user.IsDeleted = true;
            var result = await _userManager.UpdateAsync(user);
            return result.Succeeded;
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Query)]
        public async Task<List<string>> GetRolesAsync()
        {
            var user = CurrentUser.Name;
            var roles = await _usersManager.GetRolesAsync();
            return roles.WhereIf(user == "admin", item => item.Name != "admin").Select(role => role.Name).ToList();
        }

        [Authorize(ChatGLMPermissions.UsersManagement.Chat)]
        public async Task<string> GetTokenAsync()
        {
            var client = new HttpClient();
            var apiKey = _configuration.GetValue<string>("App:ApiKey");
            var url = $"https://glm-api.baibaomen.com/token?appkey={apiKey}";
            try
            {
                var response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    var data = JsonSerializer.Deserialize<TokenObject>(content);
                    return data.token;
                }
                else
                {
                    throw new BusinessException("BBM.ChatGLM:100012");
                }
            }
            catch
            {
                throw new BusinessException("BBM.ChatGLM:100012");
            }
        }
    }
}
