using System.Security.Cryptography;
using System.Text;
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MktXService.Infrastructure.ExternalServices.Twitter;

namespace MktXService.API.Controllers;

/// <summary>
/// EN: Controller for Twitter Webhook handling.
/// VI: Controller xử lý Twitter Webhook.
/// </summary>
[ApiController]
[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/webhooks/twitter")]
[Produces("application/json")]
public class WebhooksController : ControllerBase
{
    private readonly ITwitterApiClient _twitterClient;
    private readonly TwitterApiOptions _options;
    private readonly ILogger<WebhooksController> _logger;

    public WebhooksController(
        ITwitterApiClient twitterClient,
        IOptions<TwitterApiOptions> options,
        ILogger<WebhooksController> logger)
    {
        _twitterClient = twitterClient;
        _options = options.Value;
        _logger = logger;
    }

    /// <summary>
    /// EN: CRC token verification for Twitter webhook.
    /// VI: Xác thực CRC token cho Twitter webhook.
    /// </summary>
    [HttpGet]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public IActionResult VerifyCrcToken([FromQuery(Name = "crc_token")] string crcToken)
    {
        _logger.LogInformation("Received CRC challenge: {Token}", crcToken);

        var response = _twitterClient.GenerateCrcResponse(crcToken);
        
        return Ok(new { response_token = response });
    }

    /// <summary>
    /// EN: Receive Twitter webhook events.
    /// VI: Nhận events từ Twitter webhook.
    /// </summary>
    [HttpPost]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<IActionResult> ReceiveWebhookEvent([FromBody] TwitterWebhookPayload payload)
    {
        _logger.LogInformation("Received webhook event for user: {UserId}", payload.ForUserId);

        // EN: Process Direct Message events
        // VI: Xử lý events Direct Message
        if (payload.DirectMessageEvents?.Any() == true)
        {
            foreach (var dmEvent in payload.DirectMessageEvents)
            {
                _logger.LogInformation("Received DM from {SenderId}: {MessageId}",
                    dmEvent.MessageCreate?.SenderId, dmEvent.Id);

                // EN: In production, queue for async processing
                // VI: Trong production, đưa vào hàng đợi để xử lý bất đồng bộ
            }
        }

        // EN: Process follow events
        // VI: Xử lý events follow
        if (payload.FollowEvents?.Any() == true)
        {
            foreach (var followEvent in payload.FollowEvents)
            {
                _logger.LogInformation("New follower: {FollowerId}",
                    followEvent.Source?.Id);
            }
        }

        return Ok();
    }

    /// <summary>
    /// EN: Register webhook for an account.
    /// VI: Đăng ký webhook cho tài khoản.
    /// </summary>
    [HttpPost("register")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> RegisterWebhook([FromBody] RegisterWebhookRequest request)
    {
        try
        {
            var webhookId = await _twitterClient.RegisterWebhookAsync(request.WebhookUrl);
            return Ok(new { success = true, webhookId });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to register webhook");
            return BadRequest(new { success = false, error = ex.Message });
        }
    }

    /// <summary>
    /// EN: Subscribe to webhook events.
    /// VI: Đăng ký nhận webhook events.
    /// </summary>
    [HttpPost("subscribe")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    public async Task<IActionResult> SubscribeToWebhook()
    {
        try
        {
            await _twitterClient.SubscribeToWebhookAsync();
            return Ok(new { success = true, message = "Subscribed to webhook events" });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Failed to subscribe to webhook");
            return BadRequest(new { success = false, error = ex.Message });
        }
    }
}

#region Webhook DTOs

public class TwitterWebhookPayload
{
    public string? ForUserId { get; set; }
    public List<DirectMessageEvent>? DirectMessageEvents { get; set; }
    public List<FollowEvent>? FollowEvents { get; set; }
    public Dictionary<string, TwitterUserData>? Users { get; set; }
}

public class DirectMessageEvent
{
    public string? Id { get; set; }
    public string? Type { get; set; }
    public string? CreatedTimestamp { get; set; }
    public MessageCreate? MessageCreate { get; set; }
}

public class MessageCreate
{
    public string? SenderId { get; set; }
    public string? Target { get; set; }
    public MessageData? MessageData { get; set; }
}

public class MessageData
{
    public string? Text { get; set; }
    public List<object>? Entities { get; set; }
}

public class FollowEvent
{
    public string? Type { get; set; }
    public string? CreatedTimestamp { get; set; }
    public TwitterUserData? Source { get; set; }
    public TwitterUserData? Target { get; set; }
}

public class TwitterUserData
{
    public string? Id { get; set; }
    public string? Name { get; set; }
    public string? ScreenName { get; set; }
}

public record RegisterWebhookRequest(string WebhookUrl);

#endregion
