using Indotalent.ConfigFrontEnd.Service;
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Authentication.Identity;
using MediatR;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;

namespace Indotalent.Features.Account.Login.Cqrs;

public class LoginRequest
{
    public string Email { get; set; } = string.Empty;
    public string Password { get; set; } = string.Empty;
    public bool RememberMe { get; set; }
}

public class LoginResponse
{
    public bool Succeeded { get; set; }
    public string Message { get; set; } = string.Empty;
    public bool IsNotAllowed { get; set; }
    public string? Token { get; set; }
    public string? RefreshToken { get; set; }
}

public record LoginCommand(LoginRequest Data) : IRequest<LoginResponse>;

public class LoginHandler : IRequestHandler<LoginCommand, LoginResponse>
{
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly UserManager<ApplicationUser> _userManager;
    private readonly JwtSettingsModel _jwtSettings;

    public LoginHandler(
        SignInManager<ApplicationUser> signInManager,
        UserManager<ApplicationUser> userManager,
        IOptions<JwtSettingsModel> jwtSettings)
    {
        _signInManager = signInManager;
        _userManager = userManager;
        _jwtSettings = jwtSettings.Value;
    }

    public async Task<LoginResponse> Handle(LoginCommand request, CancellationToken cancellationToken)
    {
        var user = await _userManager.FindByEmailAsync(request.Data.Email);
        if (user == null) return new LoginResponse { Succeeded = false, Message = "Invalid credentials" };

        var result = await _signInManager.PasswordSignInAsync(user, request.Data.Password, request.Data.RememberMe, false);

        if (result.Succeeded)
        {
            var token = JwtService.GenerateNewJwt(user, _jwtSettings);

            var refreshToken = Guid.NewGuid().ToString().Replace("-", "");

            user.RefreshToken = refreshToken;
            user.LastLoginAt = DateTime.Now;
            await _userManager.UpdateAsync(user);

            return new LoginResponse
            {
                Succeeded = true,
                Message = "Login successful",
                Token = token,
                RefreshToken = refreshToken
            };
        }

        return new LoginResponse { Succeeded = false, Message = "Invalid credentials" };
    }


}