using MathNet.Numerics.Distributions;
using System.Text.RegularExpressions;

namespace Tiobon.Core.Services;

/// <summary>
/// 问卷调查 (服务)
/// </summary>
public class Ghre_SurveyServices : BaseServices<Ghre_Survey, Ghre_SurveyDto, InsertGhre_SurveyInput, EditGhre_SurveyInput>, IGhre_SurveyServices
{
    private readonly IBaseRepository<Ghre_Survey> _dal;
    public Ghre_SurveyServices(ICaching caching, IBaseRepository<Ghre_Survey> dal)
    {
        this._dal = dal;
        base.BaseDal = dal;
        base._caching = caching;
    }


    public override async Task<ServicePageResult<Ghre_SurveyDto>> QueryFilterPage(QueryBody filter, string condition, bool? IsEnable = true)
    {

        var result = await base.QueryFilterPage(filter, condition, IsEnable);

        result.result.DT_TableDataT1.ForEach(async x =>
        {
            x.SurveyClass = await GetParaLabel("TrainSurveyClass", x.SurveyClass);

        });

        return result;
    }

    public override async Task<long> Add(InsertGhre_SurveyInput entity)
    {
        var result = await base.Add(entity);

        return result;
    }

    public override async Task<bool> Update(long Id, EditGhre_SurveyInput editModel)
    {
        var result = await base.Update(Id, editModel, null, ["Status"]);
        return result;
    }

    public override async Task<ServiceFormResult<Ghre_SurveyDto>> QueryForm(QueryForm body)
    {
        var result = await base.QueryForm(body);
        return result;
    }

    public async Task<ServiceResult<InsertGhre_SurveyExtend>> QueryData(long id)
    {
        var entity = await base.QueryById(id);
        var data = Mapper.Map(entity).ToANew<InsertGhre_SurveyExtend>();

        data.BeginEndTime.Add(data.BeginTime);
        data.BeginEndTime.Add(data.EndTime);
        if (entity.StaffId.IsNotEmptyOrNull())
            data.StaffIds = JsonHelper.JsonToObj<List<int>>(entity.StaffId);
        if (entity.DeptId.IsNotEmptyOrNull())
            data.DeptIds = JsonHelper.JsonToObj<List<int>>(entity.DeptId);

        var questions = await Db.Queryable<Ghre_SurveyQuestion>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();
        var options = await Db.Queryable<Ghre_SurveyOption>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();

        data.Questions = Mapper.Map(questions).ToANew<List<InsertGhre_SurveyQuestionExtend>>();
        data.Questions.ForEach(x =>
        {
            x.Options = Mapper.Map(options.Where(o => o.SurveyQuestionId == x.Id)).ToANew<List<InsertGhre_SurveyOptionExtend>>();
        });
        return ServiceResult<InsertGhre_SurveyExtend>.OprateSuccess("成功", data);
    }
    public async Task<ServiceResult<long>> InsertByStatus(InsertGhre_SurveyInput insertModel, string status)
    {

        var data = ServiceResult<long>.OprateSuccess("新增成功", 0);
        insertModel.Status = status;
        var id = await Add(insertModel);

        data.Success = id > 0;
        if (data.Success)
            data.Data = id;
        else
            return ServiceResult<long>.OprateFailed("失败！");

        return data;
    }

    public async Task<ServiceResult> UpdateStatus(InsertGhre_SurveyInput input, string status)
    {

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

        var entities = new List<Ghre_Survey>();
        foreach (var id in input.Ids)
        {
            if (!BaseDal.Any(id))
                continue;

            var entity = await BaseDal.QueryById(id);

            if (entity.Status == "Publish" && status == "Temporary")
                if (await Db.Queryable<Ghre_OpenClass>().Where(x => x.FeedbackId == id || x.ParentFeedbackId == id).AnyAsync())
                    throw new Exception($"问卷【{entity.SurveyName}】已被开班引用，暂不可取消发布！");
            entity.UpdateIP = ip;
            entity.UpdateProg = api;
            entity.Status = status;
            entities.Add(entity);
        }

        var result = await BaseDal.Update(entities);
        return ServiceResult.OprateSuccess("执行成功！");

    }


