using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using QuestionSwapDoc;
using QuestionSwapDoc.SwapQuestionModel;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YGNT.Infrastructure.Extension;
using YGNT.Infrastructure.Helper;
using YGNT.QuestionLibrary.Core.Models;
using YGNT.QuestionLibrary.Core.Testings;
using YGNT.QuestionLibrary.Questions.Dto;
using YGNT.QuestionLibrary.Testings.Dto;

namespace YGNT.QuestionLibrary.Testings
{
    /// <summary>
    /// 测验试题
    /// </summary>
    public class TestingQuestionAppService: ITestingQuestionAppService
    {

        private readonly IRepository<TestingQuestion> _testingQuestionRepository;
        private readonly IRepository<Testing> _testingRepository;
        private readonly IWebHostEnvironment _hostingEnvironment;

        public TestingQuestionAppService(IRepository<TestingQuestion> testingQuestionRepository,
            IRepository<Testing> testingRepository,
            IWebHostEnvironment hostingEnvironment)
        {
            _testingQuestionRepository = testingQuestionRepository;
            _testingRepository = testingRepository;
            _hostingEnvironment = hostingEnvironment;
        }
        /// <summary>
        /// 根据测验ID查询所有试题
        /// </summary>
        /// <param name="testingId"></param>
        /// <returns></returns>
        public async Task<List<TestingQuestionDto>> GetListAsync([Required] int testingId)
        {
            var queryable = _testingQuestionRepository.GetAll()
                .Where(x => x.TestingId == testingId);

            var result = await queryable
                    .Select(x => x.Adapt(new TestingQuestionDto()
                    {
                        ShortName = x.Question.ShortName,
                        DisciplineQuestionTypeId = x.Question.DisciplineQuestionTypeId,
                        DisciplineQuestionTypeName = x.Question.DisciplineQuestionType.Name,
                        Difficulty = x.Question.Difficulty

                    })).ToListAsync();
            return result;
        }

        /// <summary>
        /// 更新测验试题
        /// </summary>
        /// <param name="update"></param>
        /// <returns></returns>
        public async Task UpdateAsync(UpdateTestingQuestionDto update)
        {
            var oriList = _testingQuestionRepository.GetAll()
                .Where(x => x.TestingId == update.TestingId);


            foreach(var questionId in update.QuestionIds)
            {
                if (oriList.Where(i => i.QuestionId == questionId).Count() == 0)
                {
                   await _testingQuestionRepository.InsertAsync(new TestingQuestion { TestingId = update.TestingId, QuestionId = questionId });
                }
            }

            foreach(var item in oriList)
            {
                if (!update.QuestionIds.Contains(item.QuestionId))
                {
                    await _testingQuestionRepository.DeleteAsync(item.Id);
                }
            }

            var testing = await _testingRepository.GetAsync(update.TestingId);
            testing.TotalQuestion = update.QuestionIds.Count();
            await _testingRepository.UpdateAsync(testing);
        }

        #region API

        /// <summary>
        /// 根据测验ID查询所有试题 (外接口)
        /// </summary>
        /// <param name="testingId"></param>
        /// <returns></returns>
        [AbpAllowAnonymous]
        public async Task<List<TestingQuestionDto>> GetQuestionAsync([Required] int testingId)
        {
            var queryable = _testingQuestionRepository.GetAll()
                .Where(x => x.TestingId == testingId);

            var result = await queryable
                    .Select(x => x.Adapt(new TestingQuestionDto()
                    {
                        QuestionId = x.QuestionId,
                        ShortName = x.Question.ShortName,
                        DisciplineQuestionTypeId = x.Question.DisciplineQuestionTypeId,
                        DisciplineQuestionTypeName = x.Question.DisciplineQuestionType.Name,
                        Difficulty = x.Question.Difficulty,
                        QuestionCategory = x.Question.QuestionOrigin.QuestionCategory,
                        Analysis = x.Question.QuestionOrigin.Analysis,
                        Answer = x.Question.QuestionOrigin.Answer,

                        Resolve = x.Question.QuestionOrigin.Resolves
                        .Where(f => f.ResolveType == ResolveType.题干 || f.ResolveType == ResolveType.选项 || f.ResolveType == ResolveType.题干和选项)
                        .OrderBy(f => f.ResolveType)
                        .ThenBy(f => f.Sort)
                        .Select(f => new ResolveDto()
                        {
                            Html = f.Html,
                            IsAnswer = f.IsAnswer,
                            QuestionOriginId = f.QuestionOriginId,
                            ResolveType = f.ResolveType
                        }).ToList()
                    })).ToListAsync();

            return result;
        }

        #endregion
    }
}
