using MongoDB.Driver.Linq;
using System.Net;
using System.Text.RegularExpressions;

namespace Tiobon.Core.Services;

/// <summary>
/// 试卷 (服务)
/// </summary>
public class Ghre_ExamPaperServices : BaseServices<Ghre_ExamPaper, Ghre_ExamPaperDto, InsertGhre_ExamPaperInput, EditGhre_ExamPaperInput>, IGhre_ExamPaperServices
{
    private readonly IGhre_ExamPaperConfigServices _ghre_ExamPaperConfigServices;
    private readonly IGhre_ExamPaperQuestionServices _ghre_ExamPaperQuestionServices;
    private readonly IGhre_QuestionServices _ghre_QuestionServices;
    private readonly IGhrs_UserServices _ghrs_UserServices;
    private readonly IGhre_QuestionAnswerServices _ghre_QuestionAnswerServices;
    private readonly IGhre_CourseServices _ghre_CourseServices;
    private readonly IGhre_CourseSceneServices _ghre_CourseSceneServices;
    private readonly IGhre_ExamServices _ghre_ExamServices;
    private readonly IGhre_ExamRecordServices _ghre_ExamRecordServices;
    private readonly IBaseRepository<Ghre_ExamPaper> _dal;

    public Ghre_ExamPaperServices(IBaseRepository<Ghre_ExamPaper> dal,
        IGhre_ExamPaperConfigServices ghre_ExamPaperConfigServices,
        IGhre_QuestionServices ghre_QuestionServices,
        IGhre_QuestionAnswerServices ghre_QuestionAnswerServices,
        IGhre_ExamPaperQuestionServices ghre_ExamPaperQuestionServices,
        IGhre_CourseServices ghre_CourseServices,
        IGhre_CourseSceneServices ghre_CourseSceneServices,
        //IGhre_ExamServices ghre_ExamServices,
        IGhre_ExamRecordServices ghre_ExamRecordServices,
        ICaching caching,
        IGhrs_UserServices ghrs_UserServices)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
        _ghre_ExamPaperConfigServices = ghre_ExamPaperConfigServices;
        _ghre_ExamPaperQuestionServices = ghre_ExamPaperQuestionServices;
        _ghre_QuestionServices = ghre_QuestionServices;
        _ghre_QuestionAnswerServices = ghre_QuestionAnswerServices;
        _ghrs_UserServices = ghrs_UserServices;
        _ghre_CourseServices = ghre_CourseServices;
        _ghre_CourseSceneServices = ghre_CourseSceneServices;
        //_ghre_ExamServices = ghre_ExamServices;
        _ghre_ExamRecordServices = ghre_ExamRecordServices;

    }
    public override async Task<Ghre_ExamPaperDto> QueryById(object objId)
    {
        var entity = await base.QueryById(objId);
        if (entity != null)
        {
            entity.SetMethodLabel = await GetParaLabel("SetMethod", entity.SetMethod);
            entity.ScoreMethodLabel = await GetParaLabel("ScoreMethod", entity.ScoreMethod);
        }

        return entity;
    }

    //public override async Task<ServicePageResult<Ghre_ExamPaperDto>> QueryFilterPage(QueryBody body)
    //{
    //    var data = await BaseDal.QueryFilterPage(body);
    //    var data1 = Mapper.Map(data.result.DT_TableDataT1).ToANew<List<Ghre_ExamPaperDto>>();

    //    var linkIds = data1.Where(x => x.LinkId != null).Select(x => x.LinkId.Value).Distinct().ToList();
    //    var courses = await _ghre_CourseServices.Query(x => linkIds.Contains(x.Id));
    //    var courseScenes = await _ghre_CourseSceneServices.Query(x => linkIds.Contains(x.Id));

    //    data1.ForEach(async x =>
    //    {
    //        try
    //        {
    //            x.ScoreMethodLabel = await GetParaLabel("ScoreMethod", x.ScoreMethod);
    //            x.TotalScore1 = Regex.Replace(x.PassScore.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(x.TotalScore.ToString(), @"\.(0+)$", "");
    //            x.SetMethodLabel = await GetParaLabel("SetMethod", x.SetMethod);

    //            if (x.LinkType == "CourseId")
    //                x.CourseName = courses.FirstOrDefault(o => o.Id == x.LinkId)?.CourseName;
    //            else if (x.LinkType == "CourseSceneId")
    //                x.CourseName = courseScenes.FirstOrDefault(o => o.Id == x.LinkId)?.SceneName;
    //        }
    //        catch (Exception)
    //        {

    //        }

    //    });

    //    return new ServicePageResult<Ghre_ExamPaperDto>(body.pageNum, data.result.DT_TablePageInfoT1.TotalCount, body.pageSize, data1);
    //}

    public async Task<ServicePageResult<Ghre_ExamPaperDto>> QueryList(QueryBody body, string status, List<long> ids = null)
    {
        var condition = $"Status='{status}'";
        if (ids != null && ids.Any())
            condition += $" AND Id IN({string.Join(",", ids)})";

        var data = await base.QueryFilterPage(body, condition);
        var data1 = Mapper.Map(data.result.DT_TableDataT1).ToANew<List<Ghre_ExamPaperDto>>();

        var linkIds = data1.Where(x => x.LinkId != null).Select(x => x.LinkId.Value).Distinct().ToList();
        var courses = await _ghre_CourseServices.Query(x => linkIds.Contains(x.Id));
        var courseScenes = await _ghre_CourseSceneServices.Query(x => linkIds.Contains(x.Id));

        data1.ForEach(async x =>
        {
            try
            {
                x.ScoreMethodLabel = await GetParaLabel("ScoreMethod", x.ScoreMethod);
                x.TotalScore1 = Regex.Replace(x.PassScore.ToString(), @"\.(0+)$", "") + "/" + Regex.Replace(x.TotalScore.ToString(), @"\.(0+)$", "");
                x.SetMethodLabel = await GetParaLabel("SetMethod", x.SetMethod);

                if (x.LinkType == "CourseId" && courses.Any(o => o.Id == x.LinkId))
                    x.CourseName = courses.FirstOrDefault(o => o.Id == x.LinkId).CourseName + " (" + courses.FirstOrDefault(o => o.Id == x.LinkId).CourseNo + ")";
                else if (x.LinkType == "CourseSceneId" && courseScenes.Any(o => o.Id == x.LinkId))
                    x.CourseName = courseScenes.FirstOrDefault(o => o.Id == x.LinkId)?.SceneName + " (" + courseScenes.FirstOrDefault(o => o.Id == x.LinkId).SceneNo + ")"; ;
            }
            catch (Exception)
            {
            }
            x.BuiltInLabel = x.BuiltIn == 1 ? "是" : "否";
        });

        return new ServicePageResult<Ghre_ExamPaperDto>(body.pageNum, data.result.DT_TablePageInfoT1.TotalCount, body.pageSize, data1);
    }

    public async Task<ServiceResult<ExcelData>> ExportExcel(QueryExport body, string status)
    {
        QueryBody filter = new QueryBody();
        filter.pageNum = 1;
        filter.pageSize = 1000000;
        filter.langId = body.langId;

        var ids = new List<long>();
        if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any())
            ids = body.exportSet.SelectRowKeys;

        var data = await QueryList(filter, status, ids);


        string sql = $@"SELECT *
                            FROM Ghrs_PageSettingQuery
                            WHERE     IsEnable = 1
                                  AND PageNo = '{body.menuName}'
                                  AND (defaultHidden = 'false' or defaultHidden is null)
                            ORDER BY SortNo ASC";

        var columns = await Db.Ado.SqlQueryAsync<QueryExportColumn>(sql);

        var fieldDescs = new Dictionary<string, string>();
        if (body.exportSet.ExFields.Any())
            body.exportSet.ExFields.ForEach(x =>
            {
                if (columns.Any(o => o.field == x))
                    fieldDescs.Add(x, columns.FirstOrDefault(o => o.field == x)?.label);
            });
        else
            fieldDescs = columns.ToDictionary(item => item.field, item => item.label);
        var dt = ToDataTable(data.result.DT_TableDataT1, fieldDescs, null);
        // 获取所有列名
        var dtColumns = dt.Columns;

        var id = SnowFlakeSingle.instance.getID();
        var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot";
        var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}";
        if (!Directory.Exists(physicsPath + path))
            Directory.CreateDirectory(physicsPath + path);

        path = path + body.exportSet.TitleName + ".xlsx";
        NPOIHelper.ExportExcel(dt, body.exportSet.TitleName, "sheet1", physicsPath + path);
        var result = new ExcelData();
        result.filePath = path;
        result.fileName = body.exportSet.TitleName + ".xlsx";
        return ServiceResult<ExcelData>.OprateSuccess("导出成功", result);
    }

    //public async Task<ServicePageResult<Ghre_ExamPaper>> QueryFilterPage1(QueryBody filter, string status = null)
    //{
    //    if (string.IsNullOrWhiteSpace(filter.orderBy))
    //        filter.orderBy = "CreateTime DESC";
    //    RefAsync<int> totalCount = 0;
    //    var query = Db.Queryable<Ghre_ExamPaper>();
    //    if (!string.IsNullOrWhiteSpace(status))
    //        query = query.Where(x => x.Status == status);
    //    string conditions = "1=1";
    //    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 (!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;
    //                }
    //            }
    //        }
    //    if (filter.pageSize == 0)
    //        filter.pageSize = 10000;
    //    query = query.Where(conditions);
    //    var list = await query
    //        .OrderByIF(!string.IsNullOrEmpty(filter.orderBy), filter.orderBy)
    //        .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);

    //    return new ServicePageResult<Ghre_ExamPaper>(filter.pageNum, totalCount, filter.pageSize, list);
    //}

    public async Task<ServiceResult<DefaultGhre_ExamPaperInput>> QueryDefault(long Id)
    {
        var input = new DefaultGhre_ExamPaperInput();

        #region baseColumns
        var baseColumns = new List<DefaultGhre_ExamPaperColumn>
        {
            new DefaultGhre_ExamPaperColumn()
            {
                label = "试卷编号",
                field = "PaperNo",
                elementType = "Input",
                required = false,
                multipleSelect = false,
                editable = false,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "试卷名称",
                field = "PaperName",
                elementType = "Input",
                required = true,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "答题分钟",
                field = "AnswerTime",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "评分方式",
                field = "ScoreMethod",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                dataSource = "/api/Common/GetSelect/ScoreMethod?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "卷面总分",
                field = "TotalScore",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "及格分",
                field = "PassScore",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "可重考次数",
                field = "RetakeTimes",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "试卷说明",
                field = "RemarkSz",
                elementType = "InputTextArea",
                required = false,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "关联课程",
                field = "LinkType",
                elementType = "CourseRadioBox",
                required = false,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "课程名称",
                field = "CourseId",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                dataSource = "/api/Common/GetSelect/Ghre_Course?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "课程场景",
                field = "CourseSceneId",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                dataSource = "/api/Common/GetSelect/Ghre_CourseScene?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "系统内置",
                field = "BuiltIn",
                elementType = "Switch",
                required = false,
                multipleSelect = false,
                editable = true,
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "集团数据归属",
                field = "DataBelongID",
                elementType = "ApiSelect",
                required = false,
                multipleSelect = false,
                editable = true,
                dataSource = "CommonList_DataBelongAll",
                placeholder = ""
            }
        };
        #endregion

        #region randomSetColumns 
        var randomSetColumns = new List<DefaultGhre_ExamPaperColumn>
        {
             new DefaultGhre_ExamPaperColumn()
             {
                 label = "课程名称",
                field = "CourseId",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType=1,
                dataSource = "/api/Ghre_Course/QuerySelect?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "题目类型",
                field = "QuestionType",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType=2,
                dataSource = "/api/Common/GetSelect/QuestionType?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "难易程度",
                field = "DifficultyLevel",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType=2,
                width=80,
                dataSource = "/api/Common/GetSelect/DifficultyLevel?FW=DOTNETCORE"
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "数量",
                field = "Quantity",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
                width=80,
                displayType=2
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "分值",
                field = "Score",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
                width=80,
                displayType=2
            }
        };
        #endregion

        #region manualSetColumns 
        var manualSetColumns = new List<DefaultGhre_ExamPaperColumn>
        {
            new DefaultGhre_ExamPaperColumn()
             {
                label = "课程名称",
                field = "CourseId",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType=1
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "题目类型",
                field = "QuestionType",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType= 2
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "题目内容",
                field = "QuestionContent",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                displayType=2
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "难易程度",
                field = "DifficultyLevel",
                elementType = "ApiSelect",
                required = true,
                multipleSelect = false,
                editable = true,
                width=80,
                displayType=2
            },
            new DefaultGhre_ExamPaperColumn()
            {
                label = "分值",
                field = "Score",
                elementType = "InputNumber",
                required = true,
                multipleSelect = false,
                editable = true,
                width=80,
                displayType=2
            }
        };
        #endregion

        #region pageData
        if (Id == 0)
        {
            var baseData = new DefaultGhre_ExamPaperBaseData();
            baseData.PaperNo = null;
            baseData.PaperName = null;
            baseData.AnswerTime = null;
            baseData.ScoreMethod = null;
            baseData.TotalScore = null;
            baseData.PassScore = null;
            baseData.RetakeTimes = null;
            baseData.RemarkSz = null;
            baseData.LinkType = "CourseId";
            baseData.CourseId = null;
            baseData.CourseSceneId = null;
            baseData.BuiltIn = null;
            baseData.DataBelongID = null;
            input.pageData.baseData = baseData;

            input.pageData.examPaperSetType = "random";
        }
        else if (Id != 0)
        {
            var exampaper = await base.QueryById(Id);

            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.BuiltIn = exampaper.BuiltIn;
            baseData.DataBelongID = exampaper.DataBelongID;
            baseData.CourseId = exampaper.LinkType == "CourseId" ? exampaper.LinkId : null;
            baseData.CourseSceneId = exampaper.LinkType == "CourseSceneId" ? exampaper.LinkId : null;
            input.pageData.baseData = baseData;
            input.CreateDataInfo = exampaper.CreateDataInfo;
            input.UpdateDataInfo = exampaper.UpdateDataInfo;


            input.pageData.styleInfo.coverImage = exampaper.CoverUrl;
            input.pageData.styleInfo.paperStyle = exampaper.Style;
            input.pageData.styleInfo.coverBackGround = exampaper.CoverBackGround;

            input.pageData.examPaperSetType = exampaper.SetMethod;

            input.pageData.examPaperSetData = await _ghre_ExamPaperConfigServices.Query(x => x.ExamPaperId == Id, "TaxisNo ASC");

            var questions = await _ghre_ExamPaperQuestionServices.Query(x => x.ExamPaperId == Id, "TaxisNo ASC");
            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
            }).ToList();

            var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList();
            var questions1 = await _ghre_QuestionServices.Query(x => questionIds.Contains(x.Id));
            var answers = await _ghre_QuestionAnswerServices.Query(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value), "TaxisNo ASC");

            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 = questions1.Select(o =>
                //new FromGhre_QuestionQuestionTypeDetail()
                //{
                //    Id = o.Id,
                //    difficulty = o.DifficultyLevel,
                //    RemarkSz = o.QuestionAnalysis,
                //    content = o.QuestionContent,
                //}).ToList();
                //detail.ForEach(y =>
                //{
                //    y.answer = answers1.Where(x => x.IsCorrect == true).FirstOrDefault()?.QuestionNo;
                //    y.answer1 = answers1.Where(x => x.IsCorrect == true).Select(x => x.QuestionNo).ToList();
                //    y.answerList = answers.Select(x => new FromGhre_QuestionQuestionAnswerList()
                //    {
                //        No = x.QuestionNo,
                //        label = x.AnswerContent,
                //        imageUrl = x.ImageUrl,
                //        imgWidthPc = x.ImageWidthPc,
                //        imgWidthApp = x.ImageWidthApp,
                //    }).ToList();
                //});

                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;
            });

            input.pageData.previewList = previews;
        }
        #endregion

        input.baseColumns = baseColumns;
        input.randomSetColumns = randomSetColumns;
        input.manualSetColumns = manualSetColumns;
        return ServiceResult<DefaultGhre_ExamPaperInput>.OprateSuccess("查询成功！", input);
    }

    public async Task<ServiceResult<InsertExamPaperConfigInput>> InsertConfig(InsertGhre_ExamPaperConfigInput insert)
    {
        var input = new InsertExamPaperConfigInput();
        long parentId = SnowFlakeSingle.instance.getID();
        input.tableData = Mapper.Map(insert).ToANew<Ghre_ExamPaperConfig>();
        input.tableData.Id = parentId;

        if (insert.QuestionId != null)
            insert.Quantity = 1;
        string sql = $@"SELECT TOP {insert.Quantity} *,NEWID() AS GuidValue FROM Ghre_Question WHERE IsEnable=1";
        if (!string.IsNullOrWhiteSpace(insert.DifficultyLevel))
            sql += $" AND DifficultyLevel='{insert.DifficultyLevel}'";
        if (!string.IsNullOrWhiteSpace(insert.QuestionType))
            sql += $" AND QuestionType='{insert.QuestionType}'";
        if (insert.CourseId != null)
            sql += $" AND (CourseId='{insert.CourseId}' OR CourseIds like '%{insert.CourseId}%')";
        if (insert.QuestionId != null)
            sql += $" AND Id='{insert.QuestionId}'";
        sql += $" ORDER BY GuidValue ASC";
        var questions = await Db.Ado.SqlQueryAsync<Ghre_Question>(sql);


        var previews = questions.Select(x => new DefaultGhre_ExamPaperPreview()
        {
            Id = x.Id,
            parentId = parentId,
            QuestionId = x.Id,
            QuestionType = x.QuestionType,
            QuestionContent = x.QuestionContent,
        }).ToList();
        var questionIds = previews.Select(x => x.QuestionId).Distinct().ToList();
        var questions1 = await _ghre_QuestionServices.Query(x => questionIds.Contains(x.Id));
        var answers = await _ghre_QuestionAnswerServices.Query(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value), "TaxisNo ASC");

        previews.ForEach(x =>
        {
            var answers1 = answers.Where(y => y.QuestionId == x.QuestionId).ToList();
            var detail = new FromGhre_QuestionQuestionTypeDetail();
            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();
            if (!string.IsNullOrEmpty(x.QuestionContent))
                x.QuestionContent = WebUtility.HtmlDecode(x.QuestionContent);
            detail.content = x.QuestionContent;
            x.detail = detail;
        });
        input.previewList = previews;

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

    public async Task<ServiceResult<long>> Insert1(DefaultGhre_ExamPaperPageData insertModel)
    {

        ValidForm(insertModel);

        await Db.Ado.BeginTranAsync();

        try
        {
            var insert = new InsertGhre_ExamPaperInput();

            insert = Mapper.Map(insertModel.baseData).ToANew<InsertGhre_ExamPaperInput>();

            insert.PaperNo = await GenerateContinuousSequence("Ghre_ExamPaper", "PaperNo", "P");
            insert.LinkId = insertModel.baseData.LinkType == "CourseId" ? insertModel.baseData.CourseId : insertModel.baseData.CourseSceneId;
            insert.CoverUrl = insertModel.styleInfo.coverImage;
            insert.CoverBackGround = insertModel.styleInfo.coverBackGround;
            insert.Style = insertModel.styleInfo.paperStyle;
            insert.SetMethod = insertModel.examPaperSetType;
            insert.BuiltIn = insertModel.baseData.BuiltIn;
            insert.DataBelongID = insertModel.baseData.DataBelongID;
            insert.Status = "Draft";

            var id = await Add(insert);


            var configs = Mapper.Map(insertModel.examPaperSetData).ToANew<List<Ghre_ExamPaperConfig>>();
            configs.ForEach(x => x.ExamPaperId = id);
            var insertConfigs = Db.Insertable(configs);

            string sql = insertConfigs.ToSqlString();
            long row = await Db.Ado.ExecuteCommandAsync(sql);

            var questions = insertModel.previewList
                .Select(x =>
                new InsertGhre_ExamPaperQuestionInput
                {
                    ExamPaperId = id,
                    QuestionId = x.QuestionId,
                    ConfigId = x.parentId,
                }).ToList();
            int TaxisNo = 1;
            questions.ForEach(x =>
            {
                x.Score = configs.FirstOrDefault(o => o.Id == x.ConfigId)?.Score;
                x.TaxisNo = TaxisNo;
                TaxisNo++;
            });

            await _ghre_ExamPaperQuestionServices.Add(questions);

            await Db.Ado.CommitTranAsync();
            return ServiceResult<long>.OprateSuccess("新增成功！", id);
        }
        catch (Exception)
        {
            await Db.Ado.RollbackTranAsync();
            throw;
        }

    }

    public async Task<ServiceResult> Update1(long id, DefaultGhre_ExamPaperPageData insertModel)
    {

        ValidForm(insertModel);

        await Db.Ado.BeginTranAsync();

        try
        {

            Db.Ado.ExecuteCommand($@"delete from Ghre_ExamPaperConfig WHERE ExamPaperId='{id}';
delete from Ghre_ExamPaperQuestion WHERE ExamPaperId='{id}';");

            var insert = new EditGhre_ExamPaperInput();
            var paper = await base.QueryById(id);
            insert = Mapper.Map(insertModel.baseData).ToANew<EditGhre_ExamPaperInput>();
            insert.PaperNo = await GenerateContinuousSequence("Ghre_ExamPaper", "PaperNo", "P");
            insert.LinkId = insertModel.baseData.LinkType == "CourseId" ? insertModel.baseData.CourseId : insertModel.baseData.CourseSceneId;
            insert.CoverUrl = insertModel.styleInfo.coverImage;
            insert.CoverBackGround = insertModel.styleInfo.coverBackGround;
            insert.Style = insertModel.styleInfo.paperStyle;
            insert.SetMethod = insertModel.examPaperSetType;
            insert.BuiltIn = insertModel.baseData.BuiltIn;
            insert.DataBelongID = insertModel.baseData.DataBelongID;
            insert.Status = "Draft";


            #region 串联试卷和课程关系
            if (
                (insert.LinkType == "CourseId" && insert.LinkType == paper.LinkType && paper.LinkId != insert.LinkId) ||
                (insert.LinkType == "CourseSceneId" && insert.LinkType != paper.LinkType)
                )
            {
                var courses = await _ghre_CourseServices.Query(x => x.Id == paper.LinkId && x.ExamPaperId.Contains(id.ObjToString()));
                courses.ForEach(async x =>
                {
                    var ids = JsonHelper.JsonToObj<List<long?>>(x.ExamPaperId);
                    ids = ids.Where(o => o != id).ToList();
                    x.ExamPaperId = JsonHelper.ObjToJson(ids);
                    await Db.Updateable(x).UpdateColumns(it => new { it.ExamPaperId }).ExecuteCommandAsync();
                });
            }
            #endregion

            await Update(id, insert);
            var configs = Mapper.Map(insertModel.examPaperSetData).ToANew<List<Ghre_ExamPaperConfig>>();
            configs.ForEach(x => x.ExamPaperId = id);
            var insertConfigs = Db.Insertable(configs);

            string sql = insertConfigs.ToSqlString();
            long row = await Db.Ado.ExecuteCommandAsync(sql);

            var questions = insertModel.previewList
                .Select(x =>
                new InsertGhre_ExamPaperQuestionInput
                {
                    ExamPaperId = id,
                    QuestionId = x.QuestionId,
                    ConfigId = x.parentId,
                }).ToList();
            int TaxisNo = 1;
            questions.ForEach(x =>
            {
                x.Score = configs.FirstOrDefault(o => o.Id == x.ConfigId)?.Score;
                x.TaxisNo = TaxisNo;
                TaxisNo++;
            });

            await _ghre_ExamPaperQuestionServices.Add(questions);

            await Db.Ado.CommitTranAsync();
            return ServiceResult.OprateSuccess("修改成功！");
        }
        catch (Exception)
        {
            await Db.Ado.RollbackTranAsync();
            throw;
        }

    }


    public async Task<ServiceResult> UpdateStatus(long[] ids, string status)
    {
        if (status != "Released" && status != "Disabled" && status != "Draft")
            throw new Exception("无效的状态");

        HttpRequest request = UserContext.Context.Request;
        var api = request.Path.ObjToString().TrimEnd('/').ToLower();
        var ip = GetUserIp(UserContext.Context);

        List<Ghre_ExamPaper> entities = new List<Ghre_ExamPaper>();
        for (int i = 0; i < ids.Count(); i++)
        {

            var id = ids[i];
            if (!BaseDal.Any(id))
                continue;

            var entity = await BaseDal.QueryById(id);

            #region 校验数据是否被引用
            if (entity.Status == "Released" && (status == "Draft" || status == "Disabled"))//取消发布-停用
            {


                if (await Db.Queryable<Ghre_Exam>().AnyAsync(x => x.ExamPaperId == id && x.Status != "Disabled"))
                {
                    var exam = await Db.Queryable<Ghre_Exam>().FirstAsync(x => x.ExamPaperId == id && x.Status != "Disabled");
                    if (exam != null) return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】已与考试【{exam.ExamName}({exam.ExamNo})】关联，暂不可{(status == "Draft" ? "取消发布" : "停用")}");
                }

                if (await _ghre_ExamRecordServices.AnyAsync(x => x.ExamPaperId == id && x.Status == "UnderWay"))
                {
                    var exam = await _ghre_ExamRecordServices.QuerySingleDto(x => x.ExamPaperId == id && x.Status == "UnderWay");
                    if (exam != null) return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】，当前有学员正在考试中，暂不可{(status == "Draft" ? "取消发布" : "停用")}");
                }
            }

            if (status == "Released" && entity.Status != "Released")
            {
                if (entity.LinkType == "CourseId")
                {
                    if (!await _ghre_CourseServices.AnyAsync(entity.LinkId))
                        return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】，关联的课程，已被删除，请重新维护数据！");

                    var course = await _ghre_CourseServices.QueryById(entity.LinkId);
                    if (course.Status != "Released")
                        return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】，关联的课程【{course.CourseName}】，尚未被启用，请重新维护数据！");
                }


                if (entity.LinkType == "CourseSceneId" && !await _ghre_CourseSceneServices.AnyAsync(entity.LinkId))
                    return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】，关联的课程场景，已被删除，请重新维护数据！");

                string sql = @$"SELECT COUNT(0)
                                FROM Ghre_ExamPaperQuestion A
                                      JOIN Ghre_Question B ON A.QuestionId = B.Id and B.IsEnable = 0
                                WHERE  A.IsEnable = 1 AND A.ExamPaperId='{id}'";
                var count = await Db.Ado.GetIntAsync(sql);
                if (count > 0)
                    return ServiceResult.OprateFailed($"试卷【{entity.PaperName}({entity.PaperNo})】，存在关联试题被删除，暂不可发布，请重新维护数据！");
            }
            #endregion

            BasePoco ent = entity;
            ent.UpdateIP = ip;
            ent.UpdateProg = api;
            if (status == "Released" || status == "Disabled" || status == "Draft")
            {
                entity.Status = status;
                entities.Add(entity);
            }
        }



        var result = await BaseDal.Update(entities);
        if (status == "Released")
            return ServiceResult.OprateSuccess("发布成功！");
        else if (status == "Draft")
            return ServiceResult.OprateSuccess(" 已启用成功,请进入草稿箱查看！");
        else
            return ServiceResult.OprateSuccess("停用成功！");

    }

    public static void ValidForm(DefaultGhre_ExamPaperPageData model)
    {
        if (model.baseData.PassScore == 0)
            throw new Exception("及格分需大于0！");
        if (model.baseData.PassScore > model.baseData.TotalScore)
            throw new Exception("及格分需小于卷面总分！");

        if (model.baseData.AnswerTime <= 0)
            throw new Exception("答题时间需大于0！");
    }

    #region 获取通用列表下拉
    /// <summary>
    /// 获取通用列表下拉
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public async Task<ServiceResult<CommonSelect>> GetSelectAsync(long? linkId, string keyWords)
    {
        var result = new CommonSelect();
        var TableColumn = new JArray();
        var DT_TablePageInfoT1 = new JArray();
        var DT_TableDataT1 = new JArray();
        var searchItem = new JObject();
        JObject item;
        DataTable dt;
        string sql;
        searchItem = new JObject {
            new JProperty("defaultHidden", true),
            new JProperty("field", "value"),
            new JProperty("label", "试卷ID"),
        };
        TableColumn.Add(searchItem);
        searchItem = new JObject{
            new JProperty("field", "label"),
            new JProperty("label", "试卷名称"),
        };
        TableColumn.Add(searchItem);

        sql = $"SELECT Id, PaperNo, PaperName FROM Ghre_ExamPaper WHERE LinkId='{linkId}' AND Status ='Released' AND IsEnable=1";
        if (!string.IsNullOrWhiteSpace(keyWords))
            sql += $"AND ( PaperNo like '%{keyWords}%' or PaperName like '%{keyWords}%')";
        sql += $" ORDER BY CreateTime DESC";
        dt = await Db.Ado.GetDataTableAsync(sql);

        for (int i = 0; i < dt.Rows.Count; i++)
        {
            item = new JObject
            {
                new JProperty("value",long.Parse(dt.Rows[i]["Id"].ToString())),
                new JProperty("label", dt.Rows[i]["PaperName"].ToString() + "("+dt.Rows[i]["PaperNo"].ToString()+")")
            };
            DT_TableDataT1.Add(item);
        }

        item = new JObject
        {
            new JProperty("ListMax",100),
            new JProperty("ListMin",10),
            new JProperty("PageNum",1),
            new JProperty("PageSize",99999),
            new JProperty("TotalCount",dt.Rows.Count),
            new JProperty("UIType","Auto")
        };
        DT_TablePageInfoT1.Add(item);
        result.JM_TableColumnT1.TableColumn = TableColumn;
        result.DT_TableDataT1 = DT_TableDataT1;
        result.DT_TablePageInfoT1 = DT_TablePageInfoT1;
        return new ServiceResult<CommonSelect>() { Success = true, Message = "查询成功", Data = result, };
    }
    #endregion

    #region 复制

    public async Task<ServiceResult> Copy(long id)
    {

        var entity = await base.QueryById(id);
        if (entity is null)
            return ServiceResult.OprateFailed("无效的ID！");

        entity.PaperName = entity.PaperName + "_复制";
        entity.PaperNo = await GenerateContinuousSequence("Ghre_ExamPaper", "PaperNo", "P");

        entity.Status = "Draft";
        var id1 = await base.Add(Mapper.Map(entity).ToANew<InsertGhre_ExamPaperInput>());

        var configs = await _ghre_ExamPaperConfigServices.Query(x => x.ExamPaperId == id);
        var questions = await _ghre_ExamPaperQuestionServices.Query(x => x.ExamPaperId == id);

        for (int i = 0; i < configs.Count; i++)
        {
            var config = configs[i];
            config.ExamPaperId = id1;

            var configId = await _ghre_ExamPaperConfigServices.Add(Mapper.Map(config).ToANew<InsertGhre_ExamPaperConfigInput>());

            var questions1 = Mapper.Map(questions.Where(x => x.ConfigId == config.Id)).ToANew<List<InsertGhre_ExamPaperQuestionInput>>();
            questions1.ForEach(x =>
            {
                x.ConfigId = configId;
                x.ExamPaperId = id1;
            });
            await _ghre_ExamPaperQuestionServices.Add(questions1);
        }

        //var result = await BaseDal.Update(entities);
        //if (status == "Released")
        //    return ServiceResult.OprateSuccess("发布成功！");
        //else if (status == "Draft")
        //    return ServiceResult.OprateSuccess(" 已启用成功,请进入草稿箱查看！");
        //else
        //    return ServiceResult.OprateSuccess("停用成功！");
        return ServiceResult.OprateSuccess("复制成功！");
    }
    #endregion
}