using Managing.Api.Authorization; using Managing.Api.Models.Requests; using Managing.Application.Abstractions.Models; using Managing.Application.Abstractions.Services; using Managing.Application.ManageBot.Commands; using Managing.Domain.Users; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; namespace Managing.Api.Controllers; /// /// Provides authentication-related actions, including token creation for user authentication. /// [ApiController] [Route("[controller]")] [Produces("application/json")] public class UserController : BaseController { private IConfiguration _config; private readonly IJwtUtils _jwtUtils; private readonly IWebhookService _webhookService; private readonly IMediator _mediator; /// /// Initializes a new instance of the class. /// /// Configuration settings. /// Service for user-related operations. /// Utility for JWT token operations. /// Service for webhook operations. /// Mediator for handling commands. public UserController(IConfiguration config, IUserService userService, IJwtUtils jwtUtils, IWebhookService webhookService, IMediator mediator) : base(userService) { _config = config; _jwtUtils = jwtUtils; _webhookService = webhookService; _mediator = mediator; } /// /// Creates a JWT token for a user based on the provided login credentials. /// /// The login request containing user credentials. /// A JWT token if authentication is successful; otherwise, an Unauthorized result. [AllowAnonymous] [HttpPost("create-token")] public async Task> CreateToken([FromBody] LoginRequest login) { var user = await _userService.Authenticate(login.Name, login.Address, login.Message, login.Signature, login.OwnerWalletAddress); if (user != null) { var tokenString = _jwtUtils.GenerateJwtToken(user, login.Address); return Ok(tokenString); } return Unauthorized(); } /// /// Gets the current user's information. /// /// The current user's information. [Authorize] [HttpGet] public async Task> GetCurrentUser() { var user = await base.GetUser(); return Ok(user); } /// /// Updates the agent name for the current user. /// /// The new agent name to set. /// The updated user with the new agent name. [Authorize] [HttpPut("agent-name")] public async Task> UpdateAgentName([FromBody] string agentName) { var user = await GetUser(); var updatedUser = await _userService.UpdateAgentName(user, agentName); return Ok(updatedUser); } /// /// Updates the avatar URL for the current user. /// /// The new avatar URL to set. /// The updated user with the new avatar URL. [Authorize] [HttpPut("avatar")] public async Task> UpdateAvatarUrl([FromBody] string avatarUrl) { var user = await GetUser(); var updatedUser = await _userService.UpdateAvatarUrl(user, avatarUrl); return Ok(updatedUser); } /// /// Updates the Telegram channel for the current user. /// /// The new Telegram channel to set. /// The updated user with the new Telegram channel. [Authorize] [HttpPut("telegram-channel")] public async Task> UpdateTelegramChannel([FromBody] string telegramChannel) { var user = await GetUser(); var updatedUser = await _userService.UpdateTelegramChannel(user, telegramChannel); return Ok(updatedUser); } /// /// Tests the Telegram channel configuration by sending a test message. /// /// A message indicating the test result. [Authorize] [HttpPost("telegram-channel/test")] public async Task> TestTelegramChannel() { var user = await GetUser(); if (string.IsNullOrEmpty(user.TelegramChannel)) { return BadRequest("No Telegram channel configured for this user. Please set a Telegram channel first."); } try { var testMessage = $"🚀 **Trading Bot - Channel Test**\n\n" + $"🎯 **Agent:** {user.Name}\n" + $"📡 **Channel ID:** {user.TelegramChannel}\n" + $"⏰ **Test Time:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" + $"🔔 **You will receive notifications for:**\n" + $"• 📈 Position Opens & Closes\n" + $"• 🤖 Bot configuration changes\n\n" + $"🎉 **Ready to trade!** Your notifications are now active."; await _webhookService.SendMessage(testMessage, user.TelegramChannel); return Ok( $"Test message sent successfully to Telegram channel {user.TelegramChannel}. Please check your Telegram to verify delivery."); } catch (Exception ex) { return StatusCode(500, $"Failed to send test message: {ex.Message}"); } } /// /// Updates the user settings for the current user. /// /// The user settings to update. /// The updated user with the new settings. [Authorize] [HttpPut("settings")] public async Task> UpdateUserSettings([FromBody] UpdateUserSettingsRequest settings) { var user = await GetUser(); // Map API request to DTO // Note: IsGmxEnabled and DefaultExchange are not updatable via settings endpoint var settingsDto = new UserSettingsDto { LowEthAmountAlert = settings.LowEthAmountAlert, EnableAutoswap = settings.EnableAutoswap, AutoswapAmount = settings.AutoswapAmount, MaxWaitingTimeForPositionToGetFilledSeconds = settings.MaxWaitingTimeForPositionToGetFilledSeconds, MaxTxnGasFeePerPosition = settings.MaxTxnGasFeePerPosition, GmxSlippage = settings.GmxSlippage, MinimumConfidence = settings.MinimumConfidence, TrendStrongAgreementThreshold = settings.TrendStrongAgreementThreshold, SignalAgreementThreshold = settings.SignalAgreementThreshold, AllowSignalTrendOverride = settings.AllowSignalTrendOverride }; var updatedUser = await _userService.UpdateUserSettings(user, settingsDto); return Ok(updatedUser); } /// /// Updates the agent summary by refreshing balance data and recalculating metrics. /// Should be called after a topup/deposit to ensure the balance is up to date. /// /// Success response. [HttpPost("update-agent-summary")] public async Task UpdateAgentSummary() { var user = await GetUser(); await _mediator.Send(new UpdateAgentSummaryCommand(user)); return Ok(new { message = "Agent summary updated successfully" }); } }