using System;
using System.Collections.Generic;
using System.Linq;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;

using TEAMModelOS.SDK.Models;


namespace TEAMModelOS.Services.Analysis
{
    public static class AchievementService 
    {

        
        //处理各个班级均分分析
        public static Dictionary<string, object> GetAverage(List<ExamResultDto> exams, List<string> gav, List<string> cav, List<List<double>> subSum, List<OldStudent> students)
        {
            Dictionary<string, object> Average = new Dictionary<string, object>();
            List<List<string>> classAverage = new List<List<string>>();
            HashSet<string> classList = new HashSet<string>();
            List<string> keys = new List<string>();
            if (exams.IsNotEmpty())
            {
                keys.Add("setNo");
                keys.Add("name");
                keys.Add("score");
                keys.Add("classAverage");               
                keys.Add("gradeAverage");
                int j = 0;
                exams[0].classes.ForEach(c =>
                    {
                        //c.Keys遍历key值
                        foreach (string key in c.Keys)
                        {
                            classList.Add(key);
                        }
                        int k = 0;
                        //每个班级平均分
                        foreach (int[] value in c.Values)
                        {  
                            for (int i = value[0]; i <= value[1]; i++)
                            {
                                List<string> stuPoint = new List<string>();
                                keys.ForEach(x =>
                                {
                                    stuPoint.Add("-");
                                });
                                stuPoint[0] = (i + 1).ToString();
                                foreach (OldStudent ss in students)
                                {
                                    if (exams[0].ids[i].Equals(ss.studentId))
                                    {
                                        stuPoint[1] = ss.name;
                                        break;
                                    }
                                }
                                
                                stuPoint[2] = subSum[j][k].ToString() ;
                                stuPoint[3] = cav[j];
                                stuPoint[4] = gav[0];
                                classAverage.Add(stuPoint);
                                k++;
                            }
                            j++;
                        }                       
                    });
                Average.Add("keys",keys);
                Average.Add("datas", classAverage);
            }
            return Average;
                
        }

