using System.Text.Json; using khmereid_backend.Dtos; using khmereid_backend.Integrations; namespace khmereid_backend.Services; public class AuthService( IAuthnApi authnApi, ILogger logger, UserService userService) { private readonly UserService _userService = userService; private readonly ILogger _logger = logger; private readonly IAuthnApi _authnApi = authnApi; public async Task> StartRegistrationAsync(string phone) { if (await _userService.IsUserExistsAsync(phone)) { _logger.LogWarning("User {Phone} already exists", phone); return ApiResponse.Fail("User already exists."); } _logger.LogInformation("Starting OTP registration for phone {Phone}", phone); var result = await _authnApi.CreateOtpRegistrationFlowAsync(phone); return ApiResponse.Ok(result, "OTP sent if the phone number is valid."); } public async Task> CompleteRegistrationAsync(string flowId, string phone, string otp) { var data = await _authnApi.CompleteOtpRegistrationFlowAsync(otp, phone, flowId); if (data.Error != null) return ApiResponse.Fail(data.Message ?? "Registration failed.", null, data.Code); var user = await _userService.CreateUserAsync(phone, (Guid)data.IdentityId!); return ApiResponse.Ok(data, "Registration completed successfully."); } public async Task> StartLoginAsync(string phone) { _logger.LogInformation("Starting OTP login for phone {Phone}", phone); var data = await _authnApi.CreateOtpLoginFlowAsync(phone); if (data.Error != null) return ApiResponse.Fail(data.Message ?? "Request failed.", null, data.Code); return ApiResponse.Ok(data, "Request completed successfully."); } public async Task> CompleteLoginAsync(string flowId, string phone, string otp) { _logger.LogInformation("Completing OTP login for phone {Phone}, Flow: {FlowId}", phone, flowId); var data = await _authnApi.CompleteOtpLoginFlowAsync(flowId, phone, otp); if (data.Error != null) return ApiResponse.Fail(data.Message ?? "Login failed.", null, data.Code); return ApiResponse.Ok(data, "Login completed successfully."); } public async Task> LogoutAsync(string sessionToken) { _logger.LogInformation("Logging out session token {Token}", sessionToken); await _authnApi.Logout(sessionToken); return ApiResponse.Ok("Logout completed successfully."); } public async Task> GetMeAsync(string sessionToken) { try { _logger.LogInformation("Fetching current session for token {Token}", sessionToken); var response = await _authnApi.GetMeAsync(sessionToken); if (response.Error != null) return ApiResponse.Fail(response.Message ?? "Failed."); return ApiResponse.Ok(response, "Session returned."); } catch (UnauthorizedAccessException) { throw; } catch (Exception ex) { _logger.LogError(ex, "Failed to fetch session from Kratos"); throw; } } }