using System.ComponentModel.DataAnnotations;
using EnotaryoPH.Data;
using EnotaryoPH.Data.Entities;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace EnotaryoPH.Web.Pages.Participant.Registration
{
    public class IndexModel : PageModel
    {
        private readonly NotaryoDBContext _notaryoDBContext;
        private readonly ISignInService _signInService;

        public IndexModel(NotaryoDBContext notaryoDBContext, ISignInService signInService)
        {
            _notaryoDBContext = notaryoDBContext;
            _signInService = signInService;
        }

        public async Task<IActionResult> OnGetAsync()
        {
            if (string.IsNullOrEmpty(InvitationCode))
            {
                return NotFound();
            }

            var validStates = new SignatoryStatus[] { SignatoryStatus.New, SignatoryStatus.Registered, SignatoryStatus.EmailSent, SignatoryStatus.FaceMatch };
            var invitationCodeGuid = InvitationCode.ToGuidFromBase64();
            var signatory = _notaryoDBContext.TransactionSignatories
                .Include(e => e.Transaction)
                .FirstOrDefault(e => e.InvitationCode == invitationCodeGuid.ToString());
            if (signatory == null || !signatory.Status.IsInList(validStates))
            {
                return NotFound();
            }

            var existingUser = _notaryoDBContext.Users.FirstOrDefault(e => e.Email.ToLower() == signatory.Email.ToLower());
            if (existingUser != null)
            {
                signatory.Status = nameof(SignatoryStatus.Registered);
                signatory.UserID = existingUser.UserID;
                _notaryoDBContext.Update(signatory);
                _notaryoDBContext.SaveChanges();

                await _signInService.SignInAsync(new UserLogin
                {
                    Email = existingUser.Email,
                    Role = existingUser.Role,
                    User_UID = existingUser.User_UID.Value
                });

                if (signatory.Status == nameof(SignatoryStatus.FaceMatch))
                {
                    return Redirect($"Participant/VideoCall/Room/{signatory.Transaction.Transaction_UID}");
                }

                return Redirect($"Steps/UploadIdentification/{signatory.Transaction.Transaction_UID}");
            }

            TransactionSignatory_UID = signatory.TransactionSignatory_UID.GetValueOrDefault();

            return Page();
        }

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

            if (TransactionSignatory_UID == Guid.Empty)
            {
                ModelState.AddModelError(nameof(TransactionSignatory_UID), "TransactionSignatory_UID is missing.");
                return Page();
            }

            var signatory = _notaryoDBContext.TransactionSignatories
                .Include(t => t.Transaction)
                .FirstOrDefault(e => e.TransactionSignatory_UID == TransactionSignatory_UID);
            if (signatory == null || !signatory.Status.IsInList(SignatoryStatus.New, SignatoryStatus.EmailSent))
            {
                return BadRequest();
            }

            var newUser = new User
            {
                BirthDate = new DateTime(Year.Value, Month.Value, Day.Value, 0, 0, 0, DateTimeKind.Utc),
                CreatedOn = DateTime.UtcNow,
                Email = signatory.Email,
                Firstname = Firstname,
                Lastname = Lastname,
                Middlename = Middlename,
                PhoneNumber = PhoneNumber,
                Prefix = Prefix,
                Role = signatory.Type,
                Suffix = Suffix,
                User_UID = Guid.CreateVersion7(DateTime.UtcNow),
                PasswordHash = "secret"
            };
            _notaryoDBContext.Add(newUser);
            signatory.User = newUser;
            signatory.Status = nameof(SignatoryStatus.Registered);
            _notaryoDBContext.Update(signatory);
            _notaryoDBContext.SaveChanges();

            await _signInService.SignInAsync(new UserLogin
            {
                Email = newUser.Email,
                Role = newUser.Role,
                User_UID = newUser.User_UID.Value
            });

            return Redirect($"Steps/UploadIdentification/{signatory.Transaction.Transaction_UID}");
        }

        [BindProperty(SupportsGet = true)]
        public string InvitationCode { get; set; }

        [BindProperty]
        public Guid TransactionSignatory_UID { get; set; }

        [BindProperty, Required]
        public int? Year { get; set; }

        [BindProperty, Required]
        public int? Month { get; set; }

        [BindProperty, Required]
        public int? Day { get; set; }

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

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

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

        [BindProperty]
        public string? Middlename { get; set; }

        [BindProperty]
        public string? Suffix { get; set; }

        [BindProperty]
        public string? Prefix { get; set; }
    }
}