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

namespace TechHelper.Services.Beta
{
    /// <summary>
    /// 教材服务实现类
    /// </summary>
    public class TextbookService : ITextbookService
    {
        private readonly IUnitOfWork _work;
        private readonly IMapper _mapper;

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

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

                if (query.Search != null && !string.IsNullOrWhiteSpace(query.Search))
                {
                    var textbooks = await repository.GetPagedListAsync(
                        predicate: t => t.Title.Contains(query.Search) || 
                                       t.Grade.ToString().Contains(query.Search) ||
                                       t.Publisher.ToString().Contains(query.Search) ||
                                       t.SubjectArea.ToString().Contains(query.Search),
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var textbookDtosFiltered = _mapper.Map<IEnumerable<TextbookResponseDto>>(textbooks.Items);
                    return new ApiResponse(true, textbookDtosFiltered);
                }
                else
                {
                    var textbooks = await repository.GetPagedListAsync(
                        pageSize: query.PageSize,
                        pageIndex: query.PageIndex
                    );
                    var textbookDtos = _mapper.Map<IEnumerable<TextbookResponseDto>>(textbooks.Items);
                    return new ApiResponse(true, textbookDtos);
                }
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取所有教材时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> GetAsync(Guid id)
        {
            try
            {
                var textbook = await _work.GetRepository<Textbook>().GetFirstOrDefaultAsync(
                    predicate: t => t.Id == id,
                    include: i => i
                        .Include(t => t.Lessons));

                if (textbook == null)
                {
                    return new ApiResponse("教材未找到。");
                }

                var textbookDto = _mapper.Map<TextbookResponseDto>(textbook);
                return new ApiResponse(true, textbookDto);
            }
            catch (Exception ex)
            {
                return new ApiResponse($"获取教材时发生错误: {ex.Message}");
            }
        }

        public async Task<ApiResponse> AddAsync(TextbookDto model)
        {
            try
            {
                // 检查是否已存在同名教材（考虑年级和学科领域）
                var existingTextbook = await _work.GetRepository<Textbook>().GetFirstOrDefaultAsync(
                    predicate: t => t.Title == model.Title && 
                                   t.Grade.ToString() == model.Grade && 
                                   t.SubjectArea.ToString() == model.SubjectArea);

                if (existingTextbook != null)
                {
                    return new ApiResponse($"教材 '{model.Title}' 在该年级和学科领域已存在。");
                }

                var textbook = _mapper.Map<Textbook>(model);

                await _work.GetRepository<Textbook>().InsertAsync(textbook);

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

        public async Task<ApiResponse> UpdateAsync(TextbookDto model)
        {
            try
            {
                var existingTextbook = await _work.GetRepository<Textbook>().GetFirstOrDefaultAsync(
                    predicate: t => t.Id == model.Id);

                if (existingTextbook == null)
                {
                    return new ApiResponse("教材未找到。");
                }

                // 检查是否要修改为已存在的教材名称（排除当前教材）
                var textbookWithSameName = await _work.GetRepository<Textbook>().GetFirstOrDefaultAsync(
                    predicate: t => t.Title == model.Title && 
                                   t.Grade.ToString() == model.Grade && 
                                   t.SubjectArea.ToString() == model.SubjectArea && 
                                   t.Id != model.Id);

                if (textbookWithSameName != null)
                {
                    return new ApiResponse($"教材名称 '{model.Title}' 在该年级和学科领域已被其他教材使用。");
                }

                _mapper.Map(model, existingTextbook);
                _work.GetRepository<Textbook>().Update(existingTextbook);

                if (await _work.SaveChangesAsync() > 0)
                {
                    var textbookDto = _mapper.Map<TextbookResponseDto>(existingTextbook);
                    return new ApiResponse(true, textbookDto);
                }
                return new ApiResponse("更新教材失败。");
            }
            catch (Exception ex)
            {
                return new ApiResponse($"更新教材时发生错误: {ex.Message}");
            }
        }

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

                if (existingTextbook == null)
                {
                    return new ApiResponse("教材未找到。");
                }

                // 检查是否有相关课程
                var hasLessons = existingTextbook.Lessons.Any();
                if (hasLessons)
                {
                    return new ApiResponse("无法删除该教材，因为它包含相关课程。");
                }

                _work.GetRepository<Textbook>().Delete(existingTextbook);

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