    public async Task<ServiceResult<long>> InsertData(long id, InsertGhre_SurveyExtend insertModel)
    {

        if (insertModel.BeginEndTime != null && insertModel.BeginEndTime.Count == 2)
        {
            insertModel.BeginTime = insertModel.BeginEndTime[0];
            insertModel.EndTime = insertModel.BeginEndTime[1];
        }

        var data = ServiceResult<long>.OprateSuccess("新增成功", id);
        if (id == 0)
        {

            var insert = Mapper.Map(insertModel).ToANew<InsertGhre_SurveyInput>();
            insert.Status = "Temporary";

            if (insertModel.StaffIds != null && insertModel.StaffIds.Any())
                insert.StaffId = JsonHelper.ObjToJson(insertModel.StaffIds);

            if (insertModel.DeptIds != null && insertModel.DeptIds.Any())
                insert.DeptId = JsonHelper.ObjToJson(insertModel.DeptIds);

            id = await Add(insert);

            for (int i = 0; i < insertModel.Questions.Count; i++)
            {
                var question = Mapper.Map(insertModel.Questions[i]).ToANew<Ghre_SurveyQuestion>();
                //question.Id = SnowFlakeSingle.instance.getID();

                question.SurveyId = id;
                question.SortNo = i;
                var questionId = await Db.Insertable(question).ExecuteReturnSnowflakeIdAsync();

                for (int j = 0; j < insertModel.Questions[i].Options.Count; j++)
                {
                    var option = Mapper.Map(insertModel.Questions[i].Options[j]).ToANew<Ghre_SurveyOption>();
                    option.SurveyId = id;
                    option.SurveyQuestionId = questionId;
                    option.SortNo = j;
                    await Db.Insertable(option).ExecuteReturnSnowflakeIdAsync();
                }
            }
            data.Data = id;
        }
        else
        {
            await Db.Deleteable<Ghre_SurveyQuestion>().Where(x => x.SurveyId == id).ExecuteCommandAsync();
            await Db.Deleteable<Ghre_SurveyOption>().Where(x => x.SurveyId == id).ExecuteCommandAsync();


            var insert = Mapper.Map(insertModel).ToANew<EditGhre_SurveyInput>();


            if (insertModel.StaffIds != null && insertModel.StaffIds.Any())
                insert.StaffId = JsonHelper.ObjToJson(insertModel.StaffIds);

            if (insertModel.DeptIds != null && insertModel.DeptIds.Any())
                insert.DeptId = JsonHelper.ObjToJson(insertModel.DeptIds);
            await Update(id, insert, null, ["Status"]);

            for (int i = 0; i < insertModel.Questions.Count; i++)
            {
                var question = Mapper.Map(insertModel.Questions[i]).ToANew<Ghre_SurveyQuestion>();
                //question.Id = SnowFlakeSingle.instance.getID();

                question.SurveyId = id;
                var questionId = await Db.Insertable(question).ExecuteReturnSnowflakeIdAsync();

                for (int j = 0; j < insertModel.Questions[i].Options.Count; j++)
                {
                    var option = Mapper.Map(insertModel.Questions[i].Options[j]).ToANew<Ghre_SurveyOption>();
                    option.SurveyId = id;
                    option.SurveyQuestionId = questionId;
                    await Db.Insertable(option).ExecuteReturnSnowflakeIdAsync();
                }
            }
            data.Message = "修改成功！";
        }
        return data;
    }


