using System.Text.Json;
using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;

namespace EnotaryoPH.Web.Common.Services
{
    public class EventService : IEventService
    {
        private readonly NotaryoDBContext _dBContext;
        private readonly INotificationService _notificationService;

        public EventService(NotaryoDBContext dBContext, INotificationService notificationService)
        {
            _dBContext = dBContext;
            _notificationService = notificationService;
        }

        public Task LogAsync(NotaryoEvent notaryoEvent, object entityId) => LogAsync(notaryoEvent, entityId, null);

        public async Task LogAsync(NotaryoEvent notaryoEvent, List<object> entityIds, object payLoad)
        {
            foreach (var entityId in entityIds)
            {
                await LogAsync(notaryoEvent, entityId, payLoad);
            }
        }

        public async Task LogAsync(NotaryoEvent notaryoEvent, object entityId, object payLoad)
        {
            var logItem = new EventLog
            {
                Description = $"Event: {notaryoEvent}, Entity: {entityId}",
                EventLog_UID = Guid.CreateVersion7(DateTime.UtcNow),
                LogDate = DateTime.UtcNow,
                LogType = notaryoEvent.ToString(),
                Payload = payLoad != null ? JsonSerializer.Serialize(payLoad) : null,
                StreamID = entityId.ToString(),
            };
            if (notaryoEvent == NotaryoEvent.TransactionApproved)
            {
                var transaction = _dBContext.Transactions.AsNoTracking()
                    .Include(t => t.TransactionSignatories)
                    .ThenInclude(ts => ts.User)
                    .Include(t => t.Lawyer)
                    .ThenInclude(l => l.User)
                    .Include(t => t.Principal)
                    .Include(t => t.TransactionDocument)
                    .FirstOrDefault(t => t.TransactionID == entityId.ToInteger());
                logItem.Description = $"Transaction {entityId} has been approved.";
                if (transaction != null)
                {
                    var message = $"The document {transaction.TransactionDocument.DocumentType} has been approved.";
                    var allUsers = transaction.TransactionSignatories.ConvertAll(ts => ts.User.Email);
                    allUsers.Add(transaction.Lawyer.User.Email);
                    allUsers.Add(transaction.Principal.Email);
                    await _notificationService.NotifyUsersAsync(message, allUsers.ToArray());
                }
            }
            _dBContext.Add(logItem);
            _dBContext.SaveChanges();
        }
    }
}