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

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

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

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

                if (query.Search != null && !string.IsNullOrWhiteSpace(query.Search))
                {
                    var subjects = await repository.GetPagedListAsync(
                        predicate: s => s.Name.Contains(query.Search),
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var subjectDtosFiltered = _mapper.Map<IEnumerable<TypeCommonDto>>(subjects.Items);
                    return new ApiResponse(true, subjectDtosFiltered);
                }
                else
                {
                    var subjects = await repository.GetPagedListAsync(
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var subjectDtos = _mapper.Map<IEnumerable<TypeCommonDto>>(subjects.Items);
                    return new ApiResponse(true, subjectDtos);
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取所有科目时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> GetAsync(Guid id)
        {
            try
            {
                var subject = await _work.GetRepository<Subject>().GetFirstOrDefaultAsync(
                    predicate: s => s.Id == id,
                    include: i => i
                        .Include(s => s.QuestionTypes)
                        .Include(s => s.Questions)
                        .Include(s => s.SubjectTeachers));

                if (subject == null)
                {
                    return new ApiResponse("科目未找到。");
                }

                var subjectDto = _mapper.Map<SubjectResponseDto>(subject);
                return new ApiResponse(true, subjectDto);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取科目时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> AddAsync(SubjectDto model)
        {
            try
            {
                // 检查是否已存在同名科目
                var existingSubject = await _work.GetRepository<Subject>().GetFirstOrDefaultAsync(
                    predicate: s => s.Name == model.Name);

                if (existingSubject != null)
                {
                    return new ApiResponse($"科目 '{model.Name}' 已存在。");
                }

                var subject = _mapper.Map<Subject>(model);

                await _work.GetRepository<Subject>().InsertAsync(subject);

                if (await _work.SaveChangesAsync() > 0)
                {
                    return new ApiResponse(true, subject.Id);
                }
                return new ApiResponse("添加科目失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"添加科目时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> UpdateAsync(SubjectDto model)
        {
            try
            {
                var existingSubject = await _work.GetRepository<Subject>().GetFirstOrDefaultAsync(
                    predicate: s => s.Id == model.Id);

                if (existingSubject == null)
                {
                    return new ApiResponse("科目未找到。");
                }

                // 检查是否要修改为已存在的科目名称（排除当前科目）
                var subjectWithSameName = await _work.GetRepository<Subject>().GetFirstOrDefaultAsync(
                    predicate: s => s.Name == model.Name && s.Id != model.Id);

                if (subjectWithSameName != null)
                {
                    return new ApiResponse($"科目名称 '{model.Name}' 已被其他科目使用。");
                }

                _mapper.Map(model, existingSubject);
                _work.GetRepository<Subject>().Update(existingSubject);

                if (await _work.SaveChangesAsync() > 0)
                {
                    var subjectDto = _mapper.Map<SubjectResponseDto>(existingSubject);
                    return new ApiResponse(true, subjectDto);
                }
                return new ApiResponse("更新科目失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"更新科目时发生错误: {ex.Message}");
            }
        }

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

                if (existingSubject == null)
                {
                    return new ApiResponse("科目未找到。");
                }

                _work.GetRepository<Subject>().Delete(existingSubject);

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