    public async Task<ServiceResult<Ghre_SurveyExtend>> QueryESSData(long id, long? openClassId = null)
    {
        long? feedbackId = null;
        if (openClassId != null)
        {
            if (await Db.Queryable<Ghre_OpenClassFeedback>().Where(x => x.Source == "ParentTeacher" && (x.Id == id || x.Id == openClassId)).AnyAsync())
            {
                var feedback = await Db.Queryable<Ghre_OpenClassFeedback>().Where(x => x.Source == "ParentTeacher" && (x.Id == id || x.Id == openClassId)).FirstAsync();
                feedbackId = feedback.Id;
                openClassId = feedback.OpenClassId;
                id = feedback.SurveyId.Value;
            }
            else
            {
                if (!await Db.Queryable<Ghre_OpenClassFeedback>()
                    .Where(x => x.Source == "Trainee"
                    && (x.SurveyId == id || x.Id == openClassId)
                    && x.OpenClassId == openClassId).AnyAsync())
                {

                    var openClass = await Db.Queryable<Ghre_OpenClass>().Where(x => x.Id == openClassId).FirstAsync();
                    var feedback = new Ghre_OpenClassFeedback()
                    {
                        OpenClassId = openClassId,
                        SurveyId = id,
                        StaffId = App.User.StaffId,
                        Source = "Trainee",
                        EffectiveTime = DateTime.Now,
                        ExpiryTime = DateTime.MaxValue,
                        TeacherId = openClass.TeacherId,
                        CourseBeginTime = openClass.StartTime,
                        CourseEndTime = openClass.EndTime,
                        CourseId = openClass.LinkId,
                        Status = "N",
                        Score = 0
                    };
                    feedbackId = await Db.Insertable(feedback).ExecuteReturnSnowflakeIdAsync();
                }
                else feedbackId = await Db.Queryable<Ghre_OpenClassFeedback>()
                    .Where(x => x.Source == "Trainee"
                    && (x.SurveyId == id || x.Id == openClassId)
                    && x.OpenClassId == openClassId).Select(x => x.Id).FirstAsync();
            }
        }

        var entity = await base.QueryById(id);


        var data = Mapper.Map(entity).ToANew<Ghre_SurveyExtend>();

        data.BeginEndTime.Add(data.BeginTime);
        data.BeginEndTime.Add(data.EndTime);
        if (entity.StaffId.IsNotEmptyOrNull())
            data.StaffIds = JsonHelper.JsonToObj<List<int>>(entity.StaffId);
        if (entity.DeptId.IsNotEmptyOrNull())
            data.DeptIds = JsonHelper.JsonToObj<List<int>>(entity.DeptId);

        var questions = await Db.Queryable<Ghre_SurveyQuestion>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();
        var options = await Db.Queryable<Ghre_SurveyOption>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();

        data.Questions = Mapper.Map(questions).ToANew<List<Ghre_SurveyQuestionExtend>>();
        data.Questions.ForEach(x =>
        {
            x.Options = Mapper.Map(options.Where(o => o.SurveyQuestionId == x.Id)).ToANew<List<Ghre_SurveyOptionExtend>>();
        });

        #region 是否存在已提交问卷数据
        data.IsSubmit = await Db.Queryable<Ghre_SurveyRecord>()
            .Where(x => x.StaffId == App.User.StaffId && x.SurveyId == id)
            .WhereIF(openClassId != null, x => x.OpenClassId == openClassId)
            .WhereIF(openClassId != null && feedbackId != null, x => x.OpenClassId == openClassId && x.OpenClassFeedbackId == feedbackId)
            .AnyAsync();
        #endregion

        #region 处理已提交信息
        if (data.IsSubmit)
        {
            var recordId = await Db.Queryable<Ghre_SurveyRecord>()
                .Where(x => x.StaffId == App.User.StaffId && x.SurveyId == id)
                .WhereIF(openClassId != null, x => x.OpenClassId == openClassId)
                .WhereIF(openClassId != null && feedbackId != null, x => x.OpenClassId == openClassId && x.OpenClassFeedbackId == feedbackId)
                .Select(x => x.Id).FirstAsync();

            var recordDetails = await Db.Queryable<Ghre_SurveyRecordDetail>().Where(x => x.SurveyRecordId == recordId).ToListAsync();
            var recordOptions = await Db.Queryable<Ghre_SurveyRecordOption>().Where(x => x.SurveyRecordId == recordId).OrderBy(x => x.OptionContent).ToListAsync();

            data.Questions.ForEach(question =>
            {
                switch (question.QuestionType)
                {
                    case "Multiple":
                    case "MultipleScore":
                        question.Value1 = recordOptions.Where(x => x.SurveyQuestionId == question.Id).Select(x => x.OptionContent).ToList();

                        if (question.Options.Where(x => question.Value1.Contains(x.OptionNo) && x.IsOther == true).Any())
                            question.Options.ForEach(o =>
                            {
                                if (question.Value1.Contains(o.OptionNo) && o.IsOther == true)
                                    o.OtherContent = recordOptions.Where(x => x.SurveyQuestionId == question.Id && x.SurveyQuestionOptionId == o.Id)
                                    .Select(x => x.Reverse1).FirstOrDefault() ?? "";
                            });
                        break;

                    case "Single":
                    case "ShortAnswer":
                    case "SingleScore":
                    case "Rate":
                    case "Scale":
                        question.Value = recordOptions.Where(x => x.SurveyQuestionId == question.Id).Select(x => x.OptionContent).FirstOrDefault() ?? "";
                        if (question.Options.Where(x => x.OptionNo == question.Value && x.IsOther == true).Any())
                            question.Options.ForEach(o =>
                            {
                                if (o.OptionNo == question.Value && o.IsOther == true)
                                    o.OtherContent = recordOptions.Where(x => x.SurveyQuestionId == question.Id).Select(x => x.Reverse1).FirstOrDefault() ?? "";
                            });
                        break;

                    default:
                        break;
                }
            });

        }
        #endregion

        return ServiceResult<Ghre_SurveyExtend>.OprateSuccess("成功", data);
    }