        public static List<Dictionary<string, object>> GetPR(List<ExamResultDto> exams, List<List<double>> subSum,List<OldStudent> students)
        {
            // 计算公式 PR=100- (100*R-50)/N
            List<Dictionary<string, object>> subPR = new List<Dictionary<string, object>>();
            List<Dictionary<string, object>> datas = new List<Dictionary<string, object>>();
            HashSet<string> classList = new HashSet<string>();
            List<string> keys = new List<string>();
            List<string> className = new List<string>();
            if (exams.IsNotEmpty()) {
                keys.Add("name");
                keys.Add("setNo");
                keys.Add("score");
                keys.Add("classRank");
                keys.Add("classPR");
                keys.Add("gradeRank");
                keys.Add("gradePR");
                keys.Add("areaRank");
                keys.Add("areaPR");
                //keys.Add("classAverage");
                //keys.Add("gradeAverage");
                
                exams.ForEach(e =>
                {
                    Dictionary<string, object> PR = new Dictionary<string, object>
                    {
                        { "name", e.subjectCode }
                    };
                    List<string> stuPRG = new List<string>();
                    List<string> ClassAverage = new List<string>();
                    List<List<List<string>>> classPR = new List<List<List<string>>>();
                    //初始化科目总分
                    double subjectPoint = 0;

                    //科目平均分
                    double subAverage = 0;
                    e.classes.ForEach(c =>
                    {
                        List<List<string>> classPRL = new List<List<string>>();
                        //c.Keys遍历key值
                        List<string> stuPR = new List<string>();
                        //初始化各班参考人数
                        int counts = 0;
                        //初始化班级缺考人数
                        int classCount = 0;
                        //初始化班级平均分
                        double points = 0;
                        //初始化班级总分
                        double classPoint = 0;
                        foreach (string key in c.Keys)
                        {
                            classList.Add(key);
                        }
                        //每个班级平均分
                        foreach (int[] value in c.Values)
                        {
                            int seatNo = 1;
                            for (int i = value[0]; i <= value[1]; i++)
                            {
                                List<string> SPR = new List<string>();
                                keys.ForEach(x =>
                                {
                                    SPR.Add("-");
                                });
                                if (e.result[i].Sum() == 0)
                                {
                                    classCount++;
                                    seatNo++;
                                    continue;

                                }
                                stuPR.Add(e.result[i].Sum().ToString());
                                stuPRG.Add(e.result[i].Sum().ToString());
                                SPR[1] = seatNo.ToString() ;
                                SPR[2] = e.result[i].Sum().ToString();
                                SPR[0] = e.ids[i];
                                classPRL.Add(SPR);
                                //计算班级PR值
                                //int classPR = 100 - (100*)
                                classPoint += e.result[i].Sum();                               
                                seatNo++;
                            }
                            counts = value[1] - value[0] - classCount + 1;
                            points = Convert.ToDouble(classPoint) / counts;
                            ClassAverage.Add(points.ToString("0.00"));
                        }
                        
                        //foreach (List<string> pl in classPRL) {
                        //单科计算班级排名
                        stuPR.Sort(delegate (string s1, string s2) { return double.Parse(s2).CompareTo(double.Parse(s1)); });
                        
                        foreach (List<string> pl in classPRL) {
                            
                            int index = stuPR.IndexOf(pl[2]);
                            //int gradeIndex = stuPRG.IndexOf(pl[2]);
                            pl[3] = (index + 1).ToString();
                            int CPR = 100 - (100 * int.Parse(pl[3]) - 50) / stuPR.Count;
                            pl[4] = CPR.ToString();
                            //pl.Add(index.ToString());
                            foreach (OldStudent ss in students)
                            {
                                if (pl[0].Equals(ss.studentId))
                                {
                                    pl[0] = ss.name;
                                    break;
                                }
                            }
                        }

                        //}
                        classPR.Add(classPRL);

                    });
                    //科目平均分
                    ClassAverage.ForEach(a =>
                    {
                        subjectPoint += Convert.ToDouble(a);
                    });
                    subAverage = subjectPoint / ClassAverage.Count();
                    className = new List<string>();
                    foreach (string cla in classList)
                    {
                        className.Add(cla);
                    }
                    //单科计算年级排名
                    stuPRG.Sort(delegate (string s1, string s2) { return double.Parse(s2).CompareTo(double.Parse(s1)); });
                    foreach (List<List<string>> p2 in classPR) {
                        foreach (List<string> p3 in p2) {
                            int index = stuPRG.IndexOf(p3[2]);
                            p3[5] = (index + 1).ToString();
                            int GPR = 100 - (100 * int.Parse(p3[5]) - 50) / stuPRG.Count;
                            p3[6] = GPR.ToString();

                        }
                    }
                    Dictionary<string, object> data = new Dictionary<string, object>();
                    Dictionary<string, object> classData = new Dictionary<string, object>();
                    for (int i =0;i< classPR.Count;i++) {                        
                        data.Add(className[i], classPR[i]);
                        classData.Add(className[i], ClassAverage[i]);
                        //data.Add(i.ToString(), ClassAverage[i]);
                    }

                    PR.Add("keys", keys);
                    PR.Add("datas", data);
                    PR.Add("classAverage", classData);
                    PR.Add("gradeAverage", subAverage.ToString("0.00"));
                    PR.Add("areaAverage", subAverage.ToString("0.00"));
                    subPR.Add(PR);
                });
                //处理全科PR值计算
                List<string> stuIds = exams[0].ids;
                /*for (int k=0;k< stuIds.Count;k++) {
                    if (stuIds[k].Equals("0")) {
                        stuIds.Remove(stuIds[k]);
                    }
                }*/
                Dictionary<string, object> dataAll = new Dictionary<string, object>();
                dataAll.Add("name", "Total");
                dataAll.Add("keys",keys);
                List<double> stuAll = new List<double>();
                List<double> sortGradePoint = new List<double>();
                Dictionary<string, object> classInfo = new Dictionary<string, object>();
                List<List<List<string>>> GradePR = new List<List<List<string>>>();
                int m = 0;
                int p = 0;
                List<string> allClassAverages = new List<string>();
                Dictionary<string, object> classAllData = new Dictionary<string, object>();
                foreach (List<double> classPoint in subSum)
                {
                    List<double> sortClassPoint = new List<double>();
                    int n = 1;
                    //初始化缺考人数
                    int people = 0;
                    double sumTotle = 0;
                    List<List<string>> classStuInfo = new List<List<string>>();
                    for (int i = 0;i < classPoint.Count();i++) {
                        List<string> stu = new List<string>();
                        keys.ForEach(x =>
                        {
                            stu.Add("-");
                        });
                        if (stuIds[m] == "0")
                        {
                            people++;
                            n++;
                            m++;
                            continue;
                        }
                        stu[0] = stuIds[m];
                        stu[1] = n.ToString();
                        stu[2] = classPoint[i].ToString();
                        sortClassPoint.Add(classPoint[i]);
                        stuAll.Add(classPoint[i]);
                        sortGradePoint.Add(classPoint[i]);
                        sumTotle += classPoint[i];
                        n++;
                        m++;
                        classStuInfo.Add(stu);
                    }                   
                    double allClassAverage = sumTotle / (classPoint.Count - people);
                    classAllData.Add(className[p], allClassAverage.ToString("0.00"));
                    //allClassAverages.Add(allClassAverage.ToString("0.00"));
                    GradePR.Add(classStuInfo);
                    sortClassPoint.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
                    foreach (List<string> stuIn in classStuInfo) {
                        int index = sortClassPoint.IndexOf(double.Parse(stuIn[2]));
                        stuIn[3] = (index + 1).ToString();
                        int CPR = 100 - (100 * (index + 1) - 50) / sortClassPoint.Count;
                        stuIn[4] = CPR.ToString();
                        foreach (OldStudent ss in students)
                        {
                            if (stuIn[0].Equals(ss.studentId))
                            {
                                stuIn[0] = ss.name;
                                break;
                            }
                        }
                    }
                    p++;
                }
                sortGradePoint.Sort(delegate (double s1, double s2) { return s2.CompareTo(s1); });
                double allGradeAverage = sortGradePoint.Sum() / sortGradePoint.Count();
                foreach (List<List<string>> gradeInfo in GradePR)
                {
                    foreach (List<string> info in gradeInfo)
                    {
                        int index = sortGradePoint.IndexOf(double.Parse(info[2]));
                        info[5] = (index + 1).ToString();
                        int GPR = 100 - (100 * int.Parse(info[5]) - 50) / sortGradePoint.Count;
                        info[6] = GPR.ToString();

                    }
                }
                Dictionary<string, object> classDataAll = new Dictionary<string, object>();
                for (int i = 0; i < GradePR.Count; i++)
                {
                    classDataAll.Add(className[i], GradePR[i]);
                }
                dataAll.Add("datas", classDataAll);
                dataAll.Add("classAverage", classAllData);
                dataAll.Add("gradeAverage", allGradeAverage.ToString("0.00"));
                dataAll.Add("areaAverage", allGradeAverage.ToString("0.00"));
                subPR.Add(dataAll);
            }
            return subPR;


        }

        public static List<List<string>> ReName(List<List<string>> datas, List<string> ids, List<Dictionary<string, int[]>> classToName, List<OldStudent> students)
        {
            foreach (List<string> tableName in datas)
            {
                int index = ids.IndexOf(tableName[0]);
                if (index == -1)
                {
                    continue;
                }
                foreach (Dictionary<string, int[]> classKey in classToName)
                {
                    bool flag = false;
                    foreach (KeyValuePair<string, int[]> kvp in classKey)
                    {
                        if (kvp.Value[1] >= index && index >= kvp.Value[0])
                        {
                            tableName[1] = kvp.Key;
                            flag = true;
                            break;
                        }
                    }
                    if (flag)
                    {
                        break;
                    }
                }

                foreach (OldStudent ss in students)
                {
                    if (tableName[0].Equals(ss.studentId))
                    {
                        tableName[0] = ss.name;
                        break;
                    }
                }
            }

            return datas;
        }
    }
}
