using System;
using System.Collections.Generic;

namespace mxdemo.Mind
{
    public interface IStudentClassDispatchService
    {
        // 1 班级设置 参考校长的class-manage页面
        //   a 从年级树缓存中查找当前选科学年对应的班级进行选择
        //   b 允许用户输入不存在的班级，输入完毕后确认是否创建新班级
        //       附：（创建后务必刷新缓存）（暂不考虑批量创建班级）（创建接口参考class-manage页面）

        // 2 应用班级设置 设置人数及分配模式，得到初步分派的结果
        // 3 手工微调 将查询组件化，允许加入多个对比查询，作选中操作，执行转移/或者交换操作

        #region model

        /// <summary>
        /// 选科轮次，仅显示分班关键字段，后续可能还会加选科流程的其它字段
        /// </summary>
        public class Round
        {
            // 本身的字段
            int roundId; // 选科轮次ID
            string groupIds; // 开放组合
            object[] roundGroups; // 这里包含各组合以及班级数设置
            // ...

            // 流程控制字段
            bool allowDispatch; // 标记当前是否可以进行分班逻辑
            Dictionary<int, int> enrollGroupCount; // 各组合录取人数，按组合汇总
            bool dispatchCompleted; // 所有学生已经分配完毕
        }

        /// <summary>
        /// 班级，仅显示分班关键字段
        /// </summary>
        public class Clazz
        {
            int classId;
            string name;
        }

        public class Student
        {
            int studentId;
            int sex;
            int rankInGroup; // 组合内排名
        }

        public class DispatchSetting
        {
            int roundId; // 轮次ID
            int groupId; // 组合ID

            int classId; // 班级
            int expectedCount; // 期望人数
            int? actualCount; // 实际人数，应用设置才产生数量
            int? actualCountInMale; // 实际男生，应用设置才产生数量
            int? actualCountInFemale; // 实际女生，应用设置才产生数量
        }

        public class DispatchResult
        {
            int roundId; // 轮次ID
            int groupId; // 组合ID

            int classId; // 班级
            Student[] students; // 分配的学生
        }

        public enum EnumDispatchMode
        {
            RankBalance, // 按成绩平均分配，默认按这种分配方式，可保证各个班成绩都差不多
            RankPriority, // 按成绩优先，会导致成绩好的集中到一起
            Random // 随机
        }

        /// <summary>
        /// 查询参数
        /// </summary>
        public class DispatchQuery
        {
            int roundId;
            int groupId;
            int classId;
            int? sex;
        }
        #endregion
        /// <summary>
        /// 按学年，次数查询
        /// ROUND: 如果allowDispatch=false,分班页仅只读不能操作
        /// </summary>
        /// <returns></returns>
        Round GetRoundStatus(int year, int round); // 类似/front/report/getStudentSelected

        /// <summary>
        /// 获取分班配置
        /// </summary>
        /// <param name="roundId"></param>
        /// <returns></returns>
        DispatchSetting[] GetDispatchSettings(int roundId);

        /// <summary>
        /// 保存配置
        /// </summary>
        /// <param name="settings"></param>
        void SaveDispatchSettings(DispatchSetting[] settings);

        /// <summary>
        /// 应用配置，分派学生，按组合执行
        /// </summary>
        /// <param name="roundId"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        DispatchResult ApplyDispatchSettings(int roundId, int groupId, EnumDispatchMode mode = EnumDispatchMode.RankBalance);

        /// <summary>
        /// 分派名单查询，不需要分页，按班展示，启动table排序功能
        /// </summary>
        /// <param name="roundId"></param>
        /// <param name="groupIds"></param>
        /// <returns></returns>
        DispatchResult GetDispatchResult(DispatchQuery query);

        /// <summary>
        /// 分派转移，用这个接口实现转移学生或者交换学生（手工操作），后台在操作成功后记得刷新setting中的3个人数汇总字段
        /// </summary>
        /// <param name="roundId"></param>
        /// <param name="students"></param>
        /// <param name="toClassId"></param>
        void ExchangeDispatch(int roundId, Student[] students, int toClassId);

        /// <summary>
        /// 分配完毕后发布，锁定分班流程
        /// </summary>
        /// <param name="roundId"></param>
        void PublishDispatch(int roundId);
    }
}
