using Azure.Cosmos;
using Azure.Messaging.ServiceBus;
using Microsoft.Azure.Documents;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Common;

namespace TEAMModelFunction
{
    public class TriggerExam
    {
        public static async void Trigger(AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
            CosmosClient client, Document input, string code, long stime, long etime, string school)
        {
            ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(input.Id, new Azure.Cosmos.PartitionKey($"{code}"));
            List<ExamClassResult> examClassResults = new List<ExamClassResult>();
            List<ExamSubject> examSubjects = new List<ExamSubject>();
            try
            {
                if (info.scope.Equals("teacher", StringComparison.OrdinalIgnoreCase) || info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{info.creatorId}") }))
                    {
                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                        {
                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                            {
                                examClassResults.Add(obj.ToObject<ExamClassResult>());
                            }
                        }
                    }
                }
                else
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c where c.examId = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamClassResult-{school}") }))
                    {
                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                        {
                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                            {
                                examClassResults.Add(obj.ToObject<ExamClassResult>());
                            }
                        }
                    }
                }


                List<ChangeRecord> records = await _azureStorage.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", input.Id }, { "PartitionKey", info.progress } });
                //处理科目信息
                List<string> sub = new List<string>();
                foreach (ExamSubject subject in info.subjects)
                {
                    sub.Add(subject.id);
                }
                //ChangeRecord record = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ChangeRecord>(input.Id, new Azure.Cosmos.PartitionKey($"{info.progress}"));
                switch (info.progress)
                {
                    case "pending":
                        var message = new ServiceBusMessage(new { id = input.Id, progress = "going", code = code }.ToJsonString());
                        message.ApplicationProperties.Add("name", "Exam");
                        if (records.Count > 0)
                        {
                            await _serviceBus.GetServiceBusClient().cancelMessage(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), records[0].sequenceNumber);
                            long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), message, DateTimeOffset.FromUnixTimeMilliseconds(stime));
                            records[0].sequenceNumber = start;
                            await _azureStorage.SaveOrUpdate<ChangeRecord>(records[0]);
                            //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}"));
                        }
                        else
                        {
                            long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), message, DateTimeOffset.FromUnixTimeMilliseconds(stime));
                            ChangeRecord changeRecord = new ChangeRecord
                            {
                                RowKey = input.Id,
                                PartitionKey = "pending",
                                sequenceNumber = start,
                                msgId = message.MessageId
                            };
                            await _azureStorage.Save<ChangeRecord>(changeRecord);
                            //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
                        }
                        break;
                    case "going":
                        (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school);
                        List<StuActivity> stuActivities = new List<StuActivity>();
                        List<StuActivity> tmdActivities = new List<StuActivity>();
                        try
                        {
                            if (tmdids.IsNotEmpty())
                            {
                                tmdids.ForEach(x =>
                                {
                                    tmdActivities.Add(new StuActivity
                                    {
                                        pk = "Activity",
                                        id = info.id,
                                        code = $"Activity-{x}",
                                        type = "Exam",
                                        name = info.name,
                                        startTime = info.startTime,
                                        endTime = info.endTime,
                                        scode = info.code,
                                        scope = info.scope,
                                        school = info.school,
                                        creatorId = info.creatorId,
                                        subjects = sub,
                                        blob = null,
                                        owner = info.owner

                                    });
                                });
                            }
                            if (studentss.IsNotEmpty())
                            {
                                studentss.ForEach(x =>
                                {
                                    stuActivities.Add(new StuActivity
                                    {
                                        pk = "Activity",
                                        id = info.id,
                                        code = $"Activity-{info.school}-{x.id}",
                                        type = "Exam",
                                        name = info.name,
                                        startTime = info.startTime,
                                        endTime = info.endTime,
                                        scode = info.code,
                                        scope = info.scope,
                                        school = info.school,
                                        creatorId = info.creatorId,
                                        subjects = sub,
                                        blob = null,
                                        owner = info.owner
                                    });
                                });
                            }
                            await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities);
                            //向学生或醍摩豆账号发起通知
                            #region
                            Notice notice = new Notice()
                            {
                                msgId = info.id,
                                creation = info.startTime,
                                expire = info.endTime,
                                creatorId = info.creatorId,
                                stuids = studentss,
                                tmdids = tmdids,
                                type = "notice",//评测参加通知
                                priority = "normal",
                                school = info.school,
                                scope = info.scope,
                                //data = new { }.ToJsonString()
                                body = new Body { sid = info.id, scode = info.code, spk = info.pk, biztype = "exam-join" }

                            };
                            //var messageBlob = new ServiceBusMessage(notice.ToJsonString());
                            //messageBlob.ApplicationProperties.Add("name", "Notice");
                            //await _serviceBus.GetServiceBusClient().SendMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageBlob);
                            #endregion
                            if (examClassResults.Count == 0)
                            {
                                foreach (string cla in info.classes)
                                {
                                    int m = 0;
                                    foreach (ExamSubject subject in info.subjects)
                                    {
                                        string classCode = "";
                                        if (string.IsNullOrEmpty(info.school) || !info.scope.Equals("school", StringComparison.OrdinalIgnoreCase))
                                        {
                                            classCode = "ExamClassResult-" + info.creatorId;
                                        }
                                        else
                                        {
                                            classCode = "ExamClassResult-" + info.school;
                                        }
                                        ExamClassResult result = new ExamClassResult
                                        {
                                            code = classCode,
                                            examId = info.id,
                                            id = Guid.NewGuid().ToString(),
                                            subjectId = subject.id,
                                            year = info.year,
                                            scope = info.scope
                                        };
                                        result.info.id = cla;
                                        List<string> ans = new List<string>();
                                        List<List<string>> anses = new List<List<string>>();
                                        List<double> ansPoint = new List<double>();
                                        List<string> ids = new List<string>();
                                        foreach (double p in info.papers[m].point)
                                        {
                                            //ans.Add(new List<string>());
                                            anses.Add(new List<string>());
                                            ansPoint.Add(-1);
                                        }
                                        var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"Class-{info.school}"));
                                        if (sresponse.Status == 200)
                                        {
                                            using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
                                            Class classroom = json.ToObject<Class>();
                                            //result.info.id = classroom.id;
                                            result.info.name = classroom.name;
                                            result.gradeId = classroom.gradeId;
                                            //处理班级人数
                                            await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.classId = '{classroom.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Base-{info.school}") }))
                                            {
                                                using var json_stu = await JsonDocument.ParseAsync(item.ContentStream);
                                                if (json_stu.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                                {
                                                    var accounts = json_stu.RootElement.GetProperty("Documents").EnumerateArray();
                                                    while (accounts.MoveNext())
                                                    {
                                                        JsonElement account = accounts.Current;
                                                        ids.Add(account.GetProperty("id").GetString());
                                                    }
                                                }
                                            }
                                        }
                                        if (info.scope.Equals("private", StringComparison.OrdinalIgnoreCase))
                                        {
                                            var stuResponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList"));
                                            if (stuResponse.Status == 200)
                                            {
                                                using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
                                                StuList stuList = json.ToObject<StuList>();
                                                //result.info.id = stuList.id;
                                                result.info.name = stuList.name;
                                                //处理发布对象为自选名单（个人）

                                                foreach (Students stus in stuList.students)
                                                {

                                                    ids.Add(stus.id);
                                                }
                                                if (stuList.tmids.Count > 0)
                                                {
                                                    foreach (string tid in stuList.tmids)
                                                    {
                                                        ids.Add(tid);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            var stuResponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(cla, new Azure.Cosmos.PartitionKey($"StuList-{info.school}"));
                                            if (stuResponse.Status == 200)
                                            {
                                                using var json = await JsonDocument.ParseAsync(stuResponse.ContentStream);
                                                StuList stuList = json.ToObject<StuList>();
                                                //result.info.id = stuList.id;
                                                result.info.name = stuList.name;
                                                //处理发布对象为自选名单（校本）
                                                foreach (Students stus in stuList.students)
                                                {
                                                    ids.Add(stus.id);
                                                }
                                            }
                                        }
                                        foreach (string stu in ids)
                                        {
                                            result.mark.Add("");
                                            result.studentIds.Add(stu);
                                            result.studentAnswers.Add(ans);
                                            result.studentScores.Add(ansPoint);
                                            result.ans.Add(anses);
                                            result.sum.Add(0);
                                        }

                                        //result.progress = info.progress;
                                        result.school = info.school;
                                        m++;
                                        await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(result, new Azure.Cosmos.PartitionKey($"{result.code}"));
                                    }
                                }
                                // 发送信息通知
                                var messageEnd = new ServiceBusMessage(new { id = input.Id, progress = "finish", code = code }.ToJsonString());
                                messageEnd.ApplicationProperties.Add("name", "Exam");
                                if (records.Count > 0)
                                {
                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
                                    await _serviceBus.GetServiceBusClient().cancelMessage(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), records[0].sequenceNumber);
                                    records[0].sequenceNumber = end;
                                    await _azureStorage.SaveOrUpdate<ChangeRecord>(records[0]);
                                    //await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(record, record.id, new Azure.Cosmos.PartitionKey($"{record.code}"));
                                }
                                else
                                {
                                    long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageEnd, DateTimeOffset.FromUnixTimeMilliseconds(etime));
                                    ChangeRecord changeRecord = new ChangeRecord
                                    {
                                        RowKey = input.Id,
                                        PartitionKey = "going",
                                        sequenceNumber = end,
                                        msgId = messageEnd.MessageId
                                    };
                                    await _azureStorage.Save<ChangeRecord>(changeRecord);
                                    //await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(changeRecord, new Azure.Cosmos.PartitionKey($"{changeRecord.code}"));
                                }
                            }
                            else
                            {
                                //处理单科结算时科目与试卷信息匹配的问题
                                int gno = 0;
                                foreach (ExamSubject subject in info.subjects)
                                {
                                    if (subject.classCount == info.classes.Count)
                                    {
                                        await createClassResultAsync(info, examClassResults, subject, gno, _azureCosmos, _dingDing, _azureStorage);
                                    }
                                    gno++;
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测going状态异常{e.Message}\n{e.StackTrace}", GroupNames.成都开发測試群組);
                        }
                        break;
                    case "finish":
                        int fno = 0;
                        try
                        {
                            foreach (ExamSubject subject in info.subjects)
                            {
                                await createClassResultAsync(info, examClassResults, subject, fno, _azureCosmos, _dingDing, _azureStorage);
                                fno++;
                            }

                            //计算单次考试简易统计信息
                            List<ExamResult> examResults = new List<ExamResult>();
                            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(
                                               queryText: $"select value(c) from c where c.examId  = '{info.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}") }))
                            {
                                examResults.Add(item);
                            }
                            List<Task<ItemResponse<ExamClassResult>>> tasks = new List<Task<ItemResponse<ExamClassResult>>>();
                            //结算单科单班的标准差和平均分
                            foreach (ExamClassResult classResult in examClassResults)
                            {
                                //标记单科单班总得分
                                double subScore = 0;
                                //标准差
                                double sPowSum = 0;
                                var scount = classResult.studentIds.Count;
                                foreach (List<double> sc in classResult.studentScores)
                                {
                                    List<double> newSc = new List<double>();
                                    foreach (double ssc in sc)
                                    {
                                        if (ssc == -1)
                                        {
                                            newSc.Add(0);
                                        }
                                        else
                                        {
                                            newSc.Add(ssc);
                                        }
                                    }
                                    subScore += newSc.Sum();
                                }
                                foreach (string sid in classResult.studentIds)
                                {
                                    double ssc = classResult.studentScores[classResult.studentIds.IndexOf(sid)].Sum();
                                    sPowSum += Math.Pow(ssc - scount > 0 ? Math.Round(subScore * 1.0 / scount, 2) : 0, 2);

                                }
                                classResult.standard = Math.Round(scount > 0 ? Math.Pow(sPowSum / scount, 0.5) : 0, 2);
                                classResult.average = scount > 0 ? Math.Round(subScore / scount, 2) : 0;
                                classResult.progress = true;
                                tasks.Add(client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}")));
                            }
                            await Task.WhenAll(tasks);
                            //记录某次考试所有学生得分总分
                            double score = 0;
                            double allScore = 0;
                            int stuCount = 0;
                            //标准差
                            double powSum = 0;
                            List<string> losStu = new List<string>();
                            //先与第一个值取并集
                            if (examResults.Count > 0)
                            {
                                losStu = losStu.Union(examResults[0].lostStus).ToList();
                                foreach (ExamResult examResult in examResults)
                                {
                                    if (info.id == examResult.examId)
                                    {
                                        foreach (List<double> sc in examResult.studentScores)
                                        {
                                            score += sc.Sum();
                                        }
                                        stuCount = examResult.studentIds.Count;
                                    }
                                    //powSum += Math.Pow(score - examResult.studentIds.Count > 0 ? Math.Round(score * 1.0 / examResult.studentIds.Count, 2) : 0, 2);
                                    //取交集
                                    losStu = losStu.Intersect(examResult.lostStus).ToList();
                                }
                            }
                            double NewsRateScore = stuCount > 0 ? Math.Round(score * 1.0 / stuCount, 2) : 0;
                            foreach (PaperSimple simple in info.papers)
                            {
                                allScore += simple.point.Sum();
                            }
                            //计算全科标准差
                            foreach (string id in examResults[0].studentIds)
                            {
                                double sc = 0;
                                foreach (ExamResult result in examResults)
                                {
                                    sc += result.studentScores[result.studentIds.IndexOf(id)].Sum();
                                }
                                powSum += Math.Pow(sc - NewsRateScore, 2);
                            }
                            info.standard = Math.Round(examResults[0].studentIds.Count > 0 ? Math.Pow(powSum / examResults[0].studentIds.Count, 0.5) : 0, 2);
                            double NewsRate = allScore > 0 ? Math.Round(NewsRateScore / allScore * 100, 2) : 0;
                            info.lostStu = losStu;
                            /*//补充历史数据的容器名称
                            if (string.IsNullOrEmpty(info.cn)) {
                                if (info.scope.Equals("school"))
                                {
                                    info.cn = info.school;
                                }
                                else {
                                    info.cn = info.creatorId;
                                }
                            }*/
                            //判断均分是否发生变化，便于实时的更新评测基本信息
                            if (info.sRate != NewsRate || info.average != NewsRateScore)
                            {
                                info.sRate = NewsRate;
                                info.average = NewsRateScore;
                                await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<ExamInfo>(info, info.id, new Azure.Cosmos.PartitionKey(info.code));
                            }
                        }
                        catch (Exception e)
                        {
                            await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测finish状态异常{e.Message}\n{e.StackTrace}", GroupNames.成都开发測試群組);
                        }
                        break;
                }
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测结算异常{e.Message}\n{e.StackTrace}", GroupNames.成都开发測試群組);
            }

        }
        //处理全部学生选题计数
        public static async Task examRecordCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, ExamResult result, List<ExamClassResult> classResults, AzureCosmosFactory _azureCosmos)
        {
            try
            {
                List<double> scores = new List<double>();
                foreach (List<double> sc in result.studentScores)
                {
                    scores.Add(sc.Sum());
                }
                //确定高分组 最低分数
                scores.Sort((s1, s2) => { return s2.CompareTo(s1); });
                double rhwCount = Math.Floor(scores.Count * 0.27);
                double rhw = rhwCount > 0 ? scores[int.Parse(rhwCount.ToString("0"))] : 0;
                //确定低分组 最高分数
                //scores.Sort((s1, s2) => { return s1.CompareTo(s2); });
                double rhlCount = Math.Ceiling(scores.Count * 0.73);
                double rhl = rhlCount > 0 ? scores[int.Parse(rhlCount.ToString("0"))] : 0;
                //存放高分组学生ID
                List<string> phId = new List<string>();
                List<string> plId = new List<string>();
                List<List<List<string>>> opth = new List<List<List<string>>>();
                List<List<List<string>>> optl = new List<List<List<string>>>();
                await knowledgeCount(info, subject, _dingDing, no, classResults, rhwCount, rhw, rhlCount, rhl, _azureCosmos);
                await fieldCount(info, subject, _dingDing, no, classResults, rhwCount, rhw, rhlCount, rhl, _azureCosmos);
                int PHCount = 0;
                int PLCount = 0;
                foreach (ExamClassResult classResult in classResults)
                {
                    if (classResult.subjectId.Equals(subject.id))
                    {
                        foreach (string id in classResult.studentIds)
                        {
                            int index = classResult.studentIds.IndexOf(id);
                            if (classResult.studentScores.Count > 0)
                            {
                                if (classResult.studentScores[index].Sum() >= rhw && PHCount < rhwCount)
                                {
                                    if (classResult.ans.Count > 0)
                                    {
                                        opth.Add(classResult.ans[index]);
                                        PHCount++;
                                        continue;
                                    }

                                }
                                if (classResult.studentScores[index].Sum() <= rhl && PLCount < (scores.Count - rhlCount))
                                {
                                    if (classResult.ans.Count > 0)
                                    {
                                        optl.Add(classResult.ans[index]);
                                        PLCount++;
                                        continue;
                                    }
                                }

                            }

                        }
                    }
                }
                result.phc = getMore(info, no, opth);
                result.plc = getMore(info, no, optl);
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测作答记录结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
            }
        }

        public static async Task knowledgeCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, List<ExamClassResult> classResults,
            double rhwCount, double rhw, double rhlCount, double rhl, AzureCosmosFactory _azureCosmos)
        {
            try
            {
                int phcount = 0;
                int plcount = 0;
                //存放并去重知识点
                HashSet<string> kname = new HashSet<string>();
                if (info.papers[no].knowledge.Count > 0) {
                    info.papers[no].knowledge.ForEach(kno =>
                    {
                        kno.ForEach(k =>
                        {
                            kname.Add(k);
                        });
                    });
                    List<string> knowledgeName = new List<string>();
                    foreach (string cla in kname)
                    {
                        knowledgeName.Add(cla);
                    }
                    for (int k = 0; k < knowledgeName.Count; k++)
                    {
                        if (null == knowledgeName[k])
                        {
                            knowledgeName.Remove(knowledgeName[k]);
                        }
                    }

                    foreach (ExamClassResult classResult in classResults)
                    {
                        if (classResult.subjectId.Equals(subject.id))
                        {
                            //List<int> phc = new List<int>();
                            List<int> ph = new List<int>();
                            List<int> pl = new List<int>();
                            List<int> pc = new List<int>();
                            List<double> persent = new List<double>();
                            for (int i = 0; i < knowledgeName.Count; i++)
                            {
                                //初始化单个知识点得分
                                double score = 0;
                                double allScore = 0;
                                int n = 0;
                                int phCount = 0;
                                int plCount = 0;
                                int pCount = 0;
                                foreach (List<string> str in info.papers[no].knowledge)
                                {
                                    if (str.Contains(knowledgeName[i]))
                                    {
                                        var itemPersent = str.Count > 0 ? 1 / Convert.ToDouble(str.Count) : 0;
                                        allScore += info.papers[no].point.Count > 0 ? info.papers[no].point[n] * itemPersent : 0;
                                        foreach (string id in classResult.studentIds)
                                        {
                                            int index = classResult.studentIds.IndexOf(id);
                                            if (classResult.studentScores.Count > 0)
                                            {
                                                if (classResult.studentScores[index].Count > 0)
                                                {
                                                    score += classResult.studentScores[index][n] == -1 ? 0 : classResult.studentScores[index][n];
                                                    if (classResult.studentScores[index].Sum() >= rhw && phcount < rhwCount)
                                                    {
                                                        if (classResult.studentScores[index][n] <= 0)
                                                        {
                                                            phCount++;
                                                        }
                                                        phcount++;
                                                        continue;
                                                    }
                                                    if (classResult.studentScores[index].Sum() <= rhl && plcount < (info.stuCount - rhlCount))
                                                    {
                                                        if (classResult.studentScores[index][n] <= 0)
                                                        {
                                                            plCount++;
                                                        }
                                                        plcount++;
                                                        continue;
                                                    }
                                                    if (classResult.studentScores[index][n] <= 0)
                                                    {
                                                        pCount++;
                                                    }
                                                }
                                            }

                                        }
                                    }
                                    n++;
                                }
                                pc.Add(pCount);
                                ph.Add(phCount);
                                pl.Add(plCount);
                                double per = classResult.studentIds.Count > 0 ? Math.Round(score / classResult.studentIds.Count, 2) : 0;
                                persent.Add(allScore > 0 ? per / allScore : 0);
                            }
                            classResult.phc = ph;
                            classResult.plc = pl;
                            classResult.pc = pc;
                            classResult.krate = persent;
                        }
                        //await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                    }
                }
                
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测知识点结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
            }
        }

        public static async Task fieldCount(ExamInfo info, ExamSubject subject, DingDing _dingDing, int no, List<ExamClassResult> classResults,
            double rhwCount, double rhw, double rhlCount, double rhl, AzureCosmosFactory _azureCosmos)
        {
            try
            {
                int phcount = 0;
                int plcount = 0;
                //存放并去重知识点
                List<int> knowledgeName = new List<int>();
                knowledgeName.Add(1);
                knowledgeName.Add(2);
                knowledgeName.Add(3);
                knowledgeName.Add(4);
                knowledgeName.Add(5);
                knowledgeName.Add(6);
                foreach (ExamClassResult classResult in classResults)
                {
                    if (classResult.subjectId.Equals(subject.id))
                    {
                        //List<int> phc = new List<int>();
                        List<int> ph = new List<int>();
                        List<int> pl = new List<int>();
                        List<int> pc = new List<int>();
                        List<double> persent = new List<double>();
                        for (int i = 0; i < knowledgeName.Count; i++)
                        {
                            //初始化单个知识点得分
                            double score = 0;
                            double allScore = 0;
                            int n = 0;
                            int phCount = 0;
                            int plCount = 0;
                            int pCount = 0;
                            if (info.papers[no].field.Count > 0) {
                                foreach (int str in info.papers[no].field)
                                {
                                    if (str == knowledgeName[i])
                                    {
                                        var itemPersent = 1;
                                        allScore += info.papers[no].point.Count > 0 ? info.papers[no].point[n] * itemPersent : 0;
                                        foreach (string id in classResult.studentIds)
                                        {
                                            int index = classResult.studentIds.IndexOf(id);
                                            if (classResult.studentScores.Count > 0)
                                            {
                                                if (classResult.studentScores[index].Count > 0)
                                                {
                                                    score += classResult.studentScores[index][n] == -1 ? 0 : classResult.studentScores[index][n];
                                                    if (classResult.studentScores[index].Sum() >= rhw && phcount < rhwCount)
                                                    {
                                                        if (classResult.studentScores[index][n] <= 0)
                                                        {
                                                            phCount++;
                                                        }
                                                        phcount++;
                                                        continue;
                                                    }
                                                    if (classResult.studentScores[index].Sum() <= rhl && plcount < (info.stuCount - rhlCount))
                                                    {
                                                        if (classResult.studentScores[index][n] <= 0)
                                                        {
                                                            plCount++;
                                                        }
                                                        plcount++;
                                                        continue;
                                                    }
                                                    if (classResult.studentScores[index][n] <= 0)
                                                    {
                                                        pCount++;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    n++;
                                }
                                pc.Add(pCount);
                                ph.Add(phCount);
                                pl.Add(plCount);
                                double per = classResult.studentIds.Count > 0 ? Math.Round(score / classResult.studentIds.Count, 2) : 0;
                                persent.Add(allScore > 0 ? per / allScore : 0);
                            }                           
                        }
                        classResult.fphc = ph;
                        classResult.fplc = pl;
                        classResult.fpc = pc;
                        classResult.frate = persent;
                    }
                    //await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(classResult, classResult.id, new Azure.Cosmos.PartitionKey($"{classResult.code}"));
                }
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-{info.id}-评测认知层次结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
            }
        }
        //处理选题计数
        public static List<Dictionary<string, int>> getMore(ExamInfo info, int no, List<List<List<string>>> list)
        {
            List<Dictionary<string, int>> recorde = new List<Dictionary<string, int>>();
            try
            {
                for (int i = 0; i < info.papers[no].answers.Count; i++)
                {
                    if (info.papers[no].answers[i].Count <= 0)
                    {
                        recorde.Add(new Dictionary<string, int>());
                        continue;
                    }
                    Dictionary<string, int> optCount = new Dictionary<string, int>();
                    foreach (List<List<string>> stu in list)
                    {
                        if (stu.Count == info.papers[no].answers.Count)
                        {

                            var item = stu[i];
                            foreach (string opt in item)
                            {
                                if (optCount.ContainsKey(opt))
                                {
                                    optCount[opt] = optCount[opt] + 1;
                                }
                                else
                                {
                                    optCount[opt] = 1;
                                }
                            }

                        }
                    }
                    recorde.Add(optCount);
                }
                return recorde;
            }
            catch (Exception)
            {
                return recorde;
            }
        }
        public static async Task createClassResultAsync(ExamInfo info, List<ExamClassResult> examClassResults, ExamSubject subject, int no, AzureCosmosFactory _azureCosmos, DingDing _dingDing, AzureStorageFactory _azureStorage)
        {
            //保证试卷信息与科目信息同步
            ExamResult result = new ExamResult();
            //人数总和
            int Count = 0;
            int m = 0;
            double score = 0;
            //标准差
            double powSum = 0;
            double allScore = info.papers[no].point.Sum();
            List<ClassRange> classRanges = new List<ClassRange>();
            List<string> lostStu = new List<string>();
            List<double> csRate = new List<double>();
            List<List<List<string>>> opt = new List<List<List<string>>>();
            foreach (ExamClassResult classResult in examClassResults)
            {
                double classSrate = 0;
                if (classResult.subjectId.Equals(subject.id))
                {
                    foreach (List<List<string>> op in classResult.ans)
                    {
                        opt.Add(op);
                    }
                    //记录缺考学生索引位置
                    int index = 0;
                    foreach (List<double> scores in classResult.studentScores)
                    {
                        List<double> newScores = new List<double>();
                        int count = 0;
                        foreach (double sc in scores)
                        {
                            newScores.Add(sc > -1 ? sc : 0);
                            if (sc == -1)
                            {
                                count++;
                            }
                        }
                        if (count == scores.Count)
                        {
                            lostStu.Add(classResult.studentIds[index]);
                            //mcount++;
                        }
                        classSrate += newScores.Sum();
                        score += newScores.Sum();
                        result.studentScores.Add(newScores);
                        index++;
                    }

                    //处理班级信息
                    ClassRange range = new ClassRange();
                    range.id = classResult.info.id;
                    range.name = classResult.info.name;
                    range.gradeId = classResult.gradeId;
                    List<int> ran = new List<int>();
                    int stuCount = classResult.studentIds.Count;
                    Count += stuCount;
                    if (m == 0)
                    {
                        ran.Add(0);
                        ran.Add(stuCount - 1);
                    }
                    else
                    {
                        ran.Add(Count - stuCount);
                        ran.Add(Count - 1);
                    }
                    m++;
                    range.range = ran;
                    classRanges.Add(range);
                    //处理学生ID 
                    foreach (string id in classResult.studentIds)
                    {
                        result.studentIds.Add(id);
                    }
                    if (allScore > 0)
                    {
                        csRate.Add(classResult.studentIds.Count > 0 ? Math.Round(classSrate * 1.0 / classResult.studentIds.Count, 2) : 0 / allScore);

                    }
                    else {
                        csRate.Add(0);
                    }

                    //powSum += Math.Pow(classSrate - result.average, 2);
                    //处理选项计数内容
                }
            }
            await examRecordCount(info, subject, _dingDing, no, result, examClassResults, _azureCosmos);
            result.record = getMore(info, no, opt);
            result.average = result.studentIds.Count > 0 ? Math.Round(score * 1.0 / result.studentIds.Count, 2) : 0;
            foreach (ExamClassResult classResult in examClassResults)
            {

                //double classSrate = 0;
                if (classResult.subjectId.Equals(subject.id))
                {
                    foreach (string id in classResult.studentIds)
                    {
                        double sc = classResult.studentScores[classResult.studentIds.IndexOf(id)].Sum();
                        powSum += Math.Pow(sc - result.average, 2);
                    }
                }

            }
            result.standard = Math.Round(result.studentIds.Count > 0 ? Math.Pow(powSum / result.studentIds.Count, 0.5) : 0, 2);
            result.csRate = csRate;
            result.lostStus = lostStu;

            result.sRate = allScore > 0 ? Math.Round(result.average / allScore * 100, 2) : 0;
            result.classes = classRanges;
            result.code = "ExamResult-" + info.id;
            result.school = info.school;
            result.id = subject.id;
            result.examId = info.id;
            result.subjectId = subject.id;
            result.year = info.year;
            result.paper = info.papers[no];
            //result.point = info.papers[j].point;
            result.scope = info.scope;
            result.name = info.name;
            result.time = info.startTime;

            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Common").UpsertItemAsync(result, new Azure.Cosmos.PartitionKey($"ExamResult-{info.id}"));

        }
    }
}
