using Tiobon.Core.IServices;
using Tiobon.Core.Model.Models;
using Tiobon.Core.Services.BASE;
using Tiobon.Core.IRepository.Base;
using Tiobon.Core.Common.Caches;
using Newtonsoft.Json.Linq;
using Tiobon.Core.Common;
using Tiobon.Core.Model;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using System.Net;
using Tiobon.Core.Common.Helper;
using AgileObjects.AgileMapper.Extensions;
using SqlSugar;
using Tiobon.Core.DataAccess;
using System.Data;

namespace Tiobon.Core.Services;

/// <summary>
/// 考试记录 (服务)
/// </summary>
public class Ghre_ExamRecordServices : BaseServices<Ghre_ExamRecord, Ghre_ExamRecordDto, InsertGhre_ExamRecordInput, EditGhre_ExamRecordInput>, IGhre_ExamRecordServices
{
    private readonly IBaseRepository<Ghre_ExamRecord> _dal;
    //private readonly IGhre_ExamPaperServices _ghre_ExamPaperServices;
    public Ghre_ExamRecordServices(ICaching caching,
        //IGhre_ExamPaperServices ghre_ExamPaperServices,
        IBaseRepository<Ghre_ExamRecord> dal)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
        //_ghre_ExamPaperServices = ghre_ExamPaperServices;
    }

    public override async Task<ServicePageResult<Ghre_ExamRecordDto>> QueryFilterPage(QueryBody filter, string condition, bool? IsEnable = true)
    {
        if (string.IsNullOrWhiteSpace(filter.orderBy))
            filter.orderBy = "CreateTime1 DESC";

        if (filter.pageSize == 0)
            filter.pageSize = 10000;

        var countSql = @$" SELECT COUNT(1) FROM Ghre_ExamRecord_V";
        var sql = @$" SELECT *
                    FROM Ghre_ExamRecord_V";

        string conditions = " WHERE  IsEnable = 1";

        if (!string.IsNullOrEmpty(condition)) conditions += " AND " + condition;
        if (filter.jsonParam != null)
            foreach (JProperty jProperty in filter.jsonParam.Properties())
            {
                var name = jProperty.Name;
                var value = jProperty.Value.ToString();
                if (name == "page" || name == "pageSize")
                    continue;

                if (name == "DueDate")
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);
                    conditions += $" AND FORMAT(DueDate, 'yyyy-MM-dd') = '{jsonParam.columnValue}'";
                    continue;

                }
                if (!string.IsNullOrWhiteSpace(value))
                {
                    var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);

                    switch (jsonParam.operationKey)
                    {
                        case "Include":
                            conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "NotInclude":
                            conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'";
                            break;
                        case "IsNull":
                            conditions += $" AND {name} IS NULL";
                            break;
                        case "NotNull":
                            conditions += $" AND {name} IS NOT NULL";
                            break;
                        case "Equal":
                            conditions += $" AND {name} ='{jsonParam.columnValue}'";
                            break;
                        case "NotEqual":
                            conditions += $" AND {name} !='{jsonParam.columnValue}'";
                            break;
                        default:
                            break;
                    }
                }
            }

        sql += conditions;
        countSql += conditions;
        int total = await Db.Ado.GetIntAsync(countSql);

        sql = "SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY " + filter.orderBy + ") NUM FROM (SELECT * FROM (" + sql + " ";
        sql += ") A ) B ) C";

        sql += " WHERE NUM <= " + filter.pageNum * filter.pageSize + " AND NUM >" + (filter.pageNum - 1) * filter.pageSize;

        var entitys = await Db.Ado.SqlQueryAsync<Ghre_ExamRecordDto>(sql);

        entitys.ForEach(async x =>
        {
            x.ScoreStatus = await GetParaLabel("TrainingExamScoreStatus", x.ScoreStatus);
            //x.CourseStatusLabel = await GetParaLabel("TrainingCourseStatus", x.CourseStatus);
            //x.StudyStatusLabel = await GetParaLabel("TrainingStudyStatus", x.StudyStatus);
            x.IsPassLabel = x.IsPass == true ? "合格" : "不合格";

            //x.InStatusLabel = x.InStatus == "1" ? "在职" : null;
            //x.InStatusLabel = x.InStatus == "2" ? "离职" : null;
            //x.InStatusLabel = x.InStatus == "0" ? "未入职" : null;
            if (x.BeginTime != null)
                x.ExamDate = x.BeginTime.Value.ToString("yyyy-MM-dd");


            x.TotalScore += x.Score ?? 0;
            x.TotalScore += x.AdjustScore ?? 0;
            //if (x.DueDate != null)
            //    x.DueDate1 = x.DueDate.Value.ToString("yyyy-MM-dd");
            //if (x.ExamDate != null)
            //    x.ExamDate1 = x.ExamDate.Value.ToString("yyyy-MM-dd");

        });

        return new ServicePageResult<Ghre_ExamRecordDto>(filter.pageNum, total, filter.pageSize, entitys);

    }

    public async Task<ServicePageResult<Ghre_ExamRecordDto>> Query(string examId, QueryBody body)
    {
        return await QueryFilterPage(body, $"ExamId='{examId}'");
    }

    public async Task<ServiceResult> ModifyAdjustScore(string examRecordId, EditGhre_ExamRecordInput edit)
    {
        var entity = await QuerySingle(examRecordId);

        var paper = await Db.Queryable<Ghre_ExamPaper>().FirstAsync(x => x.Id == entity.ExamPaperId);
        if (paper == null)
            return ServiceResult.OprateFailed("该考试管理的试卷已被删除，暂不可变更调整分！");

        entity.AdjustScore = edit.AdjustScore;
        //entity.Score += entity.AdjustScore;

        string score1 = Regex.Replace(entity.Score.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(entity.Score.ToString(), @"\.(0+)$", "");
        if (entity.Score < 0)
            return ServiceResult.OprateFailed($"调整后得分为【{score1}】,得分不可小于0！");
        if (entity.Score > paper.TotalScore)
            return ServiceResult.OprateFailed($"调整后得分为【{score1}】,不可大于卷面总分【{Regex.Replace(paper.TotalScore.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(paper.TotalScore.ToString(), @"\.(0+)$", "")}】！");

        var paperId = entity.ExamPaperId;
        var examPaper = await Db.Queryable<Ghre_ExamPaper>().Where(x => x.Id == paperId).FirstAsync();
        if (examPaper != null)
            entity.IsPass = examPaper.PassScore > (entity.Score + entity.AdjustScore) ? false : true;

        await Update(entity);

        return ServiceResult.OprateSuccess("修改成功！");

        //return await QueryFilterPage(body, $"ExamId='{examId}'");
    }
    public async Task<ServiceResult<Ghre_ExamRecordExtend>> ExtendAsync(long examRecordId)
    {
        var extend = new Ghre_ExamRecordExtend();
        var record = await QuerySingle(x => x.Id == examRecordId);

        var details = await Db.Queryable<Ghre_ExamRecordDetail>().Where(x => x.ExamRecordId == record.Id).ToListAsync();
        var detailIds = details.Select(x => x.Id).ToList();
        var recordAnswers = await Db.Queryable<Ghre_ExamRecordAnswer>()
            .OrderBy(x => x.TaxisNo)
            .Where(x => x.ExamRecordDetailId != null && detailIds.Contains(x.ExamRecordDetailId.Value))
            .ToListAsync();
        if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE)
            await ExamHelper.SystemMarkAsync(Db, record, details, recordAnswers);

        var exampaper = await Db.Queryable<Ghre_ExamPaper>().FirstAsync(x => x.Id == record.ExamPaperId);
        var baseData = new DefaultGhre_ExamPaperBaseData();
        baseData.PaperNo = exampaper.PaperNo;
        baseData.PaperName = exampaper.PaperName;
        baseData.AnswerTime = exampaper.AnswerTime;
        baseData.ScoreMethod = exampaper.ScoreMethod;
        baseData.TotalScore = exampaper.TotalScore;
        baseData.PassScore = exampaper.PassScore;
        baseData.RetakeTimes = exampaper.RetakeTimes;
        baseData.RemarkSz = exampaper.RemarkSz;
        baseData.LinkType = exampaper.LinkType;
        baseData.CourseId = exampaper.LinkType == "CourseId" ? exampaper.LinkId : null;
        baseData.CourseSceneId = exampaper.LinkType == "CourseSceneId" ? exampaper.LinkId : null;
        extend.baseData = baseData;


        extend.styleInfo.coverImage = exampaper.CoverUrl;
        extend.styleInfo.paperStyle = exampaper.Style;
        extend.styleInfo.coverBackGround = exampaper.CoverBackGround;

        var questions = await Db.Queryable<Ghre_ExamPaperQuestion>().Where(x => x.ExamPaperId == exampaper.Id).ToListAsync();
        var previews = questions.Where(x => x.QuestionId != null).Select(x => new DefaultGhre_ExamPaperPreview()
        {
            Id = x.Id,
            ConfigId = x.ConfigId,
            parentId = x.ConfigId,
            QuestionId = x.QuestionId.Value,
            ExamPaperId = x.ExamPaperId,
            Score = x.Score,
            RealScore = details.Where(m => m.QuestionId == x.QuestionId).Sum(m => (m.Score ?? 0) + (m.AdjustScore ?? 0))
        }).ToList();

        var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList();

        var questions1 = 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)).OrderBy(x => x.TaxisNo).ToListAsync(); ;

        previews.ForEach(x =>
        {
            var answers1 = answers.Where(y => y.QuestionId == x.QuestionId).ToList();
            x.QuestionType = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionType;
            x.QuestionContent = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionContent;
            if (!string.IsNullOrEmpty(x.QuestionContent))
                x.QuestionContent = WebUtility.HtmlDecode(x.QuestionContent);
            var detail = new FromGhre_QuestionQuestionTypeDetail();
            detail.content = x.QuestionContent;
            detail.difficulty = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.DifficultyLevel;
            detail.answer = answers1.Where(x => x.IsCorrect == true).FirstOrDefault()?.QuestionNo;
            detail.answer1 = answers1.Where(x => x.IsCorrect == true).Select(x => x.QuestionNo).ToList();
            detail.answerList = answers1.Select(x => new FromGhre_QuestionQuestionAnswerList()
            {
                No = x.QuestionNo,
                label = x.AnswerContent,
                imageUrl = x.ImageUrl,
                imgWidthPc = x.ImageWidthPc,
                imgWidthApp = x.ImageWidthApp,
            }).ToList();

            x.detail = detail;

            var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id);
            switch (x.QuestionType)
            {
                case "Completion":
                case "ShortAnswer":
                    var answerIds1 = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId == null).Select(m => m.AnswerContent).ToList();
                    answerIds1.ForEach(m =>
                    {
                        x.value1.Add(m);
                    });
                    if (x.value1.Any())
                        x.value = x.value1.First();

                    break;
                default:
                    var answerIds = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId != null).Select(m => m.QuestionAnswerId).ToList();

                    answers1.Where(m => answerIds.Contains(m.Id)).ForEach(m =>
                    {
                        x.value1.Add(m.QuestionNo);

                    });
                    if (x.value1.Any())
                        x.value = x.value1.First();
                    break;
            }

        });

        extend.questionList = previews;

        string sql = @$"SELECT StaffNo,
                               StaffName,
                               dbo.FO_DeptInfo (DeptID,
                                                getdate (),
                                                1,
                                                'DeptNo') DeptNo,
                               dbo.FO_DeptInfo (DeptID,
                                                getdate (),
                                                1,
                                                'DeptFullPateName') DepteName
                        FROM Ghra_Staff
                        WHERE StaffID = {record.StaffId}";

        extend.StaffInfo = await Db.Ado.SqlQuerySingleAsync<StaffInfo>(sql);
        extend.StaffInfo.StaffScore = record.Score != null ? record.Score.Value : 0;

        sql = @$"SELECT A.StaffNo,
                       A.StaffName,
                       dbo.FO_DeptInfo (A.DeptID,
                                        getdate (),
                                        1,
                                        'DeptNo') DeptNo,
                       dbo.FO_DeptInfo (A.DeptID,
                                        getdate (),
                                        1,
                                        'DeptFullPateName') DepteName,
                       A.PhotoUrl,
                       B.TitleName
                FROM Ghra_Staff A LEFT JOIN Ghra_Title B ON B.TitleID = A.TitleID
                WHERE A.StaffID = {record.StaffId}";

        extend.CommentData = await Db.Ado.SqlQuerySingleAsync<CommentData>(sql);

        if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE)
            extend.CommentData.IsFirstTime = true;
        extend.CommentData.Comment = record.Comment;

        var body = new QueryBody();
        body.pageNum = 1;
        body.pageSize = 10000;
        var records = await QueryFilterPage(body, $"ExamId='{record.ExamId}'");
        var records1 = records.result.DT_TableDataT1;
        int index = records1.FindIndex(x => x.Id == examRecordId);

        extend.PreviousRecordId = index - 1 >= 0 && records1.Count > 1 ? records1[index - 1].Id : null;
        extend.NextRecordId = records1.Count > index + 1 ? records1[index + 1].Id : null;


        return ServiceResult<Ghre_ExamRecordExtend>.OprateSuccess("查询成功！", extend);
    }

    public async Task<ServiceResult> CommentAsync(Ghre_ExamRecordExtend extend, long examRecordId)
    {

        var record = await QuerySingle(x => x.Id == examRecordId);
        record.Score = extend.StaffInfo.StaffScore;
        record.ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.HAS_SCORE;
        record.Comment = extend.CommentData.Comment;
        var details = await Db.Queryable<Ghre_ExamRecordDetail>().Where(x => x.ExamRecordId == record.Id).ToListAsync();

        extend.questionList.ForEach(x =>
        {
            var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id);
            recordDetail.Score = x.RealScore;
            recordDetail.IsCorrect = x.Score == x.RealScore ? true : false;
        });

        var paperId = record.ExamPaperId;
        var examPaper = await Db.Queryable<Ghre_ExamPaper>().Where(x => x.Id == paperId).FirstAsync();
        if (examPaper != null)
            record.IsPass = examPaper.PassScore > (record.Score + record.AdjustScore) ? false : true;

        await Db.Updateable(record).ExecuteCommandAsync();
        await Db.Updateable(details).ExecuteCommandAsync();

        return ServiceResult.OprateSuccess("提交成功！");
    }

    public async Task<ServiceResult<QueryExam>> QueryExamAsync(long id)
    {
        var extend = new QueryExam();
        var body = new QueryBody();
        body.pageNum = 1;
        body.pageSize = 10000;

        long examRecordId = 0;
        //if (await Db.Queryable<Ghre_Exam>().AnyAsync(x => x.Id == id))
        //{
        //    var examRecord = await Db.Queryable<Ghre_ExamRecord>().FirstAsync(x => x.ExamId == id);
        //    if (examRecord != null)
        //        examRecordId = examRecord.Id;
        //    else
        //    {
        //        var insrt = new InsertGhre_ExamRecordInput()
        //        {

        //        };
        //        examRecordId = await base.Add(insrt);
        //    }
        //}

        if (await Db.Queryable<Ghre_StudyRecord>().AnyAsync(x => x.Id == id))
        {
            var examRecord = await Db.Queryable<Ghre_ExamRecord>().FirstAsync(x => x.StudyRecordId == id);

            if (!examRecord.IsNull())
                examRecordId = examRecord.Id;
            else
            {

                var studyRecord = await Db.Queryable<Ghre_StudyRecord>().FirstAsync(x => x.Id == id);

                var exam = await Db.Queryable<Ghre_Exam>()
                    .Where(x => x.Id == studyRecord.ExamId)
                    .FirstAsync(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED);
                if (exam.IsNull())
                    exam = await Db.Queryable<Ghre_Exam>()
                        .Where(x => x.Status == Consts.DIC_EXAM_STATUS.RELEASED
                        && ((x.DateType == Consts.DicExamDateType.EXAM_DATE
                        && x.BeginTime.Value.Date <= DateTime.Now.Date && x.EndTime.Value.Date >= DateTime.Now.Date) || x.DateType == Consts.DicExamDateType.AFTER_HOW_LONG))
                        .WhereIF(!studyRecord.CourseId.IsNull(), x => x.CourseId == studyRecord.CourseId)
                        .WhereIF(!studyRecord.CourseSceneId.IsNull(), x => x.CourseSceneId == studyRecord.CourseSceneId)
                        .FirstAsync();

                if (exam.IsNull())
                    return ServiceResult<QueryExam>.OprateFailed("该门课程尚未开启考试，请联系HR ！");

                var insrt = new InsertGhre_ExamRecordInput()
                {
                    ExamId = exam.Id,
                    StudyRecordId = studyRecord.Id,
                    StaffId = studyRecord.StaffId,
                    CourseSnapId = studyRecord.CourseSnapId,
                    ExamPaperId = exam.ExamPaperId,
                    ExamDate = DateTime.Now.Date,
                    RetakeTimes = 0,
                    Status = Consts.DIC_EXAM_RECORD_STATUS.WAIT,
                    ScoreStatus = Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE,
                    BeginTime = exam.BeginTime,
                    EndTime = exam.EndTime
                };
                examRecordId = await base.Add(insrt);

                if (studyRecord.ExamId.IsNull())
                {
                    string sql = $@"UPDATE Ghre_StudyRecord SET ExamId={exam.Id} WHERE Id='{studyRecord.Id}'; ";
                    await Db.Ado.ExecuteCommandAsync(sql);
                }
            }
        }

        if (examRecordId == 0) examRecordId = id;

        var records = await QueryFilterPage(body, $"Id='{examRecordId}'");

        if (!records.result.DT_TableDataT1.Any())
            return ServiceResult<QueryExam>.OprateFailed("无效的考试ID！");

        var record = records.result.DT_TableDataT1.FirstOrDefault();

        var details = await Db.Queryable<Ghre_ExamRecordDetail>().Where(x => x.ExamRecordId == record.Id).ToListAsync();
        var detailIds = details.Select(x => x.Id).ToList();
        var recordAnswers = await Db.Queryable<Ghre_ExamRecordAnswer>()
            .OrderBy(x => x.TaxisNo)
            .Where(x => x.ExamRecordDetailId != null && detailIds.Contains(x.ExamRecordDetailId.Value))
            .ToListAsync();
        //if (record.ScoreStatus == "NoScore")
        //    await ExamHelper.SystemMarkAsync(Db, record, details, recordAnswers);

        var exampaper = await Db.Queryable<Ghre_ExamPaper>().FirstAsync(x => x.Id == record.ExamPaperId);
        var baseData = new DefaultGhre_ExamPaperBaseData();
        baseData.PaperNo = exampaper.PaperNo;
        baseData.PaperName = exampaper.PaperName;
        baseData.AnswerTime = exampaper.AnswerTime;
        baseData.ScoreMethod = exampaper.ScoreMethod;
        baseData.TotalScore = exampaper.TotalScore;
        baseData.PassScore = exampaper.PassScore;
        baseData.RetakeTimes = exampaper.RetakeTimes;
        baseData.RemarkSz = exampaper.RemarkSz;
        baseData.LinkType = exampaper.LinkType;
        baseData.CourseId = exampaper.LinkType == "CourseId" ? exampaper.LinkId : null;
        baseData.CourseSceneId = exampaper.LinkType == "CourseSceneId" ? exampaper.LinkId : null;
        extend.baseData = baseData;


        extend.styleInfo.coverImage = exampaper.CoverUrl;
        extend.styleInfo.paperStyle = exampaper.Style;
        extend.styleInfo.coverBackGround = exampaper.CoverBackGround;

        var questions = await Db.Queryable<Ghre_ExamPaperQuestion>().Where(x => x.ExamPaperId == exampaper.Id).ToListAsync();
        var previews = questions.Where(x => x.QuestionId != null).Select(x => new DefaultGhre_ExamPaperPreview()
        {
            Id = x.Id,
            ConfigId = x.ConfigId,
            parentId = x.ConfigId,
            QuestionId = x.QuestionId.Value,
            ExamPaperId = x.ExamPaperId,
            Score = x.Score,
            RealScore = details.Where(m => m.QuestionId == x.QuestionId).Sum(m => (m.Score ?? 0) + (m.AdjustScore ?? 0))
        }).ToList();

        var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList();

        var questions1 = 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)).OrderBy(x => x.TaxisNo).ToListAsync(); ;

        previews.ForEach(x =>
        {
            var answers1 = answers.Where(y => y.QuestionId == x.QuestionId).ToList();
            x.QuestionType = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionType;
            x.QuestionContent = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.QuestionContent;
            if (!string.IsNullOrEmpty(x.QuestionContent))
                x.QuestionContent = WebUtility.HtmlDecode(x.QuestionContent);
            var detail = new FromGhre_QuestionQuestionTypeDetail();
            detail.content = x.QuestionContent;
            detail.difficulty = questions1.FirstOrDefault(a => a.Id == x.QuestionId)?.DifficultyLevel;
            //detail.answer = answers1.Where(x => x.IsCorrect == true).FirstOrDefault()?.QuestionNo;
            //detail.answer1 = answers1.Where(x => x.IsCorrect == true).Select(x => x.QuestionNo).ToList();
            detail.answerList = answers1.Select(x => new FromGhre_QuestionQuestionAnswerList()
            {
                No = x.QuestionNo,
                label = x.AnswerContent,
                imageUrl = x.ImageUrl,
                imgWidthPc = x.ImageWidthPc,
                imgWidthApp = x.ImageWidthApp,
            }).ToList();

            x.detail = detail;

            var recordDetail = details.FirstOrDefault(m => m.ExamPaperQuestionId == x.Id);
            switch (x.QuestionType)
            {
                case "Completion":
                case "ShortAnswer":
                    var answerIds1 = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId == null).Select(m => m.AnswerContent).ToList();
                    answerIds1.ForEach(m =>
                    {
                        x.value1.Add(m);
                    });
                    if (x.value1.Any())
                        x.value = x.value1.First();

                    break;
                default:
                    var answerIds = recordAnswers.Where(m => m.ExamRecordDetailId == recordDetail?.Id && m.QuestionAnswerId != null).Select(m => m.QuestionAnswerId).ToList();

                    answers1.Where(m => answerIds.Contains(m.Id)).ForEach(m =>
                    {
                        x.value1.Add(m.QuestionNo);

                    });
                    if (x.value1.Any())
                        x.value = x.value1.First();
                    break;
            }

        });

        extend.questionList = previews;

        extend.StaffNo = record.StaffNo;
        extend.StaffName = record.StaffName;
        extend.DeptNo = record.StaffNo;
        extend.DeptName = record.DepteName;
        extend.StaffPhoto = record.StaffPhotoUrl;
        extend.ExamName = record.ExamName + "(" + record.ExamNo + ")";
        extend.ExamBeginDate = DateTimeHelper.ConvertToMiniuteString(record.BeginTime);
        extend.ExamEndDate = DateTimeHelper.ConvertToMiniuteString(record.EndTime);
        extend.ExamStatus = record.Status;
        extend.TotalScore = record.TotalScore;
        extend.Id = record.Id;
        extend.CourseName = record.CourseName;
        extend.CanRetake = true;

        if (extend.ExamStatus == Consts.DIC_EXAM_RECORD_STATUS.EXAM_END)
            extend.ScoreOut = false;

        //TimeSpan timeDifference = record.EndTime.Value - DateTime.Now;
        //extend.RemainingSecond = Convert.ToInt32(timeDifference.TotalSeconds);
        //if (extend.RemainingSecond < 0) extend.RemainingSecond = 0;
        extend.RemainingSecond = 3600;
        if (!exampaper.AnswerTime.IsNull())
            extend.RemainingSecond = exampaper.AnswerTime.Value * 60;

        if (!record.ActualEndTime.IsNull())
        {
            TimeSpan timeDifference = record.ActualEndTime.Value - record.ActualBeginTime.Value;

            extend.UsageTime = $"{timeDifference.Minutes}分{timeDifference.Seconds}秒";
        }

        return ServiceResult<QueryExam>.OprateSuccess("查询成功！", extend);
    }

    public async Task<ServiceResult> StartExamAsync(long examRecordId)
    {
        var entity = await base.QuerySingle(examRecordId);

        if (entity is null)
            return ServiceResult.OprateFailed("无效的考试ID！");

        #region 试卷 引用次数
        if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.WAIT)
        {
            string sql = $"UPDATE Ghre_ExamPaper SET LinkTimes = ISNULL(LinkTimes, 0)+1 WHERE Id={entity.ExamPaperId}";
            await Db.Ado.ExecuteCommandAsync(sql);
        }
        #endregion

        if (entity.ActualBeginTime is null)
            entity.ActualBeginTime = DateTime.Now;
        if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.WAIT)
            entity.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAM_END;



        await Update(entity, new List<string>()
        {
            "ActualBeginTime",
            "Status"
        });

        return ServiceResult.OprateSuccess("成功！");
    }


    public async Task<ServiceResult> RetakeExamAsync(long examRecordId)
    {
        var entity = await base.QuerySingle(examRecordId);

        if (entity is null)
            return ServiceResult.OprateFailed("无效的考试ID！");

        if (entity.Status == Consts.DIC_EXAM_RECORD_STATUS.EXAM_END)
            entity.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAMING;

        entity.RetakeTimes = entity.RetakeTimes is null ? 1 : entity.RetakeTimes + 1;

        await Update(entity, new List<string>()
        {
            "Status","RetakeTimes"
        });

        return ServiceResult.OprateSuccess("成功！");
    }
    public async Task<ServiceResult> AnswerExamAsync(List<DefaultGhre_ExamPaperPreview> answers, long studyRecordId)
    {
        var record = await base.QuerySingle(x => x.Id == studyRecordId);
        if (record is null) return ServiceResult.OprateFailed("无效的考试ID");
        using var _context = ContextFactory.CreateContext();

        string sql = $@"UPDATE Ghre_ExamRecordDetail set IsEnable=0 where ExamRecordId='{record.Id}';
                        UPDATE Ghre_ExamRecordAnswer set IsEnable=0 where ExamRecordId='{record.Id}';";
        await Db.Ado.ExecuteCommandAsync(sql);

        var questionIds = answers.Select(x => x.QuestionId).ToList();
        var questionAnswers = await Db.Queryable<Ghre_QuestionAnswer>().Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)).OrderBy(x => x.TaxisNo).ToListAsync(); ;

        var staff = await Db.Queryable<Ghrs_User>().Where(x => x.UserId == App.User.ID).FirstAsync();

        var recordDetails = new List<Ghre_ExamRecordDetail>();
        var recordDetailAnswers = new List<Ghre_ExamRecordAnswer>();
        answers.ForEach(answer =>
        {
            long id = SnowFlakeSingle.instance.getID();

            recordDetails.Add(new Ghre_ExamRecordDetail()
            {
                Id = id,
                CreateTime = DateTime.Now,
                ExamRecordId = record.Id,
                ExamPaperId = answer.ExamPaperId,
                ExamPaperQuestionId = answer.Id,
                QuestionId = answer.QuestionId,
                StaffId = staff?.UserStaffID,
                Score = 0,
                AdjustScore = 0
            });
            var questionAnswers1 = questionAnswers.Where(x => x.QuestionId == answer.QuestionId).ToList();
            switch (answer.QuestionType)
            {
                case "TrueOrFalse":
                case "Single":
                    recordDetailAnswers.Add(new Ghre_ExamRecordAnswer()
                    {
                        Id = SnowFlakeSingle.instance.getID(),
                        CreateTime = DateTime.Now,
                        ExamRecordDetailId = id,
                        ExamRecordId = record.Id,
                        QuestionAnswerId = questionAnswers1.First(x => x.QuestionNo == answer.value)?.Id,
                    });
                    break;
                case "Multiple":
                    var TaxisNo = 100;
                    foreach (var value in answer.value1)
                    {
                        recordDetailAnswers.Add(new Ghre_ExamRecordAnswer()
                        {
                            Id = SnowFlakeSingle.instance.getID(),
                            CreateTime = DateTime.Now,
                            ExamRecordDetailId = id,
                            ExamRecordId = record.Id,
                            QuestionAnswerId = questionAnswers1.First(x => x.QuestionNo == value)?.Id,
                            TaxisNo = TaxisNo
                        });
                        TaxisNo += 100;
                    }
                    break;
                case "Completion":
                    var TaxisNo1 = 100;
                    foreach (var value in answer.value1)
                    {
                        recordDetailAnswers.Add(new Ghre_ExamRecordAnswer()
                        {
                            Id = SnowFlakeSingle.instance.getID(),
                            CreateTime = DateTime.Now,
                            ExamRecordDetailId = id,
                            ExamRecordId = record.Id,
                            AnswerContent = value,
                            TaxisNo = TaxisNo1
                        });
                        TaxisNo1 += 100;
                    }
                    break;
                case "ShortAnswer":
                    recordDetailAnswers.Add(new Ghre_ExamRecordAnswer()
                    {
                        Id = SnowFlakeSingle.instance.getID(),
                        CreateTime = DateTime.Now,
                        ExamRecordId = record.Id,
                        ExamRecordDetailId = id,
                        AnswerContent = answer.value
                    });
                    break;
                default:

                    break;
            }
        });

        await _context.Ghre_ExamRecordDetail.AddRangeAsync(recordDetails);
        await _context.Ghre_ExamRecordAnswer.AddRangeAsync(recordDetailAnswers);

        await _context.SaveChangesAsync();

        record.Status = Consts.DIC_EXAM_RECORD_STATUS.EXAM_END;
        record.ActualEndTime = DateTime.Now;

        #region 打分
        if (record.ScoreStatus == Consts.DIC_EXAM_RECORD_SCORE_STATUS.NO_SCORE && record.Status == Consts.DIC_EXAM_RECORD_STATUS.EXAM_END)
            await ExamHelper.SystemMarkAsync(Db, record, recordDetails, recordDetailAnswers);
        _context.Ghre_ExamRecordDetail.UpdateRange(recordDetails);
        _context.Ghre_ExamRecordAnswer.UpdateRange(recordDetailAnswers);
        await _context.SaveChangesAsync();
        #endregion

        await Update(record, new List<string> { "Status", "Score", "ActualEndTime" }, null, $"Id='{record.Id}'");
        return ServiceResult.OprateSuccess("提交成功！");
    }
}