using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.UI;
using Mapster;
using Microsoft.EntityFrameworkCore;
using YGNT.QuestionLibrary.Core.Papers;
using YGNT.QuestionLibrary.Core.Papers.Domain;
using YGNT.QuestionLibrary.Papers.Dto;

namespace YGNT.QuestionLibrary.Papers
{
    public class ScoringAppService : IScoringAppService
    {
        private readonly IRepository<Scoring> _scoringRepository;
        private readonly IRepository<PaperQuestion, long> _paperQuestionRepository;
        private readonly IScoringManager _scoringManager;

        public ScoringAppService(IRepository<Scoring> scoringRepository, IRepository<PaperQuestion, long> paperQuestionRepository, IScoringManager scoringManager)
        {
            _scoringRepository = scoringRepository;
            _paperQuestionRepository = paperQuestionRepository;
            _scoringManager = scoringManager;
        }

        /// <summary>
        /// 获取所有的评分标准
        /// </summary>
        /// <param name="keyWord"></param>
        /// <returns></returns>
        public async Task<List<ScoringDto>> GetAllAsync(string keyWord = null)
        {
            return await _scoringRepository.GetAll()
                .WhereIf(!keyWord.IsNullOrEmpty(), x => x.Name.Contains(keyWord))
                .Select(x => x.Adapt(new ScoringDto()))
                .ToListAsync();
        }

        /// <summary>
        /// 创建新评分标准
        /// </summary>
        /// <param name="create"></param>
        /// <returns></returns>
        public async Task<int> CreateAsync(CreateScoringDto create)
        {
            var scoring = create.Adapt<Scoring>();
            return await _scoringRepository.InsertAndGetIdAsync(scoring);
        }

        /// <summary>
        /// 修改评分标准
        /// </summary>
        /// <param name="id"></param>
        /// <param name="update"></param>
        /// <returns></returns>
        public async Task UpdateAsync([Required] int id, UpdateScoringDto update)
        {
            var scoring = await _scoringRepository.GetAsync(id);

            var isUsed = await _scoringManager.CheckIsUsedAsync(id);
            if (isUsed && Math.Abs(scoring.Score - update.Score) > 0.0000001)
                throw new UserFriendlyException("当前评分标准已使用,无法再进行修改分数");
            update.Adapt(scoring);
            _scoringRepository.Update(scoring);
        }

        /// <summary>
        /// 删除评分标准
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync([Required] int id)
        {
            var isUsed = await _scoringManager.CheckIsUsedAsync(id);
            if (isUsed)
                throw new UserFriendlyException("当前评分标准已使用,无法删除");
        }
    }
}