using Exam.Infrastructure.Data.Entity;
using Exam.Infrastructure.Extensions;
using Hotline.Application.Exam.Extensions;
using Hotline.Share.Enums.Exams;
using Hotline.Share.Requests.TestPaper;
using JiebaNet.Segmenter.Common;
using System.Linq.Expressions;
using Hotline.Application.Exam.Core.Utilities;
using Hotline.Exams.ExamManages;
using Hotline.Exams.Questions;
using Hotline.Exams.TestPapers;
using ExamQuestion = Hotline.Exams.Questions.ExamQuestion;

namespace Hotline.Application.Exam.QueryExtensions.TestPapers
{
    public static class TestPaperQueryExtensions
    {
        public static Expression<Func<ExamTestPaper,bool>> GetExpression(this TestPaperPagedRequest testPaperPagedRequest)
        {
            Expression<Func<ExamTestPaper, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamTestPaper>()
                .AndIF(testPaperPagedRequest.Name.IsNotNullOrEmpty(), x => x.Name.Contains(testPaperPagedRequest.Name))
                .AndIF(testPaperPagedRequest.Code.IsNotNullOrEmpty(), x => x.Code.Contains(testPaperPagedRequest.Code))
                .AndIF(testPaperPagedRequest.Status.IsNotNull(), x => x.Status == testPaperPagedRequest.Status)
                .AndIF(testPaperPagedRequest.ExamMode.IsNotNull(), x => x.Mode == testPaperPagedRequest.ExamMode)
                .AndIF(testPaperPagedRequest.ExamType.IsNotNull(), x => x.ExamType == testPaperPagedRequest.ExamType)
                .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamTestPaperRule, bool>> GetTestPaperRuleExpression(this EntityQueryRequest entityQueryRequest)
        {
            Expression<Func<ExamTestPaperRule, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamTestPaperRule>()
                .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.TestPaperId == entityQueryRequest.Id)
                .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.TestPaperId))
                .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamTestPaper,bool>> GetTestPaperCountExpression(this TestPaperQuestionCountRequest testPaperQuestionCountRequest)
        {
            Expression<Func<ExamTestPaper, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamTestPaper>()
               .AndIF(testPaperQuestionCountRequest.TestPaperId.IsNotNullOrEmpty(), x => x.Id == testPaperQuestionCountRequest.TestPaperId)
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamExtractRule, bool>> GetExpression(this TestPaperQuestionCountRequest testPaperQuestionCountRequest)
        {
            Expression<Func<ExamExtractRule, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamExtractRule>()
               .AndIF(testPaperQuestionCountRequest.ExtractRuleId.IsNotNullOrEmpty(), x => x.Id == testPaperQuestionCountRequest.ExtractRuleId)
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamTestPaperRule,bool>> GetTestPaperRuleExpression(this TestPaperQuestionCountRequest testPaperQuestionCountRequest)
        {
            Expression<Func<ExamTestPaperRule, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamTestPaperRule>()
               .AndIF(testPaperQuestionCountRequest.TestPaperId.IsNotNullOrEmpty(), x => x.TestPaperId == testPaperQuestionCountRequest.TestPaperId)
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamTestPaperItem,bool>> GetTestPaperItemsExpression(this TestPaperQuestionCountRequest testPaperQuestionCountRequest)
        {
            Expression<Func<ExamTestPaperItem, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamTestPaperItem>()
               .AndIF(testPaperQuestionCountRequest.TestPaperId.IsNotNullOrEmpty(), x => x.TestPaperId == testPaperQuestionCountRequest.TestPaperId)
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamQuestionTag,bool>> GetExpression(this TagQuestionCountRequest tagQuestionCountRequest)
        {
            Expression<Func<ExamQuestionTag, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamQuestionTag>()
               .AndIF(tagQuestionCountRequest.TagIds.IsNotNullOrEmpty() && tagQuestionCountRequest.TagIds.Any(), x => tagQuestionCountRequest.TagIds.Contains(x.TagId))
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamQuestion,bool>> GetQuestionExpression(this TagQuestionCountRequest tagQuestionCountRequest)
        {
            Expression<Func<ExamQuestion, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamQuestion>()
               .AndIF(tagQuestionCountRequest.QuestionType.IsNotNull(), x => tagQuestionCountRequest.QuestionType ==x.QuestionType)
               .AndIF(tagQuestionCountRequest.DifficultyLevel.IsNotNull(),x=> tagQuestionCountRequest.DifficultyLevel == x.DifficultyLevel)
               .AndIF(tagQuestionCountRequest.QuestionIds.IsNotNullOrEmpty(), x => !tagQuestionCountRequest.QuestionIds.Contains(x.Id))
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamQuestionTag, bool>> GetExpression(this TestPaperQuestionRequest testPaperQuestionRequest)
        {
            Expression<Func<ExamQuestionTag, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamQuestionTag>()
               .AndIF(testPaperQuestionRequest.TagIds.IsNotNullOrEmpty(), x => testPaperQuestionRequest.TagIds.Contains(x.TagId))
               .ToExpression();

            return expression;
        }

        public static Expression<Func<ExamQuestion, bool>> GetQuestionExpression(this TestPaperQuestionRequest testPaperQuestionRequest)
        {
            Expression<Func<ExamQuestion, bool>> expression = m => m.Id != null;

            expression = ExpressionableUtility.CreateExpression<ExamQuestion>()
               .AndIF(testPaperQuestionRequest.QuestionType.IsNotNull(), x => testPaperQuestionRequest.QuestionType == x.QuestionType)
               .AndIF(testPaperQuestionRequest.DifficultyLevel.IsNotNull(), x => testPaperQuestionRequest.DifficultyLevel == x.DifficultyLevel)
               .AndIF(testPaperQuestionRequest.QuestionIds.IsNotNullOrEmpty(), x => !testPaperQuestionRequest.QuestionIds.Contains(x.Id))
               .ToExpression();

            return expression;
        }
    }
}
