using Aberwyn.Data;
using Aberwyn.Models;
using Lib.Net.Http.WebPush;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Identity;
using Aberwyn.Services;


namespace Aberwyn.Controllers
{
    [ApiController]
    [Route("api/push")]
    public class PushController : ControllerBase
    {
        private readonly ApplicationDbContext _context;
        private readonly PushNotificationService _notificationService;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly PizzaNotificationService _pizzaNotifier;


        public PushController(ApplicationDbContext context,
                            PushNotificationService notificationService,
                            UserManager<ApplicationUser> userManager,
                            PizzaNotificationService pizzaNotifier)
        {
            _context = context;
            _notificationService = notificationService;
            _userManager = userManager;
            _pizzaNotifier = pizzaNotifier;
        }

            [HttpPost("notify-pizza")]
            public async Task<IActionResult> NotifyPizza()
            {
                var count = await _pizzaNotifier.NotifyPizzaSubscribersAsync("Capricciosa", User.Identity.Name);

                return Ok(new { message = $"Skickade pizzanotiser till {count} användare." });
            }

        [HttpPost("subscribe-user")]
        public async Task<IActionResult> SubscribeUser([FromBody] PushSubscription subscription)
        {
            var user = await _userManager.GetUserAsync(User);
            if (user == null) return Unauthorized();

            var existing = await _context.PushSubscribers
                .FirstOrDefaultAsync(s => s.Endpoint == subscription.Endpoint);

            if (existing == null)
            {
                var newSub = new PushSubscriber
                {
                    Endpoint = subscription.Endpoint,
                    P256DH = subscription.Keys["p256dh"],
                    Auth = subscription.Keys["auth"],
                    UserId = user.Id
                };
                _context.PushSubscribers.Add(newSub);
            }
            else
            {
                existing.P256DH = subscription.Keys["p256dh"];
                existing.Auth = subscription.Keys["auth"];
                existing.UserId = user.Id;
            }

            await _context.SaveChangesAsync();
            return Ok();
        }

        [HttpPost("subscribe")]
        public async Task<IActionResult> Subscribe([FromBody] PushSubscriptionWithOrder dto)
        {
            var existing = await _context.PushSubscribers
                .FirstOrDefaultAsync(s => s.Endpoint == dto.Subscription.Endpoint);

            if (existing == null)
            {
                var newSub = new PushSubscriber
                {
                    Endpoint = dto.Subscription.Endpoint,
                    P256DH = dto.Subscription.Keys["p256dh"],
                    Auth = dto.Subscription.Keys["auth"],
                    PizzaOrderId = dto.PizzaOrderId
                };
                _context.PushSubscribers.Add(newSub);
            }
            else
            {
                existing.P256DH = dto.Subscription.Keys["p256dh"];
                existing.Auth = dto.Subscription.Keys["auth"];
                existing.PizzaOrderId = dto.PizzaOrderId; // uppdatera kopplingen
            }

            await _context.SaveChangesAsync();
            return Ok();
        }

        public class PushSubscriptionWithOrder
        {
            public PushSubscription Subscription { get; set; }
            public int PizzaOrderId { get; set; }
        }


        [HttpGet("vapid-public-key")]
        public IActionResult GetVapidKey([FromServices] IConfiguration config)
        {
            var publicKey = config["VapidKeys:PublicKey"];
            return Content(publicKey);
        }

        [HttpPost("notify-all")]
        public async Task<IActionResult> NotifyAll([FromBody] PushMessageDto message)
        {
            if (string.IsNullOrWhiteSpace(message.Title) || string.IsNullOrWhiteSpace(message.Body))
            {
                return BadRequest("Titel och meddelande krävs.");
            }

            var subscribers = await _context.PushSubscribers
            .Include(s => s.User)
            .ThenInclude(u => u.Preferences)
            .Where(s => s.User != null && s.User.Preferences.NotifyPizza)
            .ToListAsync();

            var payload = $"{{\"title\":\"{message.Title}\",\"body\":\"{message.Body}\"}}";

            int successCount = 0;
            foreach (var sub in subscribers)
            {
                try
                {
                    _notificationService.SendNotification(sub.Endpoint, sub.P256DH, sub.Auth, payload);
                    successCount++;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"❌ Misslyckades att skicka till {sub.Endpoint}: {ex.Message}");
                }
            }

            return Ok($"Skickade notiser till {successCount} användare.");
        }

        [HttpPost("unsubscribe")]
        public async Task<IActionResult> Unsubscribe([FromBody] PushUnsubscribeDto dto)
        {
            var sub = await _context.PushSubscribers.FirstOrDefaultAsync(s => s.Endpoint == dto.Endpoint);
            if (sub != null)
            {
                _context.PushSubscribers.Remove(sub);
                await _context.SaveChangesAsync();
            }
            return Ok();
        }

        public class PushUnsubscribeDto
        {
            public string Endpoint { get; set; }
        }


    }

}
