using SqlSugar;
using Tiobon.Core.Model.Models;
using static Tiobon.Core.Model.Consts;

namespace Tiobon.Core.Common.Helper;

public class ExamHelper
{
    public static async Task SystemMarkAsync(ISqlSugarClient Db, Ghre_ExamRecord record, List<Ghre_ExamRecordDetail> details, List<Ghre_ExamRecordAnswer> recordAnswers)
    {
        var questionIds = details.Where(x => x.QuestionId != null).Select(m => m.QuestionId).Distinct().ToList();

        //var exampaperQuestions = await Db.Queryable<Ghre_ExamPaperQuestion>().Where(x => x.ExamPaperId == record.ExamPaperId).ToListAsync();

        var exampaper = await Db.Queryable<Ghre_ExamPaper>().FirstAsync(x => x.Id == record.ExamPaperId);
        var exampaperQuestions = await Db.Queryable<Ghre_ExamPaperQuestion>()
      .Where(x => (x.ExamPaperId == exampaper.Id && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.MANUAL) || (x.ExamPaperId == record.Id && exampaper.SetMethod == DIC_EXAM_PAPER_SET_METHOD.RANDOM))
      .ToListAsync();


        var questions = await Db.Queryable<Ghre_Question>().Where(x => questionIds.Contains(x.Id)).ToListAsync();
        var answers = await Db.Queryable<Ghre_QuestionAnswer>()
            .Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value) && x.IsCorrect == true)
            .ToListAsync();
        var answerIds = answers.Select(x => x.Id).ToList();
        decimal? score = 0;

        details.ForEach(detail =>
        {
            var question = questions.FirstOrDefault(x => x.Id == detail.QuestionId);
            detail.IsCorrect = false;
            detail.Score = 0;
            var exampaperQuestion = exampaperQuestions.FirstOrDefault(x => x.QuestionId == detail.QuestionId);

            switch (question.QuestionType)
            {
                case "Completion1":
                    var completionAnswers = answers.OrderBy(x => x.TaxisNo).Where(x => x.QuestionId == detail.QuestionId).ToList();
                    var contents = recordAnswers.Where(x => x.ExamRecordDetailId == detail.Id).Select(x => x.AnswerContent).ToList();
                    var count = completionAnswers.Count;
                    if (contents.Count == count)
                    {
                        for (int i = 0; i < completionAnswers.Count; i++)
                            if (completionAnswers[i].AnswerContent == contents[i])
                                count--;

                        if (count == 0)
                        {
                            score += exampaperQuestion?.Score;
                            detail.Score = exampaperQuestion?.Score;
                            detail.IsCorrect = true;
                        }
                    }
                    break;
                case "ShortAnswer1":
                    if (recordAnswers.Where(x => x.ExamRecordDetailId == detail.Id).Any())
                    {
                        var completionAnswers1 = answers.OrderBy(x => x.TaxisNo).Where(x => x.QuestionId == detail.QuestionId).ToList();
                        var content = recordAnswers.Where(x => x.ExamRecordDetailId == detail.Id).First().AnswerContent;
                        var count1 = completionAnswers1.Count;

                        if (!content.IsNull())
                            for (int i = 0; i < completionAnswers1.Count; i++)
                                if (content.IndexOf(completionAnswers1[i].AnswerContent) > -1)
                                    count1--;

                        if (count1 == 0)
                        {
                            score += exampaperQuestion?.Score;
                            detail.Score = exampaperQuestion?.Score;
                            detail.IsCorrect = true;
                        }
                    }

                    break;
                default:
                    var questionAnswerIds = recordAnswers.Where(x =>
                    x.ExamRecordDetailId == detail.Id && x.QuestionAnswerId != null &&
                    answerIds.Contains(x.QuestionAnswerId.Value)).Select(m => m.QuestionAnswerId).ToList();

                    if (questionAnswerIds.Count == answers.Where(x => x.QuestionId == detail.QuestionId).Count() &&
                    answers.Where(x => x.QuestionId == detail.QuestionId).Count() == recordAnswers.Where(x => x.ExamRecordDetailId == detail.Id).Count())
                    {
                        score += exampaperQuestion?.Score;
                        detail.Score = exampaperQuestion?.Score;
                        detail.IsCorrect = true;
                    }
                    break;
            }
        });
        record.Score = score ?? 0;

    }

    public static async Task MarkCompleteStatusAsync(ISqlSugarClient Db, Ghre_StudyRecord record)
    {
        if (record.ExamId != null)
        {
            if (await Db.Queryable<Ghre_Exam>().Where(x => x.Id == record.ExamId && x.StudyFinishedRule == DIC_EXAM_STUDY_FINISHED_RULE.STUDY_FINISHED).AnyAsync() || await Db.Queryable<Ghre_ExamRecord>().Where(x => x.StudyRecordId == record.Id && x.IsPass == true).AnyAsync())
                record.CompleteStatus = DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED;
        }
        else
        {
            if (record.CourseSceneId.IsNotEmptyOrNull())
                record.CompleteStatus = DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED;
            else if (record.CourseId != null)
            {
                var course = await Db.Queryable<Ghre_Course>().Where(x => x.Id == record.CourseId).FirstAsync();
                if (course != null)
                {
                    if (course.ExamPaperId.IsNullOrEmpty())
                        course.ExamPaperId = "[]";
                    var examPaperIds = JsonHelper.JsonToObj<List<long>>(course.ExamPaperId);

                    if (!examPaperIds.Any())
                        record.CompleteStatus = DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED; 
                }
            }
        }

        record.ReverseI1 = 0;
        await Db.Updateable(record)
            .UpdateColumns(it => new
            {
                it.ReverseI1,
                it.CompleteStatus
            }, true)
            .ExecuteCommandAsync();
    }

}
