using AutoMapper;
using AutoMapper.Internal.Mappers;
using Entities.Contracts;
using Entities.DTO;
using Microsoft.EntityFrameworkCore;
using SharedDATA.Api;
using TechHelper.Context;
using TechHelper.Repository;
using TechHelper.Services;

namespace TechHelper.Server.Services
{
	public class StudentSubmissionDetailService : IStudentSubmissionDetailService
	{
		private readonly IUnitOfWork _unitOfWork;
		private readonly IExamService examService;
		private readonly IMapper _mapper;

		public StudentSubmissionDetailService(
			IUnitOfWork unitOfWork,
			IExamService examService,
			IMapper mapper)
		{
			_unitOfWork = unitOfWork;
			this.examService = examService;
			_mapper = mapper;
		}

		public async Task<ApiResponse> GetSubmissionDetailAsync(Guid submissionId)
		{
			try
			{
				// 获取submission基本信息
				var submission = await _unitOfWork.GetRepository<Submission>()
					.GetAll(s => s.Id == submissionId)
					.Include(s => s.Exam)
					.ThenInclude(a => a.Creator)
					.FirstOrDefaultAsync();

				if (submission == null)
				{
					return ApiResponse.Error("未找到指定的提交记录");
				}

				var assignment = await examService.GetAsync(submission.ExamId);
				if (assignment == null)
				{
					return ApiResponse.Error("未找到指定的作业");
				}

				// 获取所有提交详情
				var submissionDetails = await _unitOfWork.GetRepository<SubmissionDetail>()
					.GetAll(sd => sd.SubmissionId == submissionId)
					.Include(sd => sd.ExamQuestion)
					.ThenInclude(aq => aq.Question)
					.ThenInclude(q => q.Lesson)
					.ThenInclude(q => q.KeyPoints)
					.ToListAsync();

				// 获取同作业的所有提交用于排名和成绩分布
				var allSubmissions = await _unitOfWork.GetRepository<Submission>()
					.GetAll(s => s.ExamId == submission.ExamId)
					.ToListAsync();

				// 映射基本信息
				var result = _mapper.Map<StudentSubmissionDetailDto>(submission);
				result.Assignment = assignment.Result as AssignmentDto ?? new AssignmentDto();

				var errorQuestion = submissionDetails
					.Where(sd => sd.IsCorrect == false && sd.ExamQuestion?.StructType == AssignmentStructType.Question && sd.ExamQuestion?.Question != null)
					.ToList();

				// 计算基础统计
				result.TotalQuestions = submissionDetails.Select(x => x.ExamQuestion.StructType == AssignmentStructType.Question && x.ExamQuestion?.Question != null).Count();
				result.ErrorCount = errorQuestion.Count;
				result.CorrectCount = result.TotalQuestions - result.ErrorCount;
				result.AccuracyRate = result.TotalQuestions > 0 ?
					(float)result.CorrectCount / result.TotalQuestions : 0;

				// 计算错误类型分布 - 只获取题目类型的错误
				result.ErrorTypeDistribution = errorQuestion
					.GroupBy(sd => sd.ExamQuestion.Question.Type.ToString())
					.ToDictionary(g => g.Key, g => g.Count()); ;

				// 计算错误类型成绩分布 - 只获取题目类型的错误
				result.ErrorTypeScoreDistribution = errorQuestion
					.GroupBy(sd => sd.ExamQuestion.Question.Type.ToString())
					.ToDictionary(g => g.Key, g => g.Sum(sd => sd.PointsAwarded ?? 0));

				// 计算成绩排名
				var orderedSubmissions = allSubmissions
					.OrderByDescending(s => s.OverallGrade)
					.ToList();
				result.TotalRank = orderedSubmissions.FindIndex(s => s.Id == submissionId) + 1;

				SetBCorrect(result.Assignment, errorQuestion);
				// 计算成绩分布
				result.AllScores = allSubmissions.Select(s => s.OverallGrade).ToList();
				result.AverageScore = submission.OverallGrade;
				result.ClassAverageScore = allSubmissions.Average(s => s.OverallGrade);

				// 计算课文错误分布
				result.LessonErrorDistribution = errorQuestion
					.Where(eq => eq.ExamQuestion.Question.Lesson != null)
					.GroupBy(sd => sd.ExamQuestion.Question.Lesson.Title)
					.ToDictionary(g => g.Key, g => g.Count());

				// 计算关键点错误分布
				result.KeyPointErrorDistribution = errorQuestion
					.Where(eq => eq.ExamQuestion.Question.Lesson != null)
					.GroupBy(sd => sd.ExamQuestion.Question.KeyPoint.Key)
					.ToDictionary(g => g.Key, g => g.Count());

				return ApiResponse.Success(result: result);
			}
			catch (Exception ex)
			{
				return ApiResponse.Error($"获取学生提交详细信息失败: {ex.Message}");
			}
		}

		public void SetBCorrect(AssignmentDto assignment, List<SubmissionDetail> submissionDetails)
		{
			SetBCorrect(assignment.ExamStruct, submissionDetails);
		}

		public void SetBCorrect(AssignmentQuestionDto assignmentQuestion, List<SubmissionDetail> submissionDetails)
		{
			var sd = submissionDetails.FirstOrDefault(x => x.ExamQuestionId == assignmentQuestion.Id);
			if (sd != null)
				assignmentQuestion.BCorrect = sd.ExamQuestion.BCorrect;
			else 
				assignmentQuestion.BCorrect = false;

			assignmentQuestion.ChildrenAssignmentQuestion?.ForEach(
				cq => SetBCorrect(cq, submissionDetails));
		}

		//Task<ApiResponse> IStudentSubmissionDetailService.GetSubmissionDetailAsync(Guid submissionId)
		//{
		//	throw new NotImplementedException();
		//}
	}
}
