using Entities.Contracts;
using Entities.DTO;
using Microsoft.EntityFrameworkCore;
using SharedDATA.Api;
using TechHelper.Repository;

namespace TechHelper.Server.Repositories
{
	public class ExamRepository : IExamRepository
	{
		private readonly IUnitOfWork _unitOfWork;
		private readonly IRepository<Exam> _assignmentRepo;
		private readonly IRepository<Question> _questionRepo;
		private readonly IRepository<ExamQuestion> _assignQuestionRepo;

		public ExamRepository(IUnitOfWork unitOfWork)
		{
			_unitOfWork = unitOfWork;
			_assignmentRepo = _unitOfWork.GetRepository<Exam>();
			_assignQuestionRepo = _unitOfWork.GetRepository<ExamQuestion>();
		}

		public async Task<Exam?> GetFullExamByIdAsync(Guid assignmentId)
		{
			var result = await _assignmentRepo.GetFirstOrDefaultAsync(
				predicate:
					a => a.Id == assignmentId,
				include:
					i => i.Include(a => a.ExamStruct)
				);

			result.ExamStruct = await GetNeed(result.ExamStructId) ?? null;

			return result;
		}


		public async Task<ExamQuestion?> GetNeed(Guid id)
		{
			var result = await _assignQuestionRepo.GetFirstOrDefaultAsync(
				predicate: aq => aq.Id == id,
				include: i => i
					.Include(aq => aq.ChildExamQuestions)
					.Include(aq => aq.Question)
						.ThenInclude(q => q.Lesson)
					.Include(aq => aq.Question)
						.ThenInclude(q => q.KeyPoint)
			);

			if (result == null)
			{
				return null;
			}

			var loadedChildren = new List<ExamQuestion>();
			foreach (var child in result.ChildExamQuestions)
			{
				var loadedChild = await GetNeed(child.Id);
				if (loadedChild != null)
				{
					loadedChildren.Add(loadedChild);
				}
			}
			result.ChildExamQuestions = loadedChildren;

			return result;
		}



		public async Task<IEnumerable<Exam>> GetExamPreviewsByUserAsync(Guid userId)
		{
			return await _assignmentRepo.GetAllAsync(
				predicate: a => a.CreatorId == userId && !a.IsDeleted);
		}

		public async Task AddAsync(Exam assignment)
		{
			await _assignmentRepo.InsertAsync(assignment);
		}

		public async Task AddAsync(ExamQuestion assignment)
		{
		}

		public async Task AddAsync(Question assignment)
		{
		}

		public async Task AddAsync(Submission submission)
		{
			await _unitOfWork.GetRepository<Submission>().InsertAsync(submission);
		}

		public async Task<IEnumerable<Exam>> GetAllSubmissionPreviewsByUserAsync(Guid id)
		{
			var submissions = await _unitOfWork.GetRepository<Submission>().GetAllAsync(predicate: s => s.StudentId == id, include: i => i.Include(s => s.Exam));
			if (submissions == null || !submissions.Any())
				return Enumerable.Empty<Exam>();
			return submissions.ToList().Select(s => s.Exam).Where(a => a != null).ToList();
		}
	}
}
