using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using UniversityContracts.BindingModels;
using UniversityContracts.ViewModels;
using UniversityModels.Models;

namespace UniversityDataBaseImplemet.Models
{
    public class Stream : IStreamModel
    {
        [Required]
        public string Name { get; set; } = string.Empty;
        [Required]
        public int Course { get; set; }
        [Required]
        public int UserId { get; set; }

        public int Id { get; private set; }
        [ForeignKey("StreamId")]
        public virtual List<EducationGroupStream> EducationGroupStream { get; set; } = new();
        [ForeignKey("StreamId")]
        public virtual List<StudentStream> StreamStudents { get; set; } = new();
        public virtual User User { get; set; }
        private Dictionary<int, IStudentModel>? _studentStream = null;
        [NotMapped]
        public Dictionary<int, IStudentModel> StudentStream
        {
            get
            {
                if (_studentStream == null)
                {
                    _studentStream = StreamStudents.ToDictionary(rec => rec.StudentId, rec => rec.Student as IStudentModel);
                }
                return _studentStream;
            }
        }
        public static Stream Create(StreamBindingModel model)
        {
            return new Stream()
            {
                Id = model.Id,
                Name = model.Name,
                Course = model.Course,
                UserId = model.UserId
            };
        }
        public void Update(StreamBindingModel model)
        {
            Name = model.Name;
            Course = model.Course;
            UserId = model.UserId;
        }
        public void UpdateStreamStudents(Database context, StreamBindingModel model)
        {
            var studentStream = context.StudentStreams
                .Where(rec => rec.StreamId == model.Id)
                .ToList();
            if (studentStream != null)
            {
                context.StudentStreams
                    .RemoveRange(studentStream
                            .Where(rec => !model.StudentStream
                            .ContainsKey(rec.StudentId))
                        );
                context.SaveChanges();
                var stream = context.Streams
                    .First(x => x.Id == Id);
                foreach (var sd in studentStream)
                {
                    model.StudentStream.Remove(sd.StudentId);
                }
                foreach (var sd in model.StudentStream)
                {
                    context.StudentStreams.Add(new StudentStream
                    {
                        Stream = stream,
                        Student = context.Students.First(x => x.Id == sd.Key),
                    });
                    context.SaveChanges();
                }
                _studentStream = null;
            }
        }
        public StreamViewModel GetViewModel => new()
        {
            Id = Id,
            Name = Name,
            UserId = UserId,
            Course= Course
        };
    }
}
