using HotelContracts.BindingModels;
using HotelContracts.ViewModels;
using HotelDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace HotelDataBaseImplement.Models
{
    public class Conference : IConferenceModel
    {
        [Required]
        public string ConferenceName { get; set; } = string.Empty;
        [Required]
        public DateTime StartDate { get; set; } = DateTime.Now;

        public int OrganiserId { get; private set; }

        public int Id { get; private set; }

        public virtual Organiser Organiser { get; set; }

        [ForeignKey("ConferenceId")]
        public virtual List<ConferenceBooking> ConferenceBookings { get; set; }

        [ForeignKey("ConferenceId")]
        public virtual List<ConferenceMember> Members { get; set; }

        private Dictionary<int, IMemberModel> _conferenceMembers = null;
        public Dictionary<int, IMemberModel> ConferenceMembers
        {
            get
            {
                if (_conferenceMembers == null)
                {
                    _conferenceMembers = Members.ToDictionary(recPC => recPC.MemberId, recPC => (recPC.Member as IMemberModel));
                }
                return _conferenceMembers;
            }
        }

        public static Conference Create(HotelDataBase context, ConferenceBindingModel model)
        {
            return new Conference()
            {
                Id = model.Id,
                ConferenceName = model.ConferenceName,
                StartDate = model.StartDate,
                Members = model.ConferenceMembers.Select(x => new ConferenceMember
                {
                    Member = context.Members.First(y => y.Id == x.Key),
                }).ToList()
            };
        }

        public void Update(ConferenceBindingModel model)
        {
            ConferenceName = model.ConferenceName;
            StartDate = model.StartDate;
        }

        public ConferenceViewModel GetViewModel => new()
        {
            Id = Id,
            ConferenceName = ConferenceName,
            StartDate = StartDate,
            ConferenceMembers = ConferenceMembers
        };

        public void UpdateMembers(HotelDataBase context, ConferenceBindingModel model)
        {
            var conferenceMembers = context.ConferenceMembers.Where(rec => rec.ConferenceId == model.Id).ToList();
            
            if (conferenceMembers != null)
            {
                context.ConferenceMembers.RemoveRange(conferenceMembers.Where(rec => !model.ConferenceMembers.ContainsKey(rec.MemberId)));
                context.SaveChanges();
            }

            var conference = context.Conferences.First(x => x.Id == Id);

            foreach (var cm in model.ConferenceMembers)
            {
                context.ConferenceMembers.Add(new ConferenceMember
                {
                    Conference = conference,
                    Member = context.Members.First(x => x.Id == cm.Key)
                });
                context.SaveChanges();
            }
            _conferenceMembers = null;
        }
    }
}
