using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace EnotaryoPH.Web.Pages.Notary.TransactionStatus
{
    public class IndexModel : PageModel
    {
        private const string STATUS_READY = "Ready";
        private readonly ICurrentUserService _currentUserService;
        private readonly NotaryoDBContext _notaryoDBContext;
        private readonly IVideoConferenceService _videoConferenceService;
        private Transaction? _transaction;

        public IndexModel(NotaryoDBContext notaryoDBContext, ICurrentUserService currentUserService, IVideoConferenceService videoConferenceService)
        {
            _notaryoDBContext = notaryoDBContext;
            _currentUserService = currentUserService;
            _videoConferenceService = videoConferenceService;
        }

        public IActionResult OnGet()
        {
            _transaction = _notaryoDBContext
                .Transactions
                .AsNoTracking()
                .Include(t => t.TransactionSignatories)
                .Include(t => t.TransactionDocument)
                .Include(t => t.Principal)
                .FirstOrDefault(e => e.Transaction_UID == Transaction_UID);

            if (_transaction == null)
            {
                return NotFound();
            }

            Title = _transaction.TransactionDocument.DocumentType;
            StartedOn = _transaction.CreatedOn.GetValueOrDefault();
            StatusDescription = "Not all signatories have signed up to enotaryo and completed the onboarding process. This transaction cannot proceed until this has been resolved.";

            var signatories = _transaction.TransactionSignatories.ConvertAll(s => new SignatoryViewModel
            {
                Email = s.Email,
                Type = s.Type,
                Status = ChangeStatusLabel(s.Status)
            });
            signatories.Add(new SignatoryViewModel
            {
                Email = _transaction.Principal.Email,
                Status = STATUS_READY,
                Type = nameof(UserType.Principal)
            });

            Signatories = signatories.OrderBy(sig => sig.Type).ThenBy(sig => sig.Email).ToList();

            var isReady = Signatories.TrueForAll(sig => sig.Status == STATUS_READY);
            if (isReady)
            {
                StatusDescription = _transaction.Status == nameof(TransactionState.Accepted)
                    ? "This transaction is already assigned to a lawyer and is being processed."
                    : "All signatories have signed up to enotaryo and completed the onboarding process. This transaction is ready to be processed.";
            }

            return Page();
        }

        public async Task<IActionResult> OnPostAsync()
        {
            _transaction = _notaryoDBContext
                .Transactions
                .Include(t => t.TransactionSignatories)
                .FirstOrDefault(e => e.Transaction_UID == Transaction_UID);
            if (_transaction == null)
            {
                return NotFound();
            }

            var user = _notaryoDBContext.Users.Single(u => u.User_UID == _currentUserService.GetUser_UID());
            var lawyer = _notaryoDBContext.Lawyers.Single(l => l.UserID == user.UserID);
            _transaction.Status = nameof(TransactionState.Accepted);
            _transaction.LawyerID = lawyer.LawyerID;
            _notaryoDBContext.Update(_transaction);
            _notaryoDBContext.SaveChanges();

            var canStart = _videoConferenceService.CanStart(Transaction_UID);
            return canStart
                ? Redirect($"/Participant/VideoCall/Room/{Transaction_UID}")
                : Redirect($"/Participant/VideoCall/Waiting/{Transaction_UID}");
        }

        private string ChangeStatusLabel(string status) => status switch { nameof(SignatoryStatus.FaceMatch) => STATUS_READY, _ => status };

        public bool IsTaken => string.Equals(_transaction?.Status, nameof(TransactionState.Accepted), StringComparison.OrdinalIgnoreCase);
        public List<SignatoryViewModel> Signatories { get; private set; } = [];

        public DateTime StartedOn { get; private set; }

        public string StatusDescription { get; private set; }

        public string Title { get; private set; }

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