using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Authorization.Identity;
using MediatR;
using Microsoft.AspNetCore.Identity;

namespace Indotalent.Features.Setting.SystemUser.Cqrs;

public class CreateSystemUserRequest
{
    public string? FullName { get; set; }
    public string? Email { get; set; }
    public string? Password { get; set; }
    public string? PhoneNumber { get; set; }
    public string? UserName { get; set; }
    public bool EmailConfirmed { get; set; }
    public bool PhoneNumberConfirmed { get; set; }
    public bool TwoFactorEnabled { get; set; }
    public bool IsActive { get; set; }
    public bool LockoutEnabled { get; set; }
    public DateTimeOffset? LockoutEnd { get; set; }
    public string? SsoIdFirebase { get; set; }
    public string? SsoIdKeycloak { get; set; }
    public string? SsoIdAzure { get; set; }
    public string? SsoIdAws { get; set; }
    public string? SsoIdOther1 { get; set; }
    public string? SsoIdOther2 { get; set; }
    public string? SsoIdOther3 { get; set; }
}

public class CreateSystemUserResponse
{
    public string? Id { get; set; }
    public string? Email { get; set; }
}

public record CreateSystemUserCommand(CreateSystemUserRequest Data) : IRequest<CreateSystemUserResponse>;

public class CreateSystemUserHandler : IRequestHandler<CreateSystemUserCommand, CreateSystemUserResponse>
{
    private readonly UserManager<ApplicationUser> _userManager;
    public CreateSystemUserHandler(UserManager<ApplicationUser> userManager) => _userManager = userManager;

    public async Task<CreateSystemUserResponse> Handle(CreateSystemUserCommand request, CancellationToken cancellationToken)
    {
        var user = new ApplicationUser
        {
            FullName = request.Data.FullName,
            Email = request.Data.Email,
            UserName = request.Data.Email,
            PhoneNumber = request.Data.PhoneNumber,
            EmailConfirmed = request.Data.EmailConfirmed,
            PhoneNumberConfirmed = request.Data.PhoneNumberConfirmed,
            TwoFactorEnabled = request.Data.TwoFactorEnabled,
            IsActive = request.Data.IsActive,
            LockoutEnabled = request.Data.LockoutEnabled,
            LockoutEnd = request.Data.LockoutEnd,
            SsoIdFirebase = request.Data.SsoIdFirebase,
            SsoIdKeycloak = request.Data.SsoIdKeycloak,
            SsoIdAzure = request.Data.SsoIdAzure,
            SsoIdAws = request.Data.SsoIdAws,
            SsoIdOther1 = request.Data.SsoIdOther1,
            SsoIdOther2 = request.Data.SsoIdOther2,
            SsoIdOther3 = request.Data.SsoIdOther3,
            CreatedAt = DateTime.Now
        };

        var result = await _userManager.CreateAsync(user, request.Data.Password ?? "123456");

        if (!result.Succeeded)
        {
            var errors = string.Join(", ", result.Errors.Select(e => e.Description));
            throw new Exception(errors);
        }

        var rolesToAdd = ApplicationRoles.AllRoles
            .Where(role => role != ApplicationRoles.Admin)
            .ToList();

        if (rolesToAdd.Any())
        {
            await _userManager.AddToRolesAsync(user, rolesToAdd);
        }

        return new CreateSystemUserResponse { Id = user.Id, Email = user.Email };
    }
}