using AutoMapper;
using Entities.Contracts;
using Entities.DTO;
using Entities.DTO.Class;
using Microsoft.VisualBasic;
using SharedDATA.Api;
using TechHelper.Context;
using TechHelper.Server.Repositories;
using TechHelper.Services;

namespace TechHelper.Server.Services
{

	public class ExamService : IExamService
	{
		private readonly IUnitOfWork _unitOfWork;
		private readonly IExamRepository _examRepository;
		private readonly ISubmissionServices _submissionService;
		private readonly IClassService _classService;
		private readonly IMapper _mapper;

		public ExamService(IUnitOfWork unitOfWork, IExamRepository examRepository, IMapper mapper, IClassService classService, ISubmissionServices submissionService)
		{
			_unitOfWork = unitOfWork;
			_examRepository = examRepository;
			_mapper = mapper;
			_classService = classService;
			_submissionService = submissionService;
		}

		public async Task<ApiResponse> CreateExamAsync(AssignmentDto assignmentDto)
		{
			try
			{

				Exam newAssi = _mapper.Map<Exam>(assignmentDto);

				await _examRepository.AddAsync(newAssi);


				var context = _unitOfWork.GetDbContext<ApplicationContext>();

				foreach (var entry in context.ChangeTracker.Entries())
				{
					if (entry.State == Microsoft.EntityFrameworkCore.EntityState.Added)
					{
						if (entry.Entity is Question newQues)
						{
							newQues.CreatorId = newAssi.CreatorId;
						}
					}

				}


				if (await _unitOfWork.SaveChangesAsync() > 0)
				{
					return ApiResponse.Success();
				}

				return ApiResponse.Error("保存失败");
			}
			catch (Exception ex)
			{
				return ApiResponse.Error(ex.Message);
			}
		}



		public async Task<AssignmentDto> GetExamByIdAsync(Guid id)
		{
			var assignment = await _examRepository.GetFullExamByIdAsync(id);
			if (assignment == null)
			{

				throw new InvalidOperationException("");
			}

			return _mapper.Map<AssignmentDto>(assignment);
		}

		public async Task<ApiResponse> GetAllExamPreviewsAsync(Guid userId)
		{
			var assignments = await _examRepository.GetExamPreviewsByUserAsync(userId);
			var result = _mapper.Map<List<AssignmentDto>>(assignments);
			return ApiResponse.Success(result: result);
		}


		public Task<ApiResponse> GetAllAsync(QueryParameter query)
		{
			throw new NotImplementedException();
		}

		public async Task<ApiResponse> GetAsync(Guid id)
		{
			var assignment = await _examRepository.GetFullExamByIdAsync(id);
			if (assignment == null)
			{
				return ApiResponse.Error("获取失败");
			}
			var result = _mapper.Map<AssignmentDto>(assignment);
			return ApiResponse.Success(result: result);
		}

		public Task<ApiResponse> AddAsync(AssignmentDto model)
		{
			throw new NotImplementedException();
		}

		public Task<ApiResponse> UpdateAsync(AssignmentDto model)
		{
			throw new NotImplementedException();
		}

		public async Task<ApiResponse> DeleteAsync(Guid id)
		{
			try
			{
				var assignment = await _unitOfWork.GetRepository<Exam>().GetFirstOrDefaultAsync(predicate: a => a.Id == id);

				if (assignment == null) return ApiResponse.Error("找不到该试卷");
				_unitOfWork.GetRepository<Exam>().Delete(id);
				_unitOfWork.GetRepository<ExamQuestion>().Delete(assignment.ExamStructId);


				if (await _unitOfWork.SaveChangesAsync() > 0)
				{
					return ApiResponse.Success();
				}
				return ApiResponse.Error("删除失败");
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"内部问题,{ex.Message}, InerException{ex.InnerException}");
			}
		}

		public async Task<ApiResponse> SubmissionAssignment(SubmissionDto submissionDto)
		{
			try
			{
				var submission = _mapper.Map<Submission>(submissionDto);

				await _examRepository.AddAsync(submission);

				if (await _unitOfWork.SaveChangesAsync() > 0)
				{
					return ApiResponse.Success("保存成功");
				}
				return ApiResponse.Error("保存失败");
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"出现了错误,{ex.Message} innerEx:{ex.InnerException}");
			}
		}

		public async Task<ApiResponse> AssignmentToAllStudentsAsync(Guid assignmentId, Guid TeacherId)
		{
			try
			{
				var classes = await _classService.GetUserClass(TeacherId);
				var classUsrClass = classes.Result as List<Class>;
				var classDto = _mapper.Map<ClassDto>(classUsrClass?.FirstOrDefault());
				var cla = await _classService.GetClassStudents(classDto);
				var assignment = await _examRepository.GetFullExamByIdAsync(assignmentId);
				if (assignment == null) return ApiResponse.Error("没有找到该试卷");

				var cs = cla.Result as ICollection<ClassStudent>;
				cs?.ToList().ForEach(async s =>
				{
					var subCount = _unitOfWork.GetRepository<Submission>().GetAll(predicate: su => su.ExamId == assignmentId && su.StudentId == s.StudentId);

					var submission = assignment.ConvertToSubmission(s.StudentId, TeacherId);
					submission.AttemptNumber = (byte)(subCount.Count() + 1);
					await _unitOfWork.GetRepository<Submission>().InsertAsync(submission);

				});

				if (await _unitOfWork.SaveChangesAsync() > 0)
				{
					return ApiResponse.Success();
				}
				return ApiResponse.Error();
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"内部错误, {ex.Message}");
			}
		}

		public async Task<ApiResponse> AssignmentToStudentsAsync(AssigExamToStudentsDto examToStudentsDto)
		{
			try
			{
				var assignment = await _examRepository.GetFullExamByIdAsync(examToStudentsDto.AssignmentId);
				if (assignment == null) return ApiResponse.Error("没有找到该试卷");

				examToStudentsDto.StudentIds?.ForEach(async s =>
				{
					var subCount = _unitOfWork.GetRepository<Submission>().GetAll(predicate: su => su.ExamId == examToStudentsDto.AssignmentId && su.StudentId == s);
					var submission = assignment.ConvertToSubmission(s, examToStudentsDto.CreaterId);
					submission.AttemptNumber = (byte)(subCount.Count() + 1);
					await _unitOfWork.GetRepository<Submission>().InsertAsync(submission);
				});

				if (await _unitOfWork.SaveChangesAsync() > 0)
				{
					return ApiResponse.Success();
				}
				return ApiResponse.Error();
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"内部错误, {ex.Message}");
			}
		}

		public async Task<ApiResponse> GetAllSubmissionAsync(Guid id)
		{
			try
			{
				var result = await _examRepository.GetAllSubmissionPreviewsByUserAsync(id);
				var allExam = _mapper.Map<List<AssignmentDto>>(result);
				return ApiResponse.Success(result: allExam);
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"Submission 内部错误, {ex.Message}");
			}
		}
	}

}
