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

namespace TechHelper.Services.Beta
{
    /// <summary>
    /// 提交详情服务实现（Beta版本）
    /// 实现提交详情相关的业务逻辑操作
    /// </summary>
    public class SubmissionDetailService : ISubmissionDetailService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMapper _mapper;
        private readonly IRepository<SubmissionDetail> _submissionDetailRepository;
        private readonly IRepository<Submission> _submissionRepository;

        /// <summary>
        /// 初始化提交详情服务
        /// </summary>
        /// <param name="mapper">AutoMapper实例</param>
        /// <param name="unitOfWork">工作单元</param>
        public SubmissionDetailService(IMapper mapper, IUnitOfWork unitOfWork)
        {
            _mapper = mapper;
            _unitOfWork = unitOfWork;
            _submissionDetailRepository = _unitOfWork.GetRepository<SubmissionDetail>();
            _submissionRepository = _unitOfWork.GetRepository<Submission>();
        }

        #region 基本CRUD操作

        /// <summary>
        /// 获取所有提交详情
        /// </summary>
        /// <param name="query">查询参数</param>
        /// <returns>提交详情列表</returns>
        public async Task<ApiResponse> GetAllAsync(QueryParameter query)
        {
            try
            {
                var pagedDetails = await _submissionDetailRepository.GetPagedListAsync(
                    pageIndex: query.PageIndex,
                    pageSize: query.PageSize,
                    orderBy: sd => sd.OrderByDescending(sd => sd.CreatedAt),
                    predicate: sd => !sd.IsDeleted,
                    include: i => i.Include(sd => sd.Student)
                                  .Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(pagedDetails.Items);

                return ApiResponse.Success("获取所有提交详情成功。", new PagedList<SubmissionDetailDto>
                {
                    PageIndex = pagedDetails.PageIndex,
                    PageSize = pagedDetails.PageSize,
                    TotalCount = pagedDetails.TotalCount,
                    TotalPages = pagedDetails.TotalPages,
                    Items = detailDtos
                });
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取所有提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 根据ID获取提交详情
        /// </summary>
        /// <param name="id">提交详情ID</param>
        /// <returns>提交详情详情</returns>
        public async Task<ApiResponse> GetAsync(Guid id)
        {
            try
            {
                var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(
                    predicate: sd => sd.Id == id && !sd.IsDeleted,
                    include: i => i.Include(sd => sd.Student)
                                  .Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                if (detail == null)
                {
                    return ApiResponse.Error("未找到提交详情。", 404);
                }

                var detailDto = _mapper.Map<SubmissionDetailDto>(detail);
                return ApiResponse.Success("获取提交详情成功。", detailDto);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 创建提交详情
        /// </summary>
        /// <param name="model">提交详情数据传输对象</param>
        /// <returns>创建结果</returns>
        public async Task<ApiResponse> AddAsync(SubmissionDetailDto model)
        {
            try
            {
                if(await _unitOfWork.GetRepository<SubmissionDetail>().GetFirstOrDefaultAsync(predicate: sd => sd.Id == model.Id ) != null)
                {
                    return ApiResponse.Error("提交详情已存在。", 400);
                }

                var detail = _mapper.Map<SubmissionDetail>(model);
                detail.CreatedAt = DateTime.Now;
                detail.UpdatedAt = DateTime.Now;
                detail.IsDeleted = false;

                await _submissionDetailRepository.InsertAsync(detail);
                await _unitOfWork.SaveChangesAsync();

                var result = _mapper.Map<SubmissionDetailDto>(detail);
                return ApiResponse.Success("创建提交详情成功。", result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"创建提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新提交详情
        /// </summary>
        /// <param name="model">提交详情数据传输对象</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResponse> UpdateAsync(SubmissionDetailDto model)
        {
            try
            {
                var existingDetail = await _submissionDetailRepository.GetFirstOrDefaultAsync(predicate: sd => sd.Id == model.Id && !sd.IsDeleted);
                if (existingDetail == null)
                {
                    return ApiResponse.Error("未找到要更新的提交详情。", 404);
                }

                _mapper.Map(model, existingDetail);
                existingDetail.UpdatedAt = DateTime.Now;
                _submissionDetailRepository.Update(existingDetail);
                await _unitOfWork.SaveChangesAsync();

                var result = _mapper.Map<SubmissionDetailDto>(existingDetail);
                return ApiResponse.Success("更新提交详情成功。", result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"更新提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 删除提交详情
        /// </summary>
        /// <param name="id">提交详情ID</param>
        /// <returns>删除结果</returns>
        public async Task<ApiResponse> DeleteAsync(Guid id)
        {
            try
            {
                var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(predicate: sd => sd.Id == id && !sd.IsDeleted);
                if (detail == null)
                {
                    return ApiResponse.Error("未找到要删除的提交详情。", 404);
                }

                detail.IsDeleted = true;
                _submissionDetailRepository.Update(detail);
                await _unitOfWork.SaveChangesAsync();

                return ApiResponse.Success("删除提交详情成功。", null);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"删除提交详情失败: {ex.Message}");
            }
        }

        #endregion

        #region 特殊操作

        /// <summary>
        /// 获取提交详情列表
        /// </summary>
        /// <param name="submissionId">提交ID</param>
        /// <returns>提交详情列表</returns>
        public async Task<ApiResponse> GetBySubmissionIdAsync(Guid submissionId)
        {
            try
            {
                var details = await _submissionDetailRepository.GetPagedListAsync(
                    predicate: sd => sd.SubmissionId == submissionId && !sd.IsDeleted,
                    include: i => i.Include(sd => sd.Student)
                                  .Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
                return ApiResponse.Success("获取提交详情列表成功。", detailDtos);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取提交详情列表失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取学生的提交详情
        /// </summary>
        /// <param name="studentId">学生ID</param>
        /// <param name="examId">考试ID</param>
        /// <returns>提交详情列表</returns>
        public async Task<ApiResponse> GetByStudentAndExamAsync(Guid studentId, Guid examId)
        {
            try
            {
                var details = await _submissionDetailRepository.GetPagedListAsync(
                    predicate: sd => sd.StudentId == studentId && 
                                   sd.Submission.ExamId == examId && 
                                   !sd.IsDeleted,
                    include: i => i.Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
                return ApiResponse.Success("获取学生提交详情成功。", detailDtos);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取学生提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 批量创建提交详情
        /// </summary>
        /// <param name="submissionId">提交ID</param>
        /// <param name="details">提交详情列表</param>
        /// <returns>创建结果</returns>
        public async Task<ApiResponse> BatchCreateAsync(Guid submissionId, List<SubmissionDetailDto> details)
        {
            try
            {
                var detailEntities = _mapper.Map<List<SubmissionDetail>>(details);
                foreach (var detail in detailEntities)
                {
                    detail.SubmissionId = submissionId;
                    detail.CreatedAt = DateTime.Now;
                    detail.UpdatedAt = DateTime.Now;
                    detail.IsDeleted = false;
                    await _submissionDetailRepository.InsertAsync(detail);
                }

                await _unitOfWork.SaveChangesAsync();
                var result = _mapper.Map<List<SubmissionDetailDto>>(detailEntities);
                return ApiResponse.Success("批量创建提交详情成功。", result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"批量创建提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 批量更新提交详情
        /// </summary>
        /// <param name="details">提交详情列表</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResponse> BatchUpdateAsync(List<SubmissionDetailDto> details)
        {
            try
            {
                var detailIds = details.Select(d => d.Id).ToList();
                var existingDetails = await _submissionDetailRepository.GetAllAsync(
                    predicate: sd => detailIds.Contains(sd.Id) && !sd.IsDeleted);

                foreach (var detail in details)
                {
                    var existingDetail = existingDetails.FirstOrDefault(sd => sd.Id == detail.Id);
                    if (existingDetail != null)
                    {
                        _mapper.Map(detail, existingDetail);
                        existingDetail.UpdatedAt = DateTime.Now;
                        _submissionDetailRepository.Update(existingDetail);
                    }
                }

                await _unitOfWork.SaveChangesAsync();
                return ApiResponse.Success("批量更新提交详情成功。", null);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"批量更新提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 更新提交详情评分
        /// </summary>
        /// <param name="detailId">提交详情ID</param>
        /// <param name="points">分数</param>
        /// <param name="feedback">反馈</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResponse> UpdateScoreAsync(Guid detailId, float? points, string? feedback)
        {
            try
            {
                var detail = await _submissionDetailRepository.GetFirstOrDefaultAsync(
                    predicate: sd => sd.Id == detailId && !sd.IsDeleted);

                if (detail == null)
                {
                    return ApiResponse.Error("未找到提交详情。", 404);
                }

                detail.PointsAwarded = points;
                detail.TeacherFeedback = feedback;
                detail.UpdatedAt = DateTime.Now;

                _submissionDetailRepository.Update(detail);
                await _unitOfWork.SaveChangesAsync();

                var result = _mapper.Map<SubmissionDetailDto>(detail);
                return ApiResponse.Success("更新评分成功。", result);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"更新评分失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取错题详情
        /// </summary>
        /// <param name="studentId">学生ID</param>
        /// <param name="examId">考试ID</param>
        /// <returns>错题详情列表</returns>
        public async Task<ApiResponse> GetErrorDetailsAsync(Guid studentId, Guid examId)
        {
            try
            {
                var details = await _submissionDetailRepository.GetPagedListAsync(
                    predicate: sd => sd.StudentId == studentId && 
                                   sd.Submission.ExamId == examId && 
                                   sd.IsCorrect == false &&
                                   !sd.IsDeleted,
                    include: i => i.Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
                return ApiResponse.Success("获取错题详情成功。", detailDtos);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取错题详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取正确题详情
        /// </summary>
        /// <param name="studentId">学生ID</param>
        /// <param name="examId">考试ID</param>
        /// <returns>正确题详情列表</returns>
        public async Task<ApiResponse> GetCorrectDetailsAsync(Guid studentId, Guid examId)
        {
            try
            {
                var details = await _submissionDetailRepository.GetPagedListAsync(
                    predicate: sd => sd.StudentId == studentId && 
                                   sd.Submission.ExamId == examId && 
                                   sd.IsCorrect == true &&
                                   !sd.IsDeleted,
                    include: i => i.Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
                return ApiResponse.Success("获取正确题详情成功。", detailDtos);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取正确题详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取未批改的提交详情
        /// </summary>
        /// <param name="teacherId">教师ID</param>
        /// <returns>未批改的提交详情列表</returns>
        public async Task<ApiResponse> GetUngradedDetailsAsync(Guid teacherId)
        {
            try
            {
                var submissions = await _submissionRepository.GetPagedListAsync(
                    predicate: s => s.GraderId == teacherId && 
                                   s.Status == SubmissionStatus.Submitted &&
                                   !s.IsDeleted);

                var submissionIds = submissions.Items.Select(s => s.Id).ToList();

                var details = await _submissionDetailRepository.GetPagedListAsync(
                    predicate: sd => submissionIds.Contains(sd.SubmissionId) && 
                                   sd.PointsAwarded == null &&
                                   !sd.IsDeleted,
                    include: i => i.Include(sd => sd.Student)
                                  .Include(sd => sd.ExamQuestion)
                                      .ThenInclude(aq => aq.Question));

                var detailDtos = _mapper.Map<List<SubmissionDetailDto>>(details.Items);
                return ApiResponse.Success("获取未批改的提交详情成功。", detailDtos);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"获取未批改的提交详情失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 批量更新提交详情状态
        /// </summary>
        /// <param name="submissionId">提交ID</param>
        /// <param name="status">状态</param>
        /// <returns>更新结果</returns>
        public async Task<ApiResponse> UpdateStatusAsync(Guid submissionId, SubmissionStatus status)
        {
            try
            {
                var details = await _submissionDetailRepository.GetAllAsync(
                    predicate: sd => sd.SubmissionId == submissionId && !sd.IsDeleted);

                foreach (var detail in details)
                {
                    detail.UpdatedAt = DateTime.Now;
                    _submissionDetailRepository.Update(detail);
                }

                await _unitOfWork.SaveChangesAsync();
                return ApiResponse.Success("批量更新状态成功。", null);
            }
            catch (Exception ex)
            {
                return ApiResponse.Error($"批量更新状态失败: {ex.Message}");
            }
        }

        #endregion
    }
}
