using AutoMapper;
using Entities.Contracts;
using Entities.DTO;
using Microsoft.EntityFrameworkCore;
using SharedDATA.Api;

namespace TechHelper.Services.Beta
{
    public class GradeService : IGradeService
    {
        private readonly IUnitOfWork _work;
        private readonly IMapper _mapper;

        public GradeService(IUnitOfWork work, IMapper mapper)
        {
            _work = work;
            _mapper = mapper;
        }

        public async Task<ApiResponse> GetAllAsync(QueryParameter query)
        {
            try
            {
                var repository = _work.GetRepository<Grade>();

                if (query.Search != null && !string.IsNullOrWhiteSpace(query.Search))
                {
                    var grades = await repository.GetPagedListAsync(
                        predicate: g => g.GradeName.Contains(query.Search),
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var gradeDtosFiltered = _mapper.Map<IEnumerable<GradeDto>>(grades);
                    return new ApiResponse(true, gradeDtosFiltered);
                }
                else
                {
                    var grades = await repository.GetPagedListAsync(
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var gradeDtos = _mapper.Map<IEnumerable<GradeDto>>(grades);
                    return new ApiResponse(true, gradeDtos);
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取所有年级时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> GetAsync(Guid id)
        {
            try
            {
                var grade = await _work.GetRepository<Grade>().GetFirstOrDefaultAsync(
                    predicate: g => g.Id == id,
                    include: i => i.Include(g => g.School));

                if (grade == null)
                {
                    return new ApiResponse("年级未找到。");
                }

                var gradeDto = _mapper.Map<GradeDto>(grade);
                return new ApiResponse(true, gradeDto);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取年级时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> AddAsync(GradeDto model)
        {
            try
            {
                // 检查是否已存在相同学校下的同名年级
                var existingGrade = await _work.GetRepository<Grade>().GetFirstOrDefaultAsync(
                    predicate: g => g.SchoolId == model.SchoolId && g.GradeName == model.GradeName && g.GradeLevel == model.GradeLevel);

                if (existingGrade != null)
                {
                    return new ApiResponse($"在当前学校下，年级 '{model.GradeName}' 已存在。");
                }

                var grade = _mapper.Map<Grade>(model);
                await _work.GetRepository<Grade>().InsertAsync(grade);

                if (await _work.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, _mapper.Map<GradeDto>(grade));
                }
                return new ApiResponse("添加年级失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"添加年级时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> UpdateAsync(GradeDto model)
        {
            try
            {
                var existingGrade = await _work.GetRepository<Grade>().GetFirstOrDefaultAsync(
                    predicate: g => g.Id == model.Id);

                if (existingGrade == null)
                {
                    return new ApiResponse("年级未找到。");
                }

                _mapper.Map(model, existingGrade);
                _work.GetRepository<Grade>().Update(existingGrade);

                if (await _work.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, _mapper.Map<GradeDto>(existingGrade));
                }
                return new ApiResponse("更新年级失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"更新年级时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> DeleteAsync(Guid id)
        {
            try
            {
                var existingGrade = await _work.GetRepository<Grade>().GetFirstOrDefaultAsync(
                    predicate: g => g.Id == id);

                if (existingGrade == null)
                {
                    return new ApiResponse("年级未找到。");
                }

                _work.GetRepository<Grade>().Delete(existingGrade);

                if (await _work.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, "年级删除成功。");
                }
                return new ApiResponse("删除年级失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"删除年级时发生错误: {ex.Message}");
            }
        }
    }
}
