using ClouDASLibx;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.SDK.Models;

using TEAMModelOS.SDK;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using TEAMModelOS.SDK.Helper.Common.StringHelper;
using TEAMModelOS.SDK.Helper.Security.ShaHash;
using TEAMModelOS.Services.Analysis;
using Microsoft.Extensions.Options;
using TEAMModelOS.Models;
using Azure.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Student;
using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
using TEAMModelOS.SDK.Models.Cosmos;
using static TEAMModelOS.SDK.Models.Cosmos.ClassAnalysis;
using static TEAMModelOS.SDK.Models.Cosmos.GradeAnalysis;
using System.Text;

namespace TEAMModelOS.Controllers.Analysis
{
    [Route("analysis")]
    [ApiController]
    public class AnalysisController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        private readonly Option _option;
        private const string CacheCosmosPrefix = "Analysis:";
        private const int timeoutSeconds = 3600;
        public AnalysisController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
            _option = option?.Value;
        }
        [HttpPost("process")]
        public async Task<IActionResult> getAnalysis(JsonElement request)
        {
            //获取评测的ID
            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
            List<StudentAys> students = new List<StudentAys>();
            List<ClassAys> classes = new List<ClassAys>();
            List<GradeAys> grades = new List<GradeAys>();
            List<Dictionary<string, dynamic>> PointAnalysis = new List<Dictionary<string, dynamic>>();
            List<string> scatterKey = new List<string>
            {
                "name",
                "className",
                "x",
                "y",
                "memberId",
                "score",
                "trueNum",
                "falseNum",
                "hardList",
                "carefulList",
                "scatter"
            };
            List<string> paperKey = new List<string>
            {
                "id",
                "type",
                "areaName",
                "score",
                "diff",
                "identify",
                "classScoreRate",
                "gradeScoreRate",
                "areaScoreRate",
                "highScoreRate",
                "lowScoreRate",
                "knowledgePoint",
                "R1",
                "R2",
                "R3",
                "R4",
                "R5",
                "R6",
                "PH",
                "PL",
                "X",
                "Y",
                "knowledge",
                "examScoreRate"
            };
            List<string> knowkey = new List<string>
            {
                "id",
                "className",
                "seatNO",
                "point",
                "anwPoint",
                "persent"
            };
            List<string> keynowWrong = new List<string>
            {
                "name",
                "point",
                "itemNO",
                "persent",
                "wrong",
                "rhw",
                "rlw"
            };
            ExamInfo info = null;
            double ipoint = 0;
            List<KeyValuePair<string, List<List<string>>>> subjectPaperDatas = new List<KeyValuePair<string, List<List<string>>>>();
            List<Dictionary<string, object>> valuePairs = new List<Dictionary<string, object>>();
            List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> classSubjectPaperDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();
            List<KeyValuePair<string, List<string>>> knowNameDatas = new List<KeyValuePair<string, List<string>>>();
            List<KeyValuePair<string, List<string>>> knowPerDatas = new List<KeyValuePair<string, List<string>>>();
            List<KeyValuePair<string, List<double>>> knowAllPerDatas = new List<KeyValuePair<string, List<double>>>();
            List<KeyValuePair<string, List<double>>> knowScoreDatas = new List<KeyValuePair<string, List<double>>>();
            List<KeyValuePair<string, List<List<string>>>> wrongDatas = new List<KeyValuePair<string, List<List<string>>>>();
            List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> stuPerDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();
            //声明认知层次变量
            List<KeyValuePair<string, List<int>>> fieldNameDatas = new List<KeyValuePair<string, List<int>>>();
            List<KeyValuePair<string, List<string>>> fieldPerDatas = new List<KeyValuePair<string, List<string>>>();
            List<KeyValuePair<string, List<double>>> fieldAllPerDatas = new List<KeyValuePair<string, List<double>>>();
            List<KeyValuePair<string, List<double>>> fieldScoreDatas = new List<KeyValuePair<string, List<double>>>();
            List<KeyValuePair<string, List<List<string>>>> fieldwrongDatas = new List<KeyValuePair<string, List<List<string>>>>();
            List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>> fieldStuPerDatas = new List<KeyValuePair<string, List<KeyValuePair<string, List<double>>>>>();

            //获取进线标准以及踩线分数
            int touch = 0;
            int income = 0;
            List<ExamResult> examResults = new List<ExamResult>();
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //获取本次评测所有科目结算结果
                info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
                School school = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<School>(code.ToString(), new PartitionKey($"Base"));
                var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes,c.sRate,c.average,c.standard,c.lostStus,c.record,c.phc,c.plc from c where c.examId =  '{id}' ";
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
                {
                    examResults.Add(item);
                }
                //获取本次评测所有班级作答结果
                List<ExamClassResult> examClassResults = new List<ExamClassResult>();
                var queryClass = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.gradeId,c.info,c.standard,c.krate,c.phc,c.plc,c.pc,c.frate,c.fphc,c.fplc,c.fpc from c where c.examId =  '{id}' and c.progress = true ";
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamClassResult>(queryText: queryClass, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamClassResult-{code}") }))
                {
                    examClassResults.Add(item);

                }

                foreach (Period period in school.period)
                {
                    if (info.period.id.Equals(period.id))
                    {
                        touch = period.analysis.touch;
                        income = period.analysis.income;
                    }
                }
                //计算每个年级参考人数并计算进线分数
                List<KeyValuePair<string, double>> keys = new List<KeyValuePair<string, double>>();
                List<double> gradeTotal = new List<double>();
                /*foreach (Grade grade in info.grades) {
                    double ipoint = 0;
                    int gradeCount = 0;
                    //List<double> gradeTotal = new List<double>();
                    HashSet<string> sno = new HashSet<string>();
                    foreach (ExamClassResult examClassResult in examClassResults) {
                        if (grade.id.Equals(examClassResult.gradeId)) {
                            gradeCount += examClassResult.studentIds.Count;
                            foreach (string s in examClassResult.studentIds) {
                                sno.Add(s);
                            }
                        }
                    }
                    foreach (string sid in sno) {
                        double total = 0;
                        foreach (ExamClassResult examClassResult in examClassResults) {
                            if (grade.id.Equals(examClassResult.gradeId))
                            {
                                int index = examClassResult.studentIds.IndexOf(sid);
                                if (index == -1) continue;
                                total += examClassResult.studentScores[index].Sum();
                            }                              
                        }
                        gradeTotal.Add(total);
                    }
                    gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
                    //获取进线人数
                    int personCount = (int)System.Math.Round(gradeCount / info.subjects.Count * (touch / 100.0), MidpointRounding.AwayFromZero);
                    ipoint = gradeTotal[personCount];
                    keys.Add(new KeyValuePair<string, double>(grade.id, ipoint));
                }*/
                //获取进线人数
                int personCount = (int)System.Math.Round(info.stuCount * (income / 100.0), MidpointRounding.AwayFromZero);

                /* //声明年级所有科目总分
                 List<double> total = new List<double>();*/

                List<ClassRange> classReses = null;
                //按科目获取所有学生的分数
                Dictionary<string, List<double>> subjectTotal = new Dictionary<string, List<double>>();
                Dictionary<string, double> paperScore = new Dictionary<string, double>();
                List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>> subjectScatter = new List<KeyValuePair<string, List<KeyValuePair<string, List<string>>>>>();
                List<KeyValuePair<string, Dictionary<string, List<double>>>> gscores = new List<KeyValuePair<string, Dictionary<string, List<double>>>>();
                //声明全科总分
                double totalAll = 0;
                foreach (ExamResult examResult in examResults)
                {
                    (KeyValuePair<string, List<List<string>>> subjectData, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> classSubjectData, Dictionary<string, List<double>> gscore) = DoExerciseScatteres(examResult, paperKey);
                    (KeyValuePair<string, List<string>> knowName, KeyValuePair<string, List<string>> knowPer, KeyValuePair<string, List<double>> knowAllPer, KeyValuePair<string, List<double>> kScore, KeyValuePair<string, List<List<string>>> wrong, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> stuPer) = DoKnowledgePoint(examResult, info, keynowWrong);
                    (KeyValuePair<string, List<int>> fieldName, KeyValuePair<string, List<string>> fieldPer, KeyValuePair<string, List<double>> fieldAllPer, KeyValuePair<string, List<double>> fScore, KeyValuePair<string, List<List<string>>> fieldWrong, KeyValuePair<string, List<KeyValuePair<string, List<double>>>> fieldStuPer) = DoLevel(examResult, info, keynowWrong);
                    gscores.Add(new KeyValuePair<string, Dictionary<string, List<double>>>(examResult.subjectId, gscore));
                    /*                    Dictionary<string, dynamic> gpoint = new Dictionary<string, dynamic>();
                                        Dictionary<string, dynamic> glevel = new Dictionary<string, dynamic>();*/
                    Dictionary<string, object> gpointList = new Dictionary<string, object>();
                    subjectPaperDatas.Add(subjectData);
                    classSubjectPaperDatas.Add(classSubjectData);
                    subjectScatter.Add(DoSubjectScatter(examResult));
                    knowNameDatas.Add(knowName);
                    knowPerDatas.Add(knowPer);
                    knowAllPerDatas.Add(knowAllPer);
                    knowScoreDatas.Add(kScore);
                    wrongDatas.Add(wrong);
                    stuPerDatas.Add(stuPer);

                    fieldNameDatas.Add(fieldName);
                    fieldPerDatas.Add(fieldPer);
                    fieldAllPerDatas.Add(fieldAllPer);
                    fieldScoreDatas.Add(fScore);
                    fieldwrongDatas.Add(fieldWrong);
                    fieldStuPerDatas.Add(fieldStuPer);
                    //gpointList.Add("subjectId", examResult.subjectId);
                    //gpointList.Add("pointKey", DoKnowledgePoint(examResult, info));
                    //gpointList.Add("levelKey", DoLevel(examResult, info));
                    valuePairs.Add(gpointList);
                    //获取一张试卷的满分
                    totalAll += examResult.paper.point.Sum();
                    paperScore.Add(examResult.subjectId, examResult.paper.point.Sum());
                    List<double> StuSubjectTotals = new List<double>();
                    classReses = examResult.classes;
                    //处理个人
                    foreach (var stuid in examResult.studentIds)
                    {
                        StudentAys student = null;
                        int index = examResult.studentIds.IndexOf(stuid);
                        if (students.Select(x => x.id).Contains(stuid))
                        {
                            student = students[index];
                        }
                        else
                        {
                            student = new StudentAys() { id = stuid };
                            students.Add(student);
                        }
                        var score = examResult.studentScores[index].Sum();
                        student.total += score;
                        StuSubjectTotals.Add(score);
                        if (student.subjects.Select(x => x.id).Contains(examResult.subjectId))
                        {
                            student.subjects.ForEach(y =>
                            {
                                if (y.id.Equals(examResult.subjectId))
                                {
                                    y.score = score;
                                    y.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum() : 0, 2);
                                }
                            });
                        }
                        else
                        {
                            StudentSubject subject = new StudentSubject
                            {
                                id = examResult.subjectId,
                                scores = examResult.studentScores[examResult.studentIds.IndexOf(stuid)],
                                name = info.subjects.Where(x => x.id == examResult.subjectId).FirstOrDefault().name,
                                point = stuPerDatas.Where(x => x.Key == examResult.subjectId).SelectMany(va => va.Value).Where(stu => stu.Key == stuid).Select(pi => pi.Value).First(),
                                fieldPoint = fieldStuPerDatas.Where(x => x.Key == examResult.subjectId).SelectMany(va => va.Value).Where(stu => stu.Key == stuid).Select(pi => pi.Value).First()
                            };
                            subject.score = score;
                            subject.sRate = Math.Round(examResult.paper.point.Sum() > 0 ? score / examResult.paper.point.Sum() * 100 : 0, 2);
                            student.subjects.Add(subject);
                        }
                    }
                    subjectTotal.Add(examResult.subjectId, StuSubjectTotals);
                }
                //double powAll = 0;
                foreach (StudentAys student1 in students)
                {
                    gradeTotal.Add(student1.total);
                    student1.sRate = totalAll > 0 ? Math.Round(student1.total / totalAll * 100, 2) : 0;
                    //powAll += Math.Pow(student1.total - examResult.studentIds.Count > 0 ? Math.Round(score * 1.0 / examResult.studentIds.Count, 2) : 0, 2);
                }
                //处理进线分数
                gradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
                ipoint = gradeTotal[personCount];
                //以班级为单位
                foreach (string classId in info.classes)
                {
                    Class classroom = null;
                    var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classId, new PartitionKey($"Class-{code}"));
                    if (sresponse.Status == 200)
                    {
                        using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
                        classroom = json.ToObject<Class>();

                    }
                    //处理班级
                    var classRes = classReses.Where(x => x.id == classId).FirstOrDefault();
                    var stuCount = classRes.range[1] - classRes.range[0] + 1;
                    var classStudents = students.GetRange(classRes.range[0], classRes.range[1] - classRes.range[0] + 1);
                    List<double> stuTotals = classStudents.Select(x => x.total).ToList();
                    stuTotals.Sort((s1, s2) => { return s2.CompareTo(s1); });

                    /*                    foreach (KeyValuePair<string, double> key1 in keys)
                                        {
                                            if (classroom.gradeId.Equals(key1.Key))
                                            {
                                                ipoint = key1.Value;
                                            }
                                        }*/
                    //double ipoint = stuTotals[personCount];
                    //初始化进线人数
                    int lineCount = 0;
                    //初始化班级总分
                    double classTotal = stuTotals.Sum();
                    //标准差
                    double powSum = 0;
                    //计算标准差
                    //总平均分
                    double totalAverage = 0;
                    totalAverage = stuCount > 0 ? classTotal * 1.0 / stuCount : 0;
                    //totalAverage = classTotal / stuCount;
                    //获取整个班级 科目的分数情况
                    List<KeyValuePair<string, double>> keyValues = new List<KeyValuePair<string, double>>();
                    List<string> studentIds = new List<string>();
                    List<KeyValuePair<string, List<double>>> pointClassTotal = new List<KeyValuePair<string, List<double>>>();
                    List<KeyValuePair<string, List<double>>> fieldClassTotal = new List<KeyValuePair<string, List<double>>>();
                    subjectTotal.Keys.ToList().ForEach(sub =>
                    {
                        var points = new List<double>();
                        var fields = new List<double>();
                        knowNameDatas.Where(su => su.Key == sub).First().Value.ForEach(x => { points.Add(0); });
                        fieldNameDatas.Where(su => su.Key == sub).First().Value.ForEach(x => { fields.Add(0); });
                        pointClassTotal.Add(new KeyValuePair<string, List<double>>(sub, points));
                        fieldClassTotal.Add(new KeyValuePair<string, List<double>>(sub, fields));

                    });
                    List<Student> stus = new List<Student>();
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryIterator<Student>(queryText: $"select c.id,c.name,c.no from c where c.classId = '{classId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{code}") }))
                    {
                        stus.Add(item);
                    }
                    classStudents.ForEach(x =>
                    {
                        studentIds.Add(x.id);
                        x.classId = classId;
                        x.className = classroom.name;
                        x.gradeId = classroom.gradeId;
                        var stu = stus.Where(s => s.id == x.id).FirstOrDefault();
                        if (stu != null)
                        {
                            x.name = stu.name;
                            x.no = stu.no;
                        }
                        else
                        {
                            x.name = x.id;
                            x.no = "-";
                        }
                        /*  //班级得分率
                          x.csRate = totalAll > 0 ? Math.Round(totalAverage / totalAll,2) : 0;*/
                        //标准差
                        powSum += Math.Pow(x.total - totalAverage, 2);
                        //进线人数
                        if (x.total >= ipoint)
                        {
                            lineCount++;
                        }
                        //班级全科的pr
                        int index = stuTotals.IndexOf(x.total);
                        double CPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
                        //double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
                        x.cpr = CPR;
                        x.csort = index + 1;
                        //班级单科的pr
                        x.subjects.ForEach(y =>
                        {
                            //y.point

                            var subjectT = classStudents.SelectMany(s => s.subjects).Where(sub => sub.id == y.id).Select(scr => scr.score).ToList();
                            subjectT.Sort((s1, s2) => { return s2.CompareTo(s1); });
                            int index = subjectT.IndexOf(y.score);
                            double CPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
                            //double CPR = 100 - (100 * (index + 1) - 50) / stuCount;
                            y.cpr = CPR;
                            y.csort = index + 1;
                            //按科目获取一个班的分数
                            keyValues.Add(new KeyValuePair<string, double>(y.id, y.score));
                            var pintTalt = pointClassTotal.Where(su => su.Key == y.id).Select(pint => pint.Value).First();
                            for (int i = 0; i < y.point.Count; i++)
                            {
                                pintTalt[i] = pintTalt[i] + y.point[i];
                            }
                            var fieldTalt = fieldClassTotal.Where(su => su.Key == y.id).Select(pint => pint.Value).First();
                            for (int i = 0; i < y.fieldPoint.Count; i++)
                            {
                                fieldTalt[i] = fieldTalt[i] + y.fieldPoint[i];
                            }

                        });
                    });
                    var pow = stuCount > 0 ? Math.Pow(powSum / stuCount, 0.5) : 0;
                    //var pow = Math.Pow(powSum / stuCount, 0.5);
                    ClassAys classAys = new ClassAys
                    {
                        gradeId = classroom.gradeId,
                        studentIds = studentIds,
                        stuCount = stuCount,
                        classId = classId,
                        csRate = totalAll > 0 ? Math.Round(totalAverage / totalAll * 100, 2) : 0,
                        className = classroom.name,
                        totalAverage = totalAverage,
                        lineCount = lineCount,
                        standardDeviation = pow
                    };
                    foreach (var key in paperScore.Keys)
                    {
                        var subScore = keyValues.Where(x => x.Key.Equals(key)).Select(x => x.Value).ToList();
                        //计算及格率
                        int passCount = 0;
                        double passScore = paperScore[key] * 0.6;
                        subScore.ForEach(x =>
                        {
                            if (x > passScore)
                            {
                                passCount += 1;
                            }
                        });
                        double passPercent = stuCount > 0 ? Math.Round(passCount * 1.0 / stuCount, 2) : 0;
                        //double passPercent = Math.Round(passCount * 1.0 / stuCount,2) ;
                        double average = stuCount > 0 ? Math.Round(subScore.Sum() * 1.0 / stuCount, 2) : 0;
                        //double average = Math.Round(subScore.Sum() * 1.0 / stuCount,2) ;
                        List<double> tt = new List<double>();
                        List<double> fieldPoints = new List<double>();
                        var pp = pointClassTotal.Where(su => su.Key == key).Select(pint => pint.Value).First();
                        pp.ForEach(s =>
                        {

                            tt.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
                        });
                        var ff = fieldClassTotal.Where(su => su.Key == key).Select(pint => pint.Value).First();
                        ff.ForEach(s =>
                        {
                            fieldPoints.Add(stuCount > 0 ? Math.Round(s * 1.0 / stuCount, 2) : 0);
                        });
                        double val = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).standard;
                        List<double> krate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).krate;
                        List<int> phc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).phc;
                        List<int> plc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).plc;
                        List<int> pc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).pc;
                        List<double> frate = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).frate;
                        List<int> fphc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fphc;
                        List<int> fplc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fplc;
                        List<int> fpc = examClassResults.FirstOrDefault(c => c.subjectId == key && c.info.id == classId).fpc;
                        classAys.subjects.Add(new AysSubject
                        {
                            point = tt,
                            field = fieldPoints,
                            id = key,
                            passPercent = passPercent,
                            passCount = passCount,
                            average = average,
                            standard = val,
                            krate = krate,
                            phc = phc,
                            plc = plc,
                            pc = pc,
                            frate = frate,
                            fphc = fphc,
                            fplc = fplc,
                            fpc = fpc,
                            sRate = paperScore[key] > 0 ? Math.Round(average / paperScore[key] * 100, 2) : 0,
                            name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
                            item = classSubjectPaperDatas.Where(subd => subd.Key == key).First().Value.Where(cls => cls.Key == classId).First().Value
                        });
                    }
                    classes.Add(classAys);
                }
                //处理年级
                var tgrades = classes.GroupBy(x => x.gradeId).Select(x => x.Key);
                foreach (var greade in tgrades)
                {
                    var clases = classes.Where(x => x.gradeId.Equals(greade));
                    var classCount = clases.Count();
                    var stu = clases.SelectMany(x => x.studentIds).ToList();
                    var lineCount = clases.Select(x => x.lineCount).Sum();
                    var totalAverage = clases.Select(x => x.totalAverage).Sum() * 1.0 / classCount;
                    GradeAys gradeAys = new GradeAys
                    {
                        gradeId = greade,
                        studentIds = stu,
                        gradeName = info.grades.Where(x => x.id == greade).FirstOrDefault().name,
                        stuCount = stu.Count,
                        lineCount = lineCount,
                        totalAverage = totalAverage,
                    };
                    foreach (var key in paperScore.Keys)
                    {
                        var AysSubject = clases.SelectMany(c => c.subjects).Where(x => x.id.Equals(key)).Select(x => x).ToList();
                        var passCount = AysSubject.Select(x => x.passCount).Sum();
                        var average = Math.Round(AysSubject.Select(x => x.average).Sum() * 1.0 / classCount);
                        var passPercent = stu.Count > 0 ? Math.Round(passCount * 1.0 / stu.Count, 2) : 0;
                        //var passPercent = Math.Round(passCount * 1.0 / stu.Count,2);
                        AysSubject subject = new AysSubject
                        {
                            id = key,
                            passCount = passCount,
                            passPercent = passPercent,
                            average = average,
                            name = info.subjects.Where(x => x.id == key).FirstOrDefault().name,
                            item = gscores.Where(x => x.Key == key).FirstOrDefault().Value.Where(cls => cls.Key == greade).FirstOrDefault().Value
                        };
                        gradeAys.subjects.Add(subject);
                    }
                    grades.Add(gradeAys);
                    //处理学生年级相关的pr值
                    var studentAys = students.Where(x => x.gradeId.Equals(greade)).ToList();
                    var stuGradeTotal = studentAys.Select(x => x.total).ToList();
                    stuGradeTotal.Sort((s1, s2) => { return s2.CompareTo(s1); });
                    var stuCount = stuGradeTotal.Count;
                    studentAys.ForEach(x =>
                    {
                        //年级全科的pr
                        int index = stuGradeTotal.IndexOf(x.total);
                        double GPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50)*1.0 / stuCount) : 0;
                        //double GPR = 100 - (100 * (index + 1) - 50) / stuCount;
                        x.gpr = GPR;
                        x.gsort = index + 1;
                        //年级单科的pr
                        x.subjects.ForEach(y =>
                        {
                            var subjectT = studentAys.SelectMany(s => s.subjects).Where(sub => sub.id == y.id).Select(scr => scr.score).ToList();
                            subjectT.Sort((s1, s2) => { return s2.CompareTo(s1); });
                            int index = subjectT.IndexOf(y.score);
                            double GPR = stuCount > 0 ? Math.Floor(100 - (100 * (index + 1) - 50) * 1.0 / stuCount) : 0;
                            //double GPR = 100 - (100 * (index + 1) - 50) / stuCount;
                            y.gpr = GPR;
                            y.gsort = index + 1;
                        });
                    });
                }
                subjectScatter.ForEach(x =>
                {
                    string subjectId = x.Key;
                    x.Value.ForEach(s =>
                    {
                        string stuId = s.Key;
                        var data = s.Value;
                        var stu = students.Where(stu => stu.id == stuId).First();
                        students.Where(stu => stu.id == stuId).First().subjects.Where(sub => sub.id == subjectId).ToList().ForEach(sc =>
                        {
                            //处理阵列的索引1的班级名称
                            data[1] = stu.className;
                            sc.scatter = data;
                            //data[3] = sc.sRate.ToString();
                            //sc.sRate = double.Parse(data[3]);
                        });
                    });
                });

            }
            catch (Exception ex)
            {
                BadRequest(ex.StackTrace);
            }

            var sub  = examResults.Select(e => new {
                    id = e.id,
                    name = info.subjects.FirstOrDefault(c => c.id == e.id).name,
                    record = e.record,
                    phc = e.phc,
                    plc = e.plc,
                    sRate = e.sRate,
                    average = e.average,
                    standard = e.standard
            });
            /*var sub = info.subjects.Select(x => new
            {
                id = x.id,
                name = x.name,
                record = examResults.FirstOrDefault(c => c.id == x.id).record,
                phc = examResults.FirstOrDefault(c => c.id == x.id).phc,
                plc = examResults.FirstOrDefault(c => c.id == x.id).plc,
                sRate = examResults.FirstOrDefault(c => c.id == x.id).sRate,
                average = examResults.FirstOrDefault(c => c.id == x.id).average,
                standard = examResults.FirstOrDefault(c => c.id == x.id).standard
            });*/
            var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard, total = info.stuCount };
            return Ok(new
            {
                students,
                classes,
                grades,
                paper = subjectPaperDatas,
                subjects = sub,
                scatterKey = scatterKey,
                paperKey = paperKey,
                pointLevelKey = valuePairs,
                ipoint = ipoint,
                touchScore = touch,
                knowKey = knowkey,
                wrongKey = keynowWrong,
                wrong = wrongDatas,
                knowName = knowNameDatas,
                knowPer = knowPerDatas,
                knowAllper = knowAllPerDatas,
                fieldwrong = fieldwrongDatas,
                fieldName = fieldNameDatas,
                fieldPer = fieldPerDatas,
                fieldAllPer = fieldAllPerDatas,
                kScores = knowScoreDatas,
                fScores = fieldScoreDatas,
                all = subAll
            });
        }

        private static (KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>, Dictionary<string, List<double>>) DoExerciseScatteres(ExamResult e, List<string> paperKey)
        {
            List<int> examAnswer = new List<int>();
            List<string> examPersent = new List<string>();
            for (int n = 0; n < e.paper.point.Count; n++)
            {
                examAnswer.Add(0);
            }
            //参考人数
            double Qnum = 0;
            e.studentIds.ForEach(i =>
            {
                if (!i.Equals("0"))
                {
                    Qnum++;
                }
            });
            List<List<string>> datas = new List<List<string>>();
            List<string[]> itemAnalysis = new List<string[]>();
            Dictionary<string, List<int>> gradeItemScore = new Dictionary<string, List<int>>();
            Dictionary<string, int> gradeItemStuCount = new Dictionary<string, int>();
            List<KeyValuePair<string, List<double>>> classdatas = new List<KeyValuePair<string, List<double>>>();
            try
            {
                e.classes.ForEach(c =>
                {
                    //初始化每题得分情况
                    List<int> answerCount = new List<int>();
                    List<double> persent = new List<double>();
                    int peopleCount = 0;
                    for (int n = 0; n < e.paper.point.Count; n++)
                    {
                        answerCount.Add(0);
                    }
                    int qCount = 0;
                    //每个班级得分占比
                    for (int i = c.range[0]; i <= c.range[1]; i++)
                    {
                        if (e.studentScores[i].Sum() > 0)
                        {
                            for (int j = 0; j < e.studentScores[i].Count; j++)
                            {
                                if (e.studentScores[i][j] > 0)
                                {
                                    //记录班级每题得分数
                                    answerCount[j] = answerCount[j] + 1;
                                    //记录年级每题得分数
                                    examAnswer[j] = examAnswer[j] + 1;
                                }
                            }
                        }
                        else
                        {
                            qCount++;
                        }
                        peopleCount = c.range[1] - c.range[0] + 1 - qCount;
                    }
                    foreach (int p in answerCount)
                    {
                        var t = peopleCount > 0 ? Math.Round(p * 1.0 / peopleCount * 100, 2) : 0;
                        //var t = Math.Round(p * 1.0 / peopleCount * 100,2);
                        persent.Add(t);
                    }
                    classdatas.Add(new KeyValuePair<string, List<double>>(c.id, persent));
                    if (gradeItemScore.ContainsKey(c.gradeId))
                    {

                        var we = gradeItemScore[c.gradeId];

                        List<int> count = we;
                        for (int index = 0; index < count.Count; index++)
                        {
                            count[index] = count[index] + answerCount[index];

                        }
                        gradeItemScore[c.gradeId] = count;
                        // gradeItemScore[c.gradeId].ForEach(x => { x = x + answerCount[index]; index += 1; });
                        gradeItemStuCount[c.gradeId] = gradeItemStuCount[c.gradeId] + peopleCount;
                    }
                    else
                    {
                        gradeItemScore.Add(c.gradeId, answerCount);
                        gradeItemStuCount.Add(c.gradeId, peopleCount);
                    }
                });

                double[] point = StringHelper.ListTodouble(e.paper.point);
                double[,] result = StringHelper.ListToDouble(e.studentScores);
                var cdm = new ClouDASMatrix(result, point);
                //试题Y
                List<double> answer = cdm.AnswerRate;
                //试题X
                List<double> quality = cdm.QualityRate;
                //试题区域
                List<string> topic = cdm.TopicFallArea;
                //试题相关分析结果
                List<(double Diff, double D, double R1, double R2, double R3, double R4, double R5, double R6, double PH, double PL)> rs = cdm.RS;
                for (int i = 0; i < rs.Count; i++)
                {
                    string[] ex = new string[] { };
                    string ss = rs[i].ToString()[1..^1];
                    ex = ss.Split(",");
                    itemAnalysis.Add(ex);
                }
                foreach (int p in examAnswer)
                {
                    var t = Qnum > 0 ? Math.Round(p * 1.0 / Qnum * 100, 2) : 0;
                    //var t = Math.Round(p * 1.0 / Qnum * 100,2);
                    examPersent.Add(t.ToString());
                }
                for (int k = 0; k < e.paper.point.Count; k++)
                {
                    List<string> values = new List<string>();
                    paperKey.ForEach(x =>
                    {
                        values.Add("-");
                    });
                    values[0] = (k + 1).ToString();
                    if (e.paper.type.Count > 0)
                    {
                        values[1] = e.paper.type[k].ToString();
                    }
                    else
                    {
                        values[1] = "";
                    }

                    values[2] = topic[k].ToString();
                    values[3] = e.paper.point[k].ToString();
                    /*                    List<string> sk = new List<string>();
                                        foreach (string kl in e.paper.knowledge[k]) {                       
                                            sk.Add(kl);
                                        }*/
                    values[22] = string.Join(",", e.paper.knowledge[k]);
                    if (itemAnalysis.Count > 0)
                    {
                        values[4] = itemAnalysis[k][0];
                        values[5] = itemAnalysis[k][1].Trim();
                        values[12] = itemAnalysis[k][2];
                        values[13] = itemAnalysis[k][3];
                        values[14] = itemAnalysis[k][4];
                        values[15] = itemAnalysis[k][5];
                        values[16] = itemAnalysis[k][6];
                        values[17] = itemAnalysis[k][7];
                        values[18] = itemAnalysis[k][8];
                        values[19] = itemAnalysis[k][9];
                    }
                    else
                    {
                        values[4] = "-";
                        values[5] = "-";
                        values[12] = "-";
                        values[13] = "-";
                        values[14] = "-";
                        values[15] = "-";
                        values[16] = "-";
                        values[17] = "-";
                        values[18] = "-";
                        values[19] = "-";
                    }
                    Dictionary<string, double> its = new Dictionary<string, double>();
                    classdatas.ForEach(cls => { its.Add(cls.Key, cls.Value[k]); });
                    StringBuilder classBuilder = new StringBuilder();
                    foreach (var key in its.Keys)
                    {
                        classBuilder.Append(key + ":" + its[key] + ",");
                    }
                    var cstr = classBuilder.ToString();
                    values[7] = cstr.Substring(0, cstr.Length - 1);
                    StringBuilder gradeBuilder = new StringBuilder();
                    //处理年级的这个题的得分
                    foreach (var key in gradeItemScore.Keys)
                    {
                        var data = gradeItemStuCount[key] > 0 ? Math.Round(gradeItemScore[key][k] * 1.0 / gradeItemStuCount[key] * 100, 2) : 0;
                        //var data = Math.Round(gradeItemScore[key][k] * 1.0 / gradeItemStuCount[key] * 100, 2);
                        gradeBuilder.Append(key + ":" + data + ",");
                    }
                    var gstr = gradeBuilder.ToString();
                    values[8] = gstr.Substring(0, gstr.Length - 1);
                    values[20] = quality[k].ToString();
                    values[21] = answer[k].ToString();
                    // string pointName = "";                                     
                    values[23] = examPersent[k];
                    datas.Add(values);
                }
                Dictionary<string, List<double>> dict = new Dictionary<string, List<double>>();
                //处理年级的这个题的得分
                foreach (var key in gradeItemScore.Keys)
                {
                    List<double> gscores = new List<double>();
                    gradeItemScore[key].ForEach(x =>
                    {
                        var data = gradeItemStuCount[key] > 0 ? Math.Round(x * 1.0 / gradeItemStuCount[key] * 100, 2) : 0;
                        //var data = Math.Round(x * 1.0 / gradeItemStuCount[key] * 100, 2);
                        gscores.Add(data);
                    });
                    dict.TryAdd(key, gscores);
                }
                KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(e.subjectId, datas);
                KeyValuePair<string, List<KeyValuePair<string, List<double>>>> classdata = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(e.subjectId, classdatas);
                return (keyValue, classdata, dict);

            }
            catch (Exception ex)
            {
                // throw new BizException(ex.Message);
            }
            return (default, default, default);
        }

        //落点分析
        private KeyValuePair<string, List<KeyValuePair<string, List<string>>>> DoSubjectScatter(ExamResult e)
        {
            List<KeyValuePair<string, List<string>>> datas = new List<KeyValuePair<string, List<string>>>();
            double[] point = StringHelper.ListTodouble(e.paper.point);
            double[,] result = StringHelper.ListToDouble(e.studentScores);
            try
            {
                var cdm = new ClouDASMatrix(result, point);
                //学生通过率
                List<double> pass = cdm.ScoringRate;
                //学生稳定度
                List<double> sta = cdm.StabilityRate;
                //落点区域
                List<string> stu = cdm.StuFallArea;
                //需努力的题型
                List<int[]> strive = cdm.StriveTopic;
                //需小心的题型
                List<int[]> careful = cdm.CarefulTopic;
                int i = 0;
                for (int k = e.studentIds.Count - 1; k >= 0; k--)
                {
                    if (e.studentIds[k].Equals("0"))
                    {
                        e.studentIds.Remove(e.studentIds[k]);
                    }
                }
                e.studentIds.ForEach(s =>
                {
                    /*                    if (e.studentScores[i].Sum() != 0)
                                        {*/

                    List<string> info = new List<string>
                                {
                                    s,
                                    "-",
                                    sta[i].ToString(),
                                    pass[i].ToString(),
                                    i + 1 + "",
                                    e.studentScores[i].Sum().ToString()
                                };
                    int right = 0;
                    int wrong = 0;
                    foreach (int p in e.studentScores[i])
                    {
                        if (p > 0)
                        {
                            right++;
                        }
                        else
                        {
                            wrong++;
                        }
                    }
                    info.Add(right + "");
                    info.Add(wrong + "");
                    int[] str = strive[i];
                    string striveAll = "";

                    foreach (int n in str)
                    {
                        striveAll += n.ToString() + ",";
                    }
                    int[] care = careful[i];
                    string careAll = "";
                    foreach (int n in care)
                    {
                        careAll += n.ToString() + ",";
                    }
                    if (string.IsNullOrEmpty(striveAll))
                    {
                        info.Add("-");
                    }
                    else
                    {
                        info.Add(striveAll.Substring(0, striveAll.Length - 1));
                    }
                    if (string.IsNullOrEmpty(careAll))
                    {
                        info.Add("-");
                    }
                    else
                    {
                        info.Add(careAll.Substring(0, careAll.Length - 1)); ;
                    }
                    info.Add(stu[i].ToString());
                    KeyValuePair<string, List<string>> keyValue = new KeyValuePair<string, List<string>>(s, info);
                    datas.Add(keyValue);

                    //}
                    i++;
                });
                return new KeyValuePair<string, List<KeyValuePair<string, List<string>>>>(e.subjectId, datas);
            }
            catch (Exception ex)
            {
                BadRequest(ex.Message + ex.StackTrace);
                Console.WriteLine("---------------------" + ex.Message + "--------------------------");
            }
            return default;
        }
        private static (KeyValuePair<string, List<string>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoKnowledgePoint(ExamResult exam, ExamInfo info, List<string> keynowWrong)
        {
            HashSet<string> knowledge = new HashSet<string>();
            //HashSet<string> area = new HashSet<string>();
            List<double> point = new List<double>();
            List<List<double>> result = new List<List<double>>();
            List<ClassRange> classes = new List<ClassRange>();
            //List<string> ids = new List<string>();

            List<KeyValuePair<string, List<double>>> datas = new List<KeyValuePair<string, List<double>>>();
            //求单个知识点所占分数
            List<string> per = new List<string>();
            //List<string> gper = new List<string>();
            //List<string> knowPer = new List<string>();

            //Dictionary<string, object> wrongMap = new Dictionary<string, object>();
            List<List<string>> wrongPersent = new List<List<string>>();

            //定位试卷信息
            int index = 0;
            foreach (ExamSubject subject in info.subjects)
            {
                if (subject.id.Equals(exam.subjectId))
                {
                    break;
                }
                else
                {
                    index++;
                }
            }
            if (info.papers[index].knowledge != null && info.papers[index].knowledge.Count > 0)
            {
                info.papers[index].knowledge.ForEach(k =>
                {
                    k.ForEach(e =>
                    {
                        knowledge.Add(e);
                    });
                });
            }
            else
            {
                return (default, default, default, default, default, default);
            }
            point = info.papers[index].point;
            result = exam.studentScores;
            classes = exam.classes;
            //ids = exam.studentIds;
            //确定高分组 低分组人数
            List<List<double>> re = exam.studentScores;
            List<double> resultSum = new List<double>();
            foreach (List<double> data in re)
            {
                resultSum.Add(data.Sum());
            }
            //确定高分组 最低分数
            resultSum.Sort((s1, s2) => { return s2.CompareTo(s1); });
            double rhwCount = Math.Floor(resultSum.Count * 0.27);
            double rhw = rhwCount > 0 ? resultSum[int.Parse(rhwCount.ToString("0"))] : 0;
            double rhlCount = Math.Ceiling(resultSum.Count * 0.73);
            double rhl = rhlCount > 0 ? resultSum[int.Parse(rhlCount.ToString("0"))] : 0;
            //double rhl = resultSum[int.Parse(rhwCount.ToString("0"))];

            List<string> knowledgeName = new List<string>();
            foreach (string cla in knowledge)
            {
                knowledgeName.Add(cla);
            }
            for (int k = 0; k < knowledgeName.Count; k++)
            {
                if (null == knowledgeName[k])
                {
                    knowledgeName.Remove(knowledgeName[k]);
                }
            }
            //初始化年级总分
            double total = 0;
            //处理年级单个知识点得分率
            foreach (List<double> grade in result)
            {
                total += grade.Sum();
            }
            //试卷总分
            double TotalPoint = point.Sum();
            List<double> knowScore = new List<double>();
            //得分率
            List<double> Score = new List<double>();
            //分值
            List<double> kScore = new List<double>();
            for (int k = 0; k < knowledgeName.Count; k++)
            {
                double OnePoint = 0;
                List<string> valuew = new List<string>();
                List<string> itemNo = new List<string>();
                keynowWrong.ForEach(x =>
                {
                    valuew.Add("-");
                });
                valuew[0] = knowledgeName[k];
                int n = 0;
                int wrong = 0;
                int rhwC = 0;
                int rhlC = 0;
                int scoreCount = 0;
                double scores = 0;
                //知识点分值
                double gPoint = 0;
                info.papers[index].knowledge.ForEach(kno =>
                    {
                        if (kno.Contains(knowledgeName[k]))
                        {
                            var itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
                            OnePoint += point[n];
                            itemNo.Add((n + 1).ToString());
                            //处理单个知识点错题人数
                            int phCount = 0;
                            int plCount = 0;
                            foreach (string id in exam.studentIds)
                            {
                                int index = exam.studentIds.IndexOf(id);
                                if (exam.studentScores[index][n] == 0)
                                {
                                    wrong++;
                                    if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
                                    {
                                        rhwC++;
                                        phCount++;
                                        continue;
                                    }
                                    if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
                                    {
                                        rhlC++;
                                        plCount++;
                                        continue;
                                    }
                                    continue;
                                }
                                else
                                {
                                    //单个知识点得分情况
                                    scores += exam.studentScores[index][n] * itemPersent;
                                    //scoreCount++;
                                }
                                /*if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
                                {
                                    rhwC++;
                                    phCount++;
                                    continue;
                                }
                                if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
                                {
                                    rhlC++;
                                    plCount++;
                                    continue;
                                }*/
                            }
                            gPoint += point[n];
                        }
                        valuew[1] = OnePoint.ToString();
                        string itemNos = "";
                        if (itemNo.Count > 0)
                        {
                            foreach (string np in itemNo)
                            {
                                itemNos += np + ",";
                            }
                            valuew[2] = itemNos[0..^1];
                        }
                        else
                        {
                            valuew[2] = itemNos;
                        }
                        n++;
                    });
                kScore.Add(gPoint);
                Score.Add(scores);
                knowScore.Add(OnePoint);
                //该知识点平均得分
                double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
                //错题关系表
                valuew[3] = (sc / OnePoint).ToString();
                valuew[4] = wrong.ToString();
                valuew[5] = rhwC.ToString();
                valuew[6] = rhlC.ToString();
                wrongPersent.Add(valuew);
                //知识点占比
                double persent = TotalPoint > 0 ? OnePoint / TotalPoint : 0;
                //double persent = OnePoint / TotalPoint;
                per.Add(persent.ToString("0.00"));

            }
            //本次考试知识点占比
            List<double> allPer = new List<double>();
            foreach (double sc in Score)
            {
                allPer.Add(exam.studentIds.Count > 0 ? Math.Round(sc * 1.0 / exam.studentIds.Count, 2) : 0);
            }
            int stuNo = 0;
            exam.studentIds.ForEach(e =>
            {
                List<double> valueKnow = new List<double>();
                foreach (string know in knowledge)
                {
                    double anwPoint = 0;
                    double itemPersent = 0;
                    int sno = 0;
                    info.papers[index].knowledge.ForEach(kno =>
                    {
                        if (kno.Contains(know))
                        {
                            //当前知识点在该题占比多少
                            itemPersent = kno.Count > 0 ? 1 / Convert.ToDouble(kno.Count) : 0;
                            //itemPersent = 1 / Convert.ToDouble(kno.Count);
                            anwPoint += result[stuNo][sno] * itemPersent;
                        }
                        sno++;
                    });
                    valueKnow.Add(anwPoint);
                }
                KeyValuePair<string, List<double>> keyValue = new KeyValuePair<string, List<double>>(e, valueKnow);
                datas.Add(keyValue);
                stuNo++;
            });
            KeyValuePair<string, List<string>> key1 = new KeyValuePair<string, List<string>>(exam.subjectId, knowledgeName);
            KeyValuePair<string, List<string>> key2 = new KeyValuePair<string, List<string>>(exam.subjectId, per);
            KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
            KeyValuePair<string, List<double>> key4 = new KeyValuePair<string, List<double>>(exam.subjectId, kScore);
            KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(exam.subjectId, wrongPersent);
            KeyValuePair<string, List<KeyValuePair<string, List<double>>>> valuePair = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(exam.subjectId, datas);
            return (key1, key2, key3, key4, keyValue, valuePair);
        }



        private static (KeyValuePair<string, List<int>>, KeyValuePair<string, List<string>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<double>>, KeyValuePair<string, List<List<string>>>, KeyValuePair<string, List<KeyValuePair<string, List<double>>>>) DoLevel(ExamResult exam, ExamInfo info, List<string> keynowWrong)
        {
            List<double> point = new List<double>();
            List<List<double>> result = new List<List<double>>();
            List<ClassRange> classes = new List<ClassRange>();
            List<KeyValuePair<string, List<double>>> datas = new List<KeyValuePair<string, List<double>>>();
            //求单个认知层次所占分数
            List<string> per = new List<string>();
            List<List<string>> wrongPersent = new List<List<string>>();
            List<int> knowledgeName = new List<int>();
            //定位试卷信息
            int index = 0;
            foreach (ExamSubject subject in info.subjects)
            {
                if (subject.id.Equals(exam.subjectId))
                {
                    break;
                }
                else
                {
                    index++;
                }
            }
            knowledgeName.Add(1);
            knowledgeName.Add(2);
            knowledgeName.Add(3);
            knowledgeName.Add(4);
            knowledgeName.Add(5);
            knowledgeName.Add(6);

            //double Qnum = 0;
            point = info.papers[index].point;
            result = exam.studentScores;
            classes = exam.classes;
            //ids = exam.studentIds;
            //确定高分组 低分组人数
            List<List<double>> re = exam.studentScores;
            List<double> resultSum = new List<double>();
            foreach (List<double> data in re)
            {
                resultSum.Add(data.Sum());
            }
            //确定高分组 最低分数
            resultSum.Sort((s1, s2) => { return s2.CompareTo(s1); });
            double rhwCount = Math.Floor(resultSum.Count * 0.27);
            double rhw = rhwCount > 0 ? resultSum[int.Parse(rhwCount.ToString("0"))] : 0;
            double rhlCount = Math.Ceiling(resultSum.Count * 0.73);
            double rhl = rhlCount > 0 ? resultSum[int.Parse(rhlCount.ToString("0"))] : 0;

            //初始化年级总分
            double total = 0;
            //处理年级单个知识点得分率
            foreach (List<double> grade in result)
            {
                total += grade.Sum();
            }
            //试卷总分
            double TotalPoint = point.Sum();
            List<double> knowScore = new List<double>();
            //得分率
            List<double> Score = new List<double>();
            //分值
            List<double> kScore = new List<double>();
            //List<double> allPer = new List<double>();
            for (int k = 0; k < knowledgeName.Count; k++)
            {
                double OnePoint = 0;
                List<string> valuew = new List<string>();
                List<string> itemNo = new List<string>();
                keynowWrong.ForEach(x =>
                {
                    valuew.Add("-");
                });
                valuew[0] = knowledgeName[k].ToString();
                int n = 0;
                int wrong = 0;
                int rhwC = 0;
                int rhlC = 0;
                //int scoreCount = 0;
                double scores = 0;
                //所有认知层次得分
                double anwGPoint = 0;
                double gPoint = 0;
                info.papers[index].field.ForEach(kno =>
                {
                    if (kno == knowledgeName[k])
                    {
                        OnePoint += point[n];
                        itemNo.Add((n + 1).ToString());
                        //处理认知层次错题人数
                        int phCount = 0;
                        int plCount = 0;
                        foreach (string id in exam.studentIds)
                        {
                            int index = exam.studentIds.IndexOf(id);
                            if (exam.studentScores[index][n] == 0)
                            {
                                wrong++;
                                if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount)
                                {
                                    rhwC++;
                                    phCount++;
                                    continue;
                                }
                                if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount))
                                {
                                    rhlC++;
                                    plCount++;
                                    continue;
                                }
                                continue;
                            }
                            else
                            {
                                //单个认知层次得分情况
                                scores += exam.studentScores[index][n];
                            }
                           /* if (exam.studentScores[index].Sum() >= rhw && phCount < rhwCount && exam.studentScores[index][n] == 0)
                            {
                                rhwC++;
                                phCount++;
                                continue;
                            }
                            if (exam.studentScores[index].Sum() <= rhl && plCount < (exam.studentIds.Count - rhlCount) && exam.studentScores[index][n] == 0)
                            {
                                rhlC++;
                                plCount++;
                                continue;
                            }*/
                            //anwGPoint += exam.studentScores[index][n];
                        }
                        gPoint += point[n];
                    }
                    valuew[1] = OnePoint.ToString();
                    string itemNos = "";
                    if (itemNo.Count > 0)
                    {
                        foreach (string np in itemNo)
                        {
                            itemNos += np + ",";
                        }
                        valuew[2] = itemNos[0..^1];
                    }
                    else
                    {
                        valuew[2] = itemNos;
                    }
                    n++;
                });
                Score.Add(scores);
                kScore.Add(gPoint);
                knowScore.Add(OnePoint);
                double sc = exam.studentIds.Count > 0 ? Math.Round(scores * 1.0 / exam.studentIds.Count, 2) : 0;
                //错题关系表

                valuew[3] = (OnePoint > 0 ? Math.Round(sc / OnePoint, 2) : 0).ToString();
                valuew[4] = wrong.ToString();
                valuew[5] = rhwC.ToString();
                valuew[6] = rhlC.ToString();
                wrongPersent.Add(valuew);
                //认知层次占比
                double persent = TotalPoint > 0 ? OnePoint / TotalPoint : 0;
                //allPer.Add(OnePoint > 0 ? Math.Round(sc / OnePoint, 2) : 0);
                per.Add(persent.ToString("0.00"));
            }
            //本次考试认知层次占比
            List<double> allPer = new List<double>();
            foreach (double sc in Score)
            {
                allPer.Add(exam.studentIds.Count > 0 ? Math.Round(sc * 1.0 / exam.studentIds.Count, 2) : 0);
            }
            int stuNo = 0;
            exam.studentIds.ForEach(e =>
            {
                List<double> valueKnow = new List<double>();
                foreach (int know in knowledgeName)
                {
                    double anwPoint = 0;
                    double itemPersent = 0;
                    int sno = 0;
                    info.papers[index].field.ForEach(kno =>
                    {
                        if (kno == know)
                        {
                            //当前认知层次在该题占比多少
                            itemPersent = 1;
                            anwPoint += result[stuNo][sno] * itemPersent;
                        }
                        sno++;
                    });
                    valueKnow.Add(anwPoint);
                }
                KeyValuePair<string, List<double>> keyValue = new KeyValuePair<string, List<double>>(e, valueKnow);
                datas.Add(keyValue);
                stuNo++;
            });
            KeyValuePair<string, List<int>> key1 = new KeyValuePair<string, List<int>>(exam.subjectId, knowledgeName);
            KeyValuePair<string, List<string>> key2 = new KeyValuePair<string, List<string>>(exam.subjectId, per);
            KeyValuePair<string, List<double>> key3 = new KeyValuePair<string, List<double>>(exam.subjectId, allPer);
            KeyValuePair<string, List<double>> key4 = new KeyValuePair<string, List<double>>(exam.subjectId, kScore);
            KeyValuePair<string, List<List<string>>> keyValue = new KeyValuePair<string, List<List<string>>>(exam.subjectId, wrongPersent);
            KeyValuePair<string, List<KeyValuePair<string, List<double>>>> valuePair = new KeyValuePair<string, List<KeyValuePair<string, List<double>>>>(exam.subjectId, datas);
            return (key1, key2, key3, key4, keyValue, valuePair);
        }
        [HttpPost("simple")]
        public async Task<IActionResult> simple(JsonElement request)
        {
            //获取评测的ID
            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
            try
            {
                List<Dictionary<string, object>> averageMap = new List<Dictionary<string, object>>();
                List<Dictionary<string, object>> averageTotal = new List<Dictionary<string, object>>();
                var client = _azureCosmos.GetCosmosClient();
                ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));
                List<ExamResult> examResults = new List<ExamResult>();
                var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes from c where c.examId =  '{id}' ";
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
                {
                    examResults.Add(item);
                }
                foreach (ExamResult result in examResults)
                {
                    List<double> ClassAverage = new List<double>();
                    List<ClassSimple> ClassName = new List<ClassSimple>();
                    Dictionary<string, object> mapSubject = new Dictionary<string, object>();
                    Dictionary<string, object> mapClass = new Dictionary<string, object>();
                    mapClass.Add("subjectId", result.subjectId);
                    foreach (ClassRange range in result.classes)
                    {
                        ClassSimple classSimple = new ClassSimple();
                        classSimple.id = range.id;
                        classSimple.name = range.name;
                        ClassName.Add(classSimple);
                        double totalClass = 0;
                        for (int i = range.range[0]; i <= range.range[1]; i++)
                        {
                            totalClass += result.studentScores[i].Sum();
                        }
                        ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? totalClass * 1.0 / (range.range[1] - range.range[0] + 1) : 0);
                    }
                    mapClass.Add("className", ClassName);
                    mapClass.Add("ClassAverage", ClassAverage);
                    averageMap.Add(mapClass);
                    List<double> SubjectTotal = new List<double>();
                    foreach (List<double> score in result.studentScores)
                    {
                        SubjectTotal.Add(score.Sum());
                    }
                    mapSubject.Add("subjectId", result.subjectId);
                    mapSubject.Add("total", SubjectTotal);
                    averageTotal.Add(mapSubject);
                }
                return Ok(new { averageMap, averageTotal });
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，analysis/simple()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
        public class ClassSimple
        {
            public string id { get; set; }
            public string name { get; set; }
        }


        [HttpPost("studentAnalysis")]
        public async Task<IActionResult> studentAnalysis(JsonElement request)
        {
            //获取个人或者校本
            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
            //评测Id
            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
            if (!request.TryGetProperty("sId", out JsonElement sId)) return BadRequest();
            if (!request.TryGetProperty("cId", out JsonElement cId)) return BadRequest();
            if (!request.TryGetProperty("gId", out JsonElement gId)) return BadRequest();
            try
            {
                List<Dictionary<string, object>> averageMap = new();
                List<Dictionary<string, object>> averageTotal = new();
                List<List<double>> classAllAverage = new();
                School school = new();
                var client = _azureCosmos.GetCosmosClient();
                ExamInfo info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"Exam-{code}"));

                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(code.ToString(), new PartitionKey($"Base"));
                if (response.Status == 200)
                {
                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
                    school = json.ToObject<School>();
                }   
                //School school = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<School>(code.ToString(), new PartitionKey($"Base"));
                List<ExamResult> examResults = new List<ExamResult>();
                var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes from c where c.examId =  '{id}' ";
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{id}") }))
                {
                    examResults.Add(item);
                }
                if (examResults.Count == 0)
                {
                    return Ok(new { code = ResponseCode.DATA_EMPTY_NULL, v = "正在结算中" });
                }
                int indexClass = 0;
                HashSet<string> cla = new HashSet<string>();
                HashSet<string> stu = new HashSet<string>();
                double totalScore = 0;
                List<List<double>> allList = new List<List<double>>();
                double income = 0;
                foreach (Period period in school.period)
                {
                    if (info.period.id.Equals(period.id))
                    {
                        income = period.analysis.income;
                    }
                }
                //获取进线人数
                int count = (int)System.Math.Round(info.stuCount * (income / 100.0), MidpointRounding.AwayFromZero);
                foreach (ExamResult result in examResults)
                {

                    List<double> ClassAverage = new List<double>();
                    List<int> personCount = new List<int>();
                    List<string> ClassId = new List<string>();
                    Dictionary<string, object> mapClass = new Dictionary<string, object>();
                    int index = result.studentIds.IndexOf(sId.ToString());
                    //个人总分
                    totalScore += result.studentScores[index].Sum();
                    mapClass.Add("subjectId", result.subjectId);
                    double totalGrade = 0;
                    List<double> gradeScores = new List<double>();
                    List<List<double>> classScores = new List<List<double>>();
                    //此处声明集合存储原本的成绩序列
                    List<List<double>> cScores = new List<List<double>>();
                    foreach (ClassRange range in result.classes)
                    {
                        List<double> scores = new List<double>();
                        List<double> finalScores = new List<double>();
                        if (!string.IsNullOrEmpty(range.gradeId))
                        {
                            if (range.gradeId.Equals(gId.ToString(), StringComparison.OrdinalIgnoreCase))
                            {
                                ClassId.Add(range.id);
                                cla.Add(range.id);
                                double totalClass = 0;
                                for (int i = range.range[0]; i <= range.range[1]; i++)
                                {
                                    totalClass += result.studentScores[i].Sum();
                                    scores.Add(result.studentScores[i].Sum());
                                    finalScores.Add(result.studentScores[i].Sum());
                                    gradeScores.Add(result.studentScores[i].Sum());
                                    totalGrade += result.studentScores[i].Sum();
                                    stu.Add(result.studentIds[i]);
                                }
                                classScores.Add(scores);
                                cScores.Add(finalScores);
                                ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? Math.Round(totalClass * 1.0 / (range.range[1] - range.range[0] + 1), 2) : 0);
                                personCount.Add(range.range[1] - range.range[0] + 1);
                            }
                        }
                        else {
                            ClassId.Add(range.id);
                            cla.Add(range.id);
                            double totalClass = 0;
                            for (int i = range.range[0]; i <= range.range[1]; i++)
                            {
                                totalClass += result.studentScores[i].Sum();
                                scores.Add(result.studentScores[i].Sum());
                                finalScores.Add(result.studentScores[i].Sum());
                                gradeScores.Add(result.studentScores[i].Sum());
                                totalGrade += result.studentScores[i].Sum();
                                stu.Add(result.studentIds[i]);
                            }
                            classScores.Add(scores);
                            cScores.Add(finalScores);
                            ClassAverage.Add(range.range[1] - range.range[0] + 1 > 0 ? Math.Round(totalClass * 1.0 / (range.range[1] - range.range[0] + 1), 2) : 0);
                            personCount.Add(range.range[1] - range.range[0] + 1);
                        }
                        
                    }
                    classAllAverage.Add(ClassAverage);
                    gradeScores.Sort((s1, s2) => { return s2.CompareTo(s1); });
                    indexClass = ClassId.IndexOf(cId.ToString());
                    //单科成绩
                    allList.Add(cScores[indexClass]);
                    classScores[indexClass].Sort((s1, s2) => { return s2.CompareTo(s1); });
                    mapClass.Add("scoreSum", result.paper.point.Sum());
                    mapClass.Add("score", result.studentScores[index].Sum());
                    mapClass.Add("classAverage", ClassAverage[indexClass]);
                    mapClass.Add("classCount", personCount[indexClass]);
                    mapClass.Add("classRank", classScores[indexClass].IndexOf(result.studentScores[index].Sum()));
                    mapClass.Add("gradeAverage", result.studentIds.Count > 0 ? Math.Round(totalGrade * 1.0 / result.studentIds.Count, 2) : 0);
                    mapClass.Add("gradeCount", result.studentIds.Count);
                    mapClass.Add("gradeRank", gradeScores.IndexOf(result.studentScores[index].Sum()));
                    averageMap.Add(mapClass);
                }
                //处理班级/年级全科均分
                List<double> AllAverage = new List<double>();
                double a = 0;
                for (int k = 0; k < cla.Count; k++)
                {
                    for (int i = 0; i < classAllAverage.Count; i++)
                    {
                        a += classAllAverage[i][k];
                    }
                    AllAverage.Add(a);
                }
                List<double> classScore = new List<double>();
                for (int i = 0; i < allList[0].Count; i++)
                {
                    double b = 0;
                    for (int m = 0; m < allList.Count; m++)
                    {
                        b += allList[m][i];
                    }
                    classScore.Add(b);
                }
                classScore.Sort((s1, s2) => { return s2.CompareTo(s1); });
                //处理年级总分以及排名
                List<double> GradeScore = new List<double>();
                foreach (string ss in stu)
                {
                    double score = 0;
                    foreach (ExamResult result in examResults)
                    {
                        int index = result.studentIds.IndexOf(ss);
                        score += result.studentScores[index].Sum();
                    }
                    GradeScore.Add(score);
                }
                GradeScore.Sort((s1, s2) => { return s2.CompareTo(s1); });
                double ipoint = GradeScore[count];
                return Ok(new { income = ipoint, rankc = classScore.IndexOf(totalScore), rankg = GradeScore.IndexOf(totalScore), classAverage = Math.Round(AllAverage[indexClass], 2), gradeAverage = cla.Count > 0 ? Math.Round(AllAverage.Sum() * 1.0 / cla.Count, 2) : 0, averageMap }); ;
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，analysis/studentAnalysis()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }

    }
}
