using MemberCenter.Api.Contracts;
using MemberCenter.Application.Abstractions;
using Microsoft.AspNetCore.Mvc;

namespace MemberCenter.Api.Controllers;

[ApiController]
[Route("newsletter")]
public class NewsletterController : ControllerBase
{
    private readonly INewsletterService _newsletterService;

    public NewsletterController(INewsletterService newsletterService)
    {
        _newsletterService = newsletterService;
    }

    [HttpPost("subscribe")]
    public async Task<IActionResult> Subscribe([FromBody] SubscribeRequest request)
    {
        var result = await _newsletterService.SubscribeAsync(request.ListId, request.Email, request.Preferences);
        if (result is null)
        {
            return NotFound("List not found.");
        }

        return Ok(new
        {
            id = result.Subscription.Id,
            list_id = result.Subscription.ListId,
            email = result.Subscription.Email,
            status = result.Subscription.Status,
            created_at = result.Subscription.CreatedAt,
            confirm_token = result.ConfirmToken
        });
    }

    [HttpGet("confirm")]
    public async Task<IActionResult> Confirm([FromQuery] string token)
    {
        var subscription = await _newsletterService.ConfirmAsync(token);
        if (subscription is null)
        {
            return NotFound("Invalid token.");
        }

        return Ok(new
        {
            id = subscription.Id,
            list_id = subscription.ListId,
            email = subscription.Email,
            status = subscription.Status,
            created_at = subscription.CreatedAt
        });
    }

    [HttpPost("unsubscribe")]
    public async Task<IActionResult> Unsubscribe([FromBody] UnsubscribeRequest request)
    {
        var subscription = await _newsletterService.UnsubscribeAsync(request.Token);
        if (subscription is null)
        {
            return NotFound("Invalid token.");
        }

        return Ok(new
        {
            id = subscription.Id,
            list_id = subscription.ListId,
            email = subscription.Email,
            status = subscription.Status,
            created_at = subscription.CreatedAt
        });
    }

    [HttpPost("unsubscribe-token")]
    public async Task<IActionResult> IssueUnsubscribeToken([FromBody] IssueUnsubscribeTokenRequest request)
    {
        if (request.ListId == Guid.Empty || string.IsNullOrWhiteSpace(request.Email))
        {
            return BadRequest("Both list_id and email are required.");
        }

        var token = await _newsletterService.IssueUnsubscribeTokenAsync(request.ListId, request.Email);
        if (token is null)
        {
            return NotFound("Subscription not found.");
        }

        return Ok(new
        {
            unsubscribe_token = token
        });
    }

    [HttpGet("preferences")]
    public async Task<IActionResult> Preferences([FromQuery(Name = "list_id")] Guid? listId, [FromQuery] string? email)
    {
        if (!listId.HasValue || listId.Value == Guid.Empty || string.IsNullOrWhiteSpace(email))
        {
            return BadRequest("Both list_id and email are required.");
        }

        var subscription = await _newsletterService.GetPreferencesAsync(listId.Value, email);
        if (subscription is null)
        {
            return NotFound("Subscription not found.");
        }

        return Ok(new
        {
            id = subscription.Id,
            list_id = subscription.ListId,
            email = subscription.Email,
            status = subscription.Status,
            preferences = subscription.Preferences
        });
    }

    [HttpPost("preferences")]
    public async Task<IActionResult> UpdatePreferences([FromBody] UpdatePreferencesRequest request)
    {
        if (request.ListId == Guid.Empty || string.IsNullOrWhiteSpace(request.Email))
        {
            return BadRequest("Both list_id and email are required.");
        }

        var subscription = await _newsletterService.UpdatePreferencesAsync(request.ListId, request.Email, request.Preferences);
        if (subscription is null)
        {
            return NotFound("Subscription not found.");
        }

        return Ok(new
        {
            id = subscription.Id,
            list_id = subscription.ListId,
            email = subscription.Email,
            status = subscription.Status,
            preferences = subscription.Preferences
        });
    }
}
