using Managing.Api.Authorization;
using Managing.Api.Models.Requests;
using Managing.Application.Abstractions.Services;
using Managing.Domain.Users;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Managing.Api.Controllers;

/// <summary>
/// Provides authentication-related actions, including token creation for user authentication.
/// </summary>
[ApiController]
[Route("[controller]")]
[Produces("application/json")]
public class UserController : BaseController
{
    private IConfiguration _config;
    private readonly IJwtUtils _jwtUtils;
    private readonly IWebhookService _webhookService;

    /// <summary>
    /// Initializes a new instance of the <see cref="UserController"/> class.
    /// </summary>
    /// <param name="config">Configuration settings.</param>
    /// <param name="userService">Service for user-related operations.</param>
    /// <param name="jwtUtils">Utility for JWT token operations.</param>
    /// <param name="webhookService">Service for webhook operations.</param>
    public UserController(IConfiguration config, IUserService userService, IJwtUtils jwtUtils,
        IWebhookService webhookService)
        : base(userService)
    {
        _config = config;
        _jwtUtils = jwtUtils;
        _webhookService = webhookService;
    }

    /// <summary>
    /// Creates a JWT token for a user based on the provided login credentials.
    /// </summary>
    /// <param name="login">The login request containing user credentials.</param>
    /// <returns>A JWT token if authentication is successful; otherwise, an Unauthorized result.</returns>
    [AllowAnonymous]
    [HttpPost("create-token")]
    public async Task<ActionResult<string>> CreateToken([FromBody] LoginRequest login)
    {
        var user = await _userService.Authenticate(login.Name, login.Address, login.Message, login.Signature);

        if (user != null)
        {
            var tokenString = _jwtUtils.GenerateJwtToken(user, login.Address);
            return Ok(tokenString);
        }

        return Unauthorized();
    }

    /// <summary>
    /// Gets the current user's information.
    /// </summary>
    /// <returns>The current user's information.</returns>
    [Authorize]
    [HttpGet]
    public async Task<ActionResult<User>> GetCurrentUser()
    {
        var user = await base.GetUser();
        user = await _userService.GetUserByName(user.Name);
        return Ok(user);
    }

    /// <summary>
    /// Updates the agent name for the current user.
    /// </summary>
    /// <param name="agentName">The new agent name to set.</param>
    /// <returns>The updated user with the new agent name.</returns>
    [Authorize]
    [HttpPut("agent-name")]
    public async Task<ActionResult<User>> UpdateAgentName([FromBody] string agentName)
    {
        var user = await GetUser();
        var updatedUser = await _userService.UpdateAgentName(user, agentName);
        return Ok(updatedUser);
    }

    /// <summary>
    /// Updates the avatar URL for the current user.
    /// </summary>
    /// <param name="avatarUrl">The new avatar URL to set.</param>
    /// <returns>The updated user with the new avatar URL.</returns>
    [Authorize]
    [HttpPut("avatar")]
    public async Task<ActionResult<User>> UpdateAvatarUrl([FromBody] string avatarUrl)
    {
        var user = await GetUser();
        var updatedUser = await _userService.UpdateAvatarUrl(user, avatarUrl);
        return Ok(updatedUser);
    }

    /// <summary>
    /// Updates the Telegram channel for the current user.
    /// </summary>
    /// <param name="telegramChannel">The new Telegram channel to set.</param>
    /// <returns>The updated user with the new Telegram channel.</returns>
    [Authorize]
    [HttpPut("telegram-channel")]
    public async Task<ActionResult<User>> UpdateTelegramChannel([FromBody] string telegramChannel)
    {
        var user = await GetUser();
        var updatedUser = await _userService.UpdateTelegramChannel(user, telegramChannel);

        // Send welcome message to the newly configured telegram channel
        if (!string.IsNullOrEmpty(telegramChannel))
        {
            try
            {
                var welcomeMessage = $"🎉 **Trading Bot - Welcome!**\n\n" +
                                     $"🎯 **Agent:** {user.Name}\n" +
                                     $"📡 **Channel ID:** {telegramChannel}\n" +
                                     $"⏰ **Setup Time:** {DateTime.UtcNow:MMM dd, yyyy • HH:mm:ss} UTC\n\n" +
                                     $"🔔 **Notification Types:**\n" +
                                     $"• 📈 Position Opens & Closes\n" +
                                     $"• 🤖 Bot configuration changes\n\n" +
                                     $"🚀 **Welcome aboard!** Your trading notifications are now live.";

                await _webhookService.SendMessage(welcomeMessage, telegramChannel);
            }
            catch (Exception ex)
            {
                // Log the error but don't fail the update operation
                Console.WriteLine(
                    $"Failed to send welcome message to telegram channel {telegramChannel}: {ex.Message}");
            }
        }

        return Ok(updatedUser);
    }

    /// <summary>
    /// Tests the Telegram channel configuration by sending a test message.
    /// </summary>
    /// <returns>A message indicating the test result.</returns>
    [Authorize]
    [HttpPost("telegram-channel/test")]
    public async Task<ActionResult<string>> 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}");
        }
    }
}