using CandidateReviewContracts.BindingModels;
using CandidateReviewContracts.ViewModels;
using CandidateReviewDataModels.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace CandidateReviewDatabaseImplement.Models
{
    public class Assessment : IAssessmentModel
    {
        public int? UserId { get; set; }

        public int? ResumeId { get; set; }

        public string? Comment { get; set; }

        public int Id { get; set; }
        public virtual User User { get; set; }
        public virtual Resume Resume { get; set; }

        private Dictionary<int, (CriterionModel, int)>? _assessmentCriterions = null;

        public Dictionary<int, (CriterionModel, int)> AssessmentCriterions
        {
            get
            {
                if (_assessmentCriterions == null)
                {
                    _assessmentCriterions = Criterions
                    .ToDictionary(recAC => recAC.CriterionId, recAC =>
                   (new CriterionModel { Id = recAC.Criterion.Id, Name = recAC.Criterion.Name }, recAC.Value));
                }
                return _assessmentCriterions;
            }
        }

        [ForeignKey("AssessmentId")]
        public virtual List<AssessmentCriterion> Criterions { get; set; } = new();

        public static Assessment Create(CandidateReviewDatabase context, AssessmentBindingModel model)
        {
            return new Assessment()
            {
                Id = model.Id,
                ResumeId = model.ResumeId,
                UserId = model.UserId,
                Comment = model.Comment,
                Criterions = model.AssessmentCriterions.Select(x => new AssessmentCriterion
                {
                    Assessment = context.Assessments.First(y => y.Id == x.Key),
                    Value = x.Value.Item2
                }).ToList()
            };
        }

        public void Update(AssessmentBindingModel model)
        {
            if (model == null)
            {
                return;
            }
            ResumeId = model.ResumeId;
            UserId = model.UserId;
            Comment = model.Comment;
        }


        public AssessmentViewModel GetViewModel => new()
        {
            Id = Id,
            ResumeId = ResumeId,
            UserId = UserId,
            Comment = Comment,
            AssessmentCriterions = AssessmentCriterions
        };

        public void UpdateCriterions(CandidateReviewDatabase context, AssessmentBindingModel model)
        {
            var assessmentCriterions = context.AssessmentCriterions.Where(rec => rec.AssessmentId == model.Id).ToList();
            if (assessmentCriterions != null && assessmentCriterions.Count > 0)
            { 
                context.AssessmentCriterions.RemoveRange(assessmentCriterions.Where(rec => !model.AssessmentCriterions.ContainsKey(rec.CriterionId)));
                context.SaveChanges();
                foreach (var updateCriterion in assessmentCriterions)
                {
                    updateCriterion.Value = model.AssessmentCriterions[updateCriterion.CriterionId].Item2;
                    model.AssessmentCriterions.Remove(updateCriterion.CriterionId);
                }
                context.SaveChanges();
            }
            var assessment = context.Assessments.First(x => x.Id == Id);
            foreach (var ac in model.AssessmentCriterions)
            {
                var criterion = context.Criterions.First(x => x.Id == ac.Value.Item1.Id);
                if (criterion == null)
                {
                    throw new Exception($"Критерий с ID {ac.Key} не найден.");
                }

                context.AssessmentCriterions.Add(new AssessmentCriterion
                {
                    Assessment = assessment,
                    Criterion = criterion,
                    Value = ac.Value.Item2
                });
            }
            context.SaveChanges();
            _assessmentCriterions = null;
        }
    }
}