    public async Task<ServiceResult> SubmitESSData(long id, Ghre_SurveyExtend input, long? openClassId = null)
    {
        long? feedbackId = null;
        if (await Db.Queryable<Ghre_OpenClassFeedback>().Where(x => x.Source == "ParentTeacher" && (x.Id == id || x.Id == openClassId)).AnyAsync())
        {
            var feedback = await Db.Queryable<Ghre_OpenClassFeedback>().Where(x => x.Source == "ParentTeacher" && (x.Id == id || x.Id == openClassId)).FirstAsync();
            feedbackId = feedback.Id;
            openClassId = feedback.OpenClassId;
            id = feedback.SurveyId.Value;
        }
        else
            feedbackId = await Db.Queryable<Ghre_OpenClassFeedback>()
                      .Where(x => x.Source == "Trainee"
                      && (x.SurveyId == id || x.Id == openClassId)
                      && x.OpenClassId == openClassId).Select(x => x.Id).FirstAsync();

        var entity = await base.QueryById(id);


        var lastRecord = await Db.Queryable<Ghre_SurveyRecord>()
            .Where(x => x.StaffId == App.User.StaffId && x.SurveyId == id)
            .WhereIF(openClassId != null, x => x.OpenClassId == openClassId)
            .WhereIF(openClassId != null && feedbackId != null, x => x.OpenClassFeedbackId == feedbackId)
            .FirstAsync();
        var surveyRecordId = lastRecord?.Id;
        await Db.Updateable<Ghre_SurveyRecord>()
            .SetColumns(it => new Ghre_SurveyRecord() { IsEnable = 0 }, true)
            .Where(x => x.StaffId == App.User.StaffId && x.SurveyId == id && x.IsEnable == 1 && x.SubmitDate != null)
           .ExecuteCommandAsync();
        await Db.Updateable<Ghre_SurveyRecordDetail>()
            .SetColumns(it => new Ghre_SurveyRecordDetail() { IsEnable = 0 }, true)
            .Where(x => x.SurveyRecordId == surveyRecordId)
           .ExecuteCommandAsync();
        await Db.Updateable<Ghre_SurveyRecordOption>()
            .SetColumns(it => new Ghre_SurveyRecordOption() { IsEnable = 0 }, true)
            .Where(x => x.SurveyRecordId == surveyRecordId)
           .ExecuteCommandAsync();

        var questions = await Db.Queryable<Ghre_SurveyQuestion>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();
        var options = await Db.Queryable<Ghre_SurveyOption>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();

        //var recordId = SnowFlakeSingle.Instance.NextId();

        if (lastRecord.IsNullOrEmpty() || (lastRecord != null && lastRecord.SubmitDate != null) || surveyRecordId == 0)
        {

            var record = new Ghre_SurveyRecord()
            {
                //Id = recordId,
                SurveyId = id,
                StaffId = App.User.StaffId,
                Score = 0,
                AdjustScore = 0,
                SubmitDate = DateTime.Now,
                IsView = false,
                OpenClassId = openClassId,
                OpenClassFeedbackId = feedbackId
            };
            surveyRecordId = await Db.Insertable(record).ExecuteReturnSnowflakeIdAsync();
        }
        else
        {
            await Db.Updateable<Ghre_SurveyRecord>()
                .SetColumns(it => new Ghre_SurveyRecord() { SubmitDate = DateTime.Now }, true)
                .Where(x => x.Id == surveyRecordId)
                .ExecuteCommandAsync();
        }
        decimal? totalScore = 0;
        for (int i = 0; i < input.Questions.Count; i++)
        {
            var question = input.Questions[i];

            var recordDetailId = await Db.Insertable(new Ghre_SurveyRecordDetail()
            {

                SurveyId = id,
                SurveyRecordId = surveyRecordId,
                SurveyQuestionId = question.Id,
                StaffId = App.User.StaffId,
                Score = 0

            }).ExecuteReturnSnowflakeIdAsync();
            var recordOptions = new List<Ghre_SurveyRecordOption>();
            decimal? score = 0;
            switch (question.QuestionType)
            {
                case "Multiple":
                case "MultipleScore":
                    for (int j = 0; j < question.Value1.Count; j++)
                    {
                        var option1 = new Ghre_SurveyRecordOption()
                        {
                            SurveyId = id,
                            SurveyRecordId = surveyRecordId,
                            SurveyRecordDetailId = recordDetailId,
                            SurveyQuestionId = question.Id,
                            //SurveyQuestionOptionId = x.Id,
                            StaffId = App.User.StaffId,
                            Score = 0
                        };
                        if (question.Value1.Any())
                        {
                            var questionOption1 = question.Options.Where(x => x.OptionNo == question.Value1[j]).FirstOrDefault();

                            option1.SurveyQuestionOptionId = questionOption1?.Id;
                            option1.Score = questionOption1?.Score;
                            option1.OptionContent = question.Value1[j];

                            if (questionOption1.IsOther == true)
                                option1.Reverse1 = questionOption1.OtherContent;
                        }
                        score += option1.Score;
                        await Db.Insertable(option1).ExecuteReturnSnowflakeIdAsync();
                    }

                    break;

                case "Single":
                case "SingleScore":
                    var option = new Ghre_SurveyRecordOption()
                    {
                        SurveyId = id,
                        SurveyRecordId = surveyRecordId,
                        SurveyRecordDetailId = recordDetailId,
                        SurveyQuestionId = question.Id,
                        //SurveyQuestionOptionId = x.Id,
                        StaffId = App.User.StaffId,
                        Score = 0
                    };
                    if (question.Value.IsNotEmptyOrNull())
                    {
                        var questionOption = question.Options.Where(x => x.OptionNo == question.Value).FirstOrDefault();

                        option.SurveyQuestionOptionId = questionOption?.Id;
                        option.Score = questionOption?.Score;
                        option.OptionContent = question.Value;
                        if (questionOption.IsOther == true)
                            option.Reverse1 = questionOption.OtherContent;
                        score += option.Score;
                        await Db.Insertable(option).ExecuteReturnSnowflakeIdAsync();
                    }

                    break;

                case "Rate":
                case "Scale":
                case "ShortAnswer":
                    option = new Ghre_SurveyRecordOption()
                    {
                        SurveyId = id,
                        SurveyRecordId = surveyRecordId,
                        SurveyRecordDetailId = recordDetailId,
                        SurveyQuestionId = question.Id,
                        //SurveyQuestionOptionId = x.Id,
                        StaffId = App.User.StaffId,
                        Score = 0
                    };

                    option.OptionContent = question.Value;
                    await Db.Insertable(option).ExecuteReturnSnowflakeIdAsync();

                    break;

                default:
                    break;
            }

            await Db.Updateable<Ghre_SurveyRecordDetail>()
                .SetColumns(it => new Ghre_SurveyRecordDetail() { Score = score, UpdateTime = DateTime.Now })
                .Where(it => it.Id == recordDetailId)
                .ExecuteCommandAsync();
            totalScore += score;
        }


        #region 修正反馈单
        if (feedbackId != null)
            await Db.Updateable<Ghre_OpenClassFeedback>()
                .SetColumns(it => new Ghre_OpenClassFeedback() { Score = totalScore, Status = "Y", UpdateTime = DateTime.Now })
                .Where(it => it.Id == feedbackId)
                .ExecuteCommandAsync();
        #endregion

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

    public async Task<ServiceResult> Publish(long id)
    {
        var entity = await base.QueryById(id);

        if (entity.Status == "Publish")

            return ServiceResult.OprateSuccess("发布成功！");

        await Db.Updateable<Ghre_Survey>()
          .SetColumns(it => new Ghre_Survey() { Status = "Publish" })
          .Where(x => x.Id == id)
         .ExecuteCommandAsync();

        var deptIds = new List<int>();
        var staffIds = new List<int>();

        if (entity.DeptId.IsNotEmptyOrNull())
            deptIds = JsonHelper.JsonToObj<List<int>>(entity.DeptId);


        if (entity.StaffId.IsNotEmptyOrNull())
            staffIds = JsonHelper.JsonToObj<List<int>>(entity.StaffId);


        var staffIds1 = await Db.Queryable<Ghra_Staff>().Where(x => x.DeptID != null && deptIds.Contains(x.DeptID.Value)).Select(x => x.StaffID).ToListAsync();
        staffIds.AddRange(staffIds1);
        staffIds = staffIds.Distinct().ToList();

        var userIds = await Db.Queryable<Ghrs_User>().Where(x => x.UserStaffID != null && staffIds.Contains(x.UserStaffID.Value)).Select(x => new
        {
            x.UserId,
            x.UserPhotoUrl
        }).ToListAsync();

        var ToDos = userIds.Select(x => new Ghrm_MessageToDo()
        {
            ToUserID = x.UserId,
            GroupType = "Survey",
            Tag = "问卷调查",
            DataID = 0,
            DataTable = "Ghre_Survey",
            WorkID = 0,
            Title = "问卷调查填写",
            Content = $"问卷名称:{entity.SurveyName}<br>填写时间:{DateTimeHelper.ConvertToMiniuteString(entity.BeginTime)}~{DateTimeHelper.ConvertToMiniuteString(entity.EndTime)}",
            PicType = "Url",
            JumpType = "link",
            WEBUrl = "/F_Ess_Nav_Survey/" + id,
            IsAgreeBtn = "N",
            IsRejectBtn = "N",
            SortNo = 1,
            IsDefault = 1
        }).ToList();

        await Db.Insertable(ToDos).ExecuteReturnIdentityAsync();

        return ServiceResult.OprateSuccess("发布成功！");
    }
    public async Task<ServiceResult<Ghre_SurveyStatistic>> QueryStatistic(long id)
    {
        var data = new Ghre_SurveyStatistic();
        var entity = await base.QueryById(id);
        var deptIds = new List<int>();
        var staffIds = new List<int>();

        if (entity.DeptId.IsNotEmptyOrNull())
            deptIds = JsonHelper.JsonToObj<List<int>>(entity.DeptId);

        if (entity.StaffId.IsNotEmptyOrNull())
            staffIds = JsonHelper.JsonToObj<List<int>>(entity.StaffId);

        var staffIds1 = await Db.Queryable<Ghra_Staff>().Where(x => x.DeptID != null && deptIds.Contains(x.DeptID.Value)).Select(x => x.StaffID).ToListAsync();
        staffIds.AddRange(staffIds1);
        staffIds = staffIds.Distinct().ToList();

        data.All = staffIds.Count;
        data.Has = await Db.Queryable<Ghre_SurveyRecord>().Where(x => x.SurveyId == id).CountAsync();
        data.New = await Db.Queryable<Ghre_SurveyRecord>().Where(x => x.SurveyId == id && x.SubmitDate.Value.Date == DateTime.Now.Date).CountAsync();

        var recordOptions = await Db.Queryable<Ghre_SurveyRecordOption>().Where(x => x.SurveyId == id).ToListAsync();

        var questions = await Db.Queryable<Ghre_SurveyQuestion>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();
        var options = await Db.Queryable<Ghre_SurveyOption>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();



        data.Questions = Mapper.Map(questions).ToANew<List<Ghre_SurveyStatisticQuestion>>();
        data.Questions.ForEach(x =>
        {
            if (x.QuestionType == "Rate")
            {
                //var totals = recordOptions.Where(a => a.SurveyQuestionId == x.Id).ToList();
                decimal total = recordOptions.Where(a => a.SurveyQuestionId == x.Id).Count();
                for (int i = 1; i < 6; i++)
                {
                    x.Table.Add(new Ghre_SurveyStatisticQuestionTable()
                    {
                        OptionNo = i.ObjToString(),
                        OptionContent = i.ObjToString(),

                    });
                }

                x.Table.ForEach(o =>
                {

                    o.Count = recordOptions.Where(a => a.SurveyQuestionId == x.Id && a.OptionContent == o.OptionContent).Count();
                    if (o.Count > 0 && total > 0)
                    {
                        o.Percent1 = o.Count / total;
                        o.Percent1 = o.Percent1 * 100;
                        o.Percent = $"{o.Percent1.TrimDecimalString(2)}%";
                    }
                    else
                        o.Percent = $"0%";
                });
            }
            else if (x.QuestionType == "Scale")
            {
                //var totals = recordOptions.Where(a => a.SurveyQuestionId == x.Id).ToList();
                decimal total = recordOptions.Where(a => a.SurveyQuestionId == x.Id).Count();
                for (int i = 1; i < 11; i++)
                {
                    x.Table.Add(new Ghre_SurveyStatisticQuestionTable()
                    {
                        OptionNo = i.ObjToString(),
                        OptionContent = i.ObjToString(),

                    });
                }

                x.Table.ForEach(o =>
                {

                    o.Count = recordOptions.Where(a => a.SurveyQuestionId == x.Id && a.OptionContent == o.OptionContent).Count();
                    if (o.Count > 0 && total > 0)
                    {
                        o.Percent1 = o.Count / total;
                        o.Percent1 = o.Percent1 * 100;
                        o.Percent = $"{o.Percent1.TrimDecimalString(2)}%";
                    }
                    else
                        o.Percent = $"0%";
                });
            }
            else if (x.QuestionType == "ShortAnswer")
            {
                if (x.WordCloudKeywords.IsNotEmptyOrNull())
                {
                    var recordOption = recordOptions.Where(a => a.SurveyQuestionId == x.Id).FirstOrDefault();
                    var KeywordList = x.WordCloudKeywords.Split(',');

                    x.Table = KeywordList.Select(x => new Ghre_SurveyStatisticQuestionTable
                    {
                        OptionContent = x,
                        Count = 0,
                        Percent1 = 0
                    }).ToList();

                    x.Table.ForEach(o =>
                    {
                        string keyword = o.OptionContent;

                        // 使用正则表达式匹配关键字（忽略大小写）
                        o.Count = Regex.Matches(recordOption.OptionContent, Regex.Escape(keyword), RegexOptions.None).Count;
                    });
                }
            }
            else
            {
                x.Table = Mapper.Map(options.Where(o => o.SurveyQuestionId == x.Id)).ToANew<List<Ghre_SurveyStatisticQuestionTable>>();

                decimal total = recordOptions.Where(a => a.SurveyQuestionId == x.Id).Count();
                x.Table.ForEach(o =>
                {

                    o.Count = recordOptions.Where(a => a.SurveyQuestionOptionId == o.Id).Count();
                    if (o.Count > 0 && total > 0)
                    {
                        o.Percent1 = o.Count / total;
                        o.Percent1 = o.Percent1 * 100;
                        o.Percent = $"{o.Percent1.TrimDecimalString(2)}%";
                    }
                    else
                        o.Percent = $"0%";
                });
            }
        });

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

    public async Task<ServiceResult> Start(long id)
    {
        //await Db.Updateable<Ghre_SurveyRecord>()
        // .SetColumns(it => new Ghre_SurveyRecord() { BeginTime = DateTime.Now })
        // .Where(x => x.StaffId == App.User.StaffId && x.SurveyId == id)
        // .ExecuteCommandAsync();

        var record = new Ghre_SurveyRecord()
        {
            SurveyId = id,
            StaffId = App.User.StaffId,
            Score = 0,
            AdjustScore = 0,
            IsView = false
        };
        await Db.Insertable(record).ExecuteReturnSnowflakeIdAsync();

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


    public async Task<dynamic> QueryRecord(long id)
    {
        dynamic obj = new ExpandoObject();
        dynamic data = new ExpandoObject();

        var entity = await base.QueryById(id);
        var questions = await Db.Queryable<Ghre_SurveyQuestion>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();
        var options = await Db.Queryable<Ghre_SurveyOption>().OrderBy(x => x.SortNo).Where(x => x.SurveyId == id).ToListAsync();

        data.Count = await Db.Queryable<Ghre_SurveyRecord>().Where(x => x.SurveyId == id).CountAsync();

        var records = await Db.Queryable<Ghre_SurveyRecord>().Where(x => x.SurveyId == id).ToListAsync();
        var recordOptions = await Db.Queryable<Ghre_SurveyRecordOption>().Where(x => x.SurveyId == id).ToListAsync();

        #region columns 
        var columns = new JArray();
        var item = new JObject
        {
            new JProperty("Filed", "No"),
            new JProperty("Name", "序号"),
        };
        columns.Add(item);
        item = new JObject
        {
            new JProperty("Filed", "StaffName"),
            new JProperty("Name", "填写人"),
        };
        columns.Add(item);
        item = new JObject
        {
            new JProperty("Filed", "BeginTime"),
            new JProperty("Name", "开始时间"),
        };
        columns.Add(item);
        item = new JObject
        {
            new JProperty("Filed", "SubmitTime"),
            new JProperty("Name", "提交时间"),
        };
        columns.Add(item);
        item = new JObject
        {
            new JProperty("Filed", "Duration"),
            new JProperty("Name", "提交时长"),
        };
        columns.Add(item);
        int i = 1;
        questions.ForEach(x =>
        {
            item = new JObject
            {
                new JProperty("Filed", "Question"+i),
                new JProperty("Name", "题目"+i)
            };
            columns.Add(item);
            i++;
        });
        data.Columns = columns;
        #endregion

        #region 记录
        var Records = new JArray();
        for (int j = 1; j <= records.Count; j++)
        {
            var record = records[i];
            var StaffName = await Db.Queryable<Ghra_Staff>().Where(x => x.StaffID == record.StaffId).Select(x => x.StaffID).FirstAsync();
            item = new JObject
            {
                new JProperty("No", i),
                new JProperty("StaffName", StaffName),
            };
            columns.Add(item);
        }
        #endregion

        obj.Data = data;
        obj.Success = true;
        obj.code = "0";
        obj.type = "success";
        obj.message = "查询成功！";
        obj.Status = 200;
        return obj;
    }
}

