using MemberCenter.Application.Abstractions;
using MemberCenter.Web.Models.Newsletter;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;

namespace MemberCenter.Web.Controllers;

public class NewsletterController : Controller
{
    private readonly INewsletterService _newsletterService;

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

    [HttpGet]
    public IActionResult Confirm(string token)
    {
        return View(new ConfirmViewModel { Token = token });
    }

    [HttpPost]
    public async Task<IActionResult> Confirm(ConfirmViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var subscription = await _newsletterService.ConfirmAsync(model.Token);
        if (subscription is null)
        {
            ViewData["Result"] = "Invalid or expired token.";
            return View("ConfirmResult");
        }

        ViewData["Result"] = "Subscription activated.";
        return View("ConfirmResult");
    }

    [HttpGet]
    public IActionResult Unsubscribe(string token)
    {
        return View(new UnsubscribeViewModel { Token = token });
    }

    [HttpPost]
    public async Task<IActionResult> Unsubscribe(UnsubscribeViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        var subscription = await _newsletterService.UnsubscribeAsync(model.Token);
        if (subscription is null)
        {
            ViewData["Result"] = "Invalid token.";
            return View("UnsubscribeResult");
        }

        ViewData["Result"] = "Subscription canceled.";
        return View("UnsubscribeResult");
    }

    [HttpGet]
    public async Task<IActionResult> Preferences([FromQuery(Name = "list_id")] Guid listId, [FromQuery] string email)
    {
        var subscription = await _newsletterService.GetPreferencesAsync(listId, email);
        if (subscription is null)
        {
            ViewData["Result"] = "Subscription not found.";
            return View("PreferencesResult");
        }

        return View(new PreferencesViewModel
        {
            ListId = listId,
            Email = email,
            PreferencesJson = subscription.Preferences.GetRawText()
        });
    }

    [HttpPost]
    public async Task<IActionResult> Preferences(PreferencesViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        Dictionary<string, object>? preferences = null;
        try
        {
            preferences = JsonSerializer.Deserialize<Dictionary<string, object>>(model.PreferencesJson);
        }
        catch
        {
            ModelState.AddModelError(string.Empty, "Invalid JSON.");
            return View(model);
        }

        var existing = await _newsletterService.GetPreferencesAsync(model.ListId, model.Email);
        if (existing is null)
        {
            ViewData["Result"] = "Subscription not found.";
            return View("PreferencesResult");
        }

        var subscription = await _newsletterService.UpdatePreferencesAsync(model.ListId, model.Email, preferences ?? new Dictionary<string, object>());
        if (subscription is null)
        {
            ViewData["Result"] = "Subscription not found.";
            return View("PreferencesResult");
        }

        ViewData["Result"] = "Preferences updated.";
        return View("PreferencesResult");
    }
}
