using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using Coravel.Queuing.Interfaces;
using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;
using EnotaryoPH.Web.Common.Jobs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;

namespace EnotaryoPH.Web.Pages.Principal.NotaryoSteps
{
    public class UploadDocumentModel : PageModel
    {
        private readonly ICurrentUserService _currentUserService;
        private readonly NotaryoDBContext _notaryoDBContext;
        private readonly IQueue _queue;

        public UploadDocumentModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, IQueue queue)
        {
            _notaryoDBContext = notaryoDBContext;
            _currentUserService = currentUserService;
            _queue = queue;
        }

        public IActionResult OnGet(Guid transaction_UID)
        {
            var _transaction = _notaryoDBContext.Transactions
                .Include(t => t.TransactionDocument)
                .Include(t => t.TransactionSignatories)
                .AsNoTracking().FirstOrDefault(e => e.Transaction_UID == transaction_UID);
            DocumentTypes = GetDocumentTypes();
            CurrentUserEmail = _currentUserService.GetEmail();
            var signatories = _transaction.TransactionSignatories.Select(ts => new SignatoryViewModel
            {
                Email = ts.Email,
                Type = ts.Type,
                UID = ts.TransactionSignatory_UID.GetValueOrDefault()
            }).ToList();
            ParticipantsJson = JsonSerializer.Serialize(signatories);

            return Page();
        }

        public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                DocumentTypes = GetDocumentTypes();
                return Page();
            }

            if (!IsConfirmed)
            {
                ModelState.AddModelError(nameof(IsConfirmed), "You must tick this box to continue.");
                DocumentTypes = GetDocumentTypes();
                return Page();
            }

            var transaction = _notaryoDBContext.Transactions
                .Include(t => t.TransactionSignatories)
                .Include(t => t.TransactionDocument)
                .FirstOrDefault(t => t.Transaction_UID == Transaction_UID);
            if (transaction == null)
            {
                return NotFound();
            }

            transaction.Status = nameof(TransactionState.DocumentUploaded);
            transaction.IsRecorded = IsVideoConferenceRecorded;

            if (transaction.TransactionDocument == null)
            {
                transaction.TransactionDocument = new TransactionDocument
                {
                    CreatedOn = DateTime.UtcNow,
                    Transaction = transaction,
                    TransactionDocument_UID = Guid.CreateVersion7(DateTime.UtcNow),
                };
            }

            var stream = new MemoryStream((int)DocumentFile.Length);
            DocumentFile.CopyTo(stream);
            transaction.TransactionDocument.File = stream.ToArray();
            transaction.TransactionDocument.Filename = DocumentFile.FileName;
            transaction.TransactionDocument.DocumentType = DocumentType;
            transaction.TransactionDocument.UploadedOn = DateTime.UtcNow;

            var participants = JsonSerializer.Deserialize<List<SignatoryViewModel>>(ParticipantsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? [];
            transaction.TransactionSignatories = participants.Select(p => new TransactionSignatory
            {
                CreatedOn = DateTime.UtcNow,
                Email = p.Email,
                Status = nameof(SignatoryStatus.New),
                TransactionSignatory_UID = Guid.CreateVersion7(DateTime.UtcNow),
                Type = p.Type,
                InvitationCode = Guid.CreateVersion7(DateTime.UtcNow).ToString()
            }).ToList();

            _notaryoDBContext.Update(transaction);
            _notaryoDBContext.SaveChanges();

            foreach (var signatory in transaction.TransactionSignatories)
            {
                _queue.QueueInvocableWithPayload<SignatoryInvitationInvocable, Guid>(signatory.TransactionSignatory_UID.GetValueOrDefault());
            }

            return Redirect($"/Principal/NotaryoSteps/ChooseNotary/{Transaction_UID}");
        }

        private List<SelectListItem> GetDocumentTypes()
        {
            var lookupIdentificationTypes = _notaryoDBContext.LookupData.AsNoTracking().Include(e => e.LookupDataValues).FirstOrDefault(e => e.Name == "Document Types");
            return lookupIdentificationTypes.LookupDataValues
                .ConvertAll(m => new SelectListItem
                {
                    Text = m.Title.DefaultIfEmpty(m.Value),
                    Value = m.Value
                });
        }

        public string CurrentUserEmail { get; private set; }

        [BindProperty, Required]
        public IFormFile DocumentFile { get; set; }

        [BindProperty, Required]
        public string DocumentType { get; set; }

        public List<SelectListItem> DocumentTypes { get; set; }

        [BindProperty]
        public bool IsConfirmed { get; set; }

        [BindProperty]
        public bool IsVideoConferenceRecorded { get; set; }

        [BindProperty]
        public string ParticipantsJson { get; set; } = "[]";

        [BindProperty(SupportsGet = true)]
        public Guid Transaction_UID { get; set; }
    }
}