using Azure.Cosmos;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Models;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos.Common;

namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("school/classroom")]
    [ApiController]
    public class ClassController : ControllerBase
    {
        public readonly AzureCosmosFactory _azureCosmos;
        private readonly Option _option;
        private readonly DingDing _dingDing;
        public ClassController(AzureCosmosFactory azureCosmos, DingDing dingDing,
            IOptionsSnapshot<Option> option)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
            _option = option?.Value;
        }
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("upsert")]
        public async ValueTask<IActionResult> Upsert(JsonElement requert)
        {
            //ResponseBuilder builder = ResponseBuilder.custom();
            //List<Student> students = null;
            Class classroom;
            if (!requert.TryGetProperty("classroom", out JsonElement room)) return BadRequest();
            if (!requert.TryGetProperty("option", out JsonElement option)) return BadRequest();
            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
            try
            {
                classroom = room.ToObject<Class>();
                var client = _azureCosmos.GetCosmosClient();
                classroom.code = "Class-" + school_code.ToString();
                //students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "classroomCode", classroom.id } });
                if (option.ToString().Equals("insert"))
                {
                    /*if (classroom.scope.Equals("private"))
                    {
                        List<string> resultIds = new List<string>();
                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                        {
                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                            {
                                var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                while (accounts.MoveNext())
                                {
                                    JsonElement account = accounts.Current;
                                    resultIds.Add(account.GetProperty("id").GetString());
                                }
                            }
                        }
                        if (resultIds.Count > 0)
                        {
                            return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在！" });
                        }
                        var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
                        if (response.Status == 200)
                        {
                            //classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(requert, new PartitionKey($"Classroom-{classroom.code}"));
                            return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级信息已经存在！" });
                        }
                        else
                        {
                            //string code = classroom.code;
                            //classroom.code = "Class-" + school_code;
                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(classroom, new PartitionKey($"Class-{school_code}"));

                        }
                    }
                    else
                    {*/
                        List<string> resultIds = new List<string>();
                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' and c.year = '{classroom.year}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                        {
                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                            {
                                var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                while (accounts.MoveNext())
                                {
                                    JsonElement account = accounts.Current;
                                    resultIds.Add(account.GetProperty("id").GetString());
                                }
                            }
                        }
                        if (resultIds.Count > 0)
                        {
                            return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在！" });
                        }
                        var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
                        if (response.Status == 200)
                        {
                            //classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(requert, new PartitionKey($"Classroom-{classroom.code}"));
                            return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级信息已经存在！" });
                        }
                        else
                        {
                            //string code = classroom.code;
                            //classroom.code = "Class-" + school_code;
                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(classroom, new PartitionKey($"Class-{school_code}"));

                        }
                   // }
                }
                else
                {
                    var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
                    if (response.Status == 200)
                    {
                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
                        Class @class = json.ToObject<Class>();
                        if (!@class.no.Equals(classroom.no))
                        {
                            List<string> resultIds = new List<string>();
                            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.year = '{classroom.year}' and c.no = '{classroom.no}' and c.periodId = '{classroom.periodId}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                            {
                                using var document = await JsonDocument.ParseAsync(item.ContentStream);
                                if (document.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                {
                                    var accounts = document.RootElement.GetProperty("Documents").EnumerateArray();
                                    while (accounts.MoveNext())
                                    {
                                        JsonElement account = accounts.Current;
                                        resultIds.Add(account.GetProperty("id").GetString());
                                    }
                                }
                            }
                            if (resultIds.Count > 0)
                            {
                                return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在！" });
                            }
                        }
                        classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
                    }
                    else {
                        classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync(classroom, new PartitionKey($"Class-{school_code}"));
                    }                                       
                        //检查该教室是否是老师创建的个人校本教室
                        /*var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(classroom.id, new PartitionKey($"Class-{school_code}"));
                        if (response.Status == 200)
                        {
                            List<string> resultIds = new List<string>();
                            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                            {
                                using var json = await JsonDocument.ParseAsync(item.ContentStream);
                                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                {
                                    var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                    while (accounts.MoveNext())
                                    {
                                        JsonElement account = accounts.Current;
                                        resultIds.Add(account.GetProperty("id").GetString());
                                    }
                                }
                            }
                            if (resultIds.Count > 0)
                            {
                                return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在！" });
                            }
                            classroom = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(classroom, classroom.id, new PartitionKey($"Class-{school_code}"));
                        }
                        else
                        {*/
                        /*                            List<string> resultIds = new List<string>();
                                                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"select c.id from c where c.periodId = '{classroom.periodId}' and c.no = '{classroom.no}' ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                                                    {
                                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
                                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                                        {
                                                            var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                                            while (accounts.MoveNext())
                                                            {
                                                                JsonElement account = accounts.Current;
                                                                resultIds.Add(account.GetProperty("id").GetString());
                                                            }
                                                        }
                                                    }
                                                    if (resultIds.Count > 0)
                                                    {
                                                        return Ok(new { error = ResponseCode.DATA_EXIST, V = "班级编码已经存在！" });
                                                    }
                                                    List<TeacherCourse> course = new List<TeacherCourse>();
                                                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select value(c) from c join A0 in c.classes where A0.id = '{classroom.id}'"))
                                                    {
                                                        using var json = await JsonDocument.ParseAsync(item.ContentStream);
                                                        if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                                        {
                                                            foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                                                            {
                                                                course.Add(obj.ToObject<TeacherCourse>());
                                                            }
                                                        }
                                                    }*/

                        /*                            for (int i = 0; i < course.Count; i++)
                                                    {
                                                        bool flag = false;
                                                        for (int j = 0; j < course[i].classes.Count; j++)
                                                        {
                                                            if (!course[i].classes[j].name.Equals(classroom.name))
                                                            {
                                                                flag = true;
                                                                course[i].classes[j].name = classroom.name;
                                                                //break;
                                                            }
                                                            if (!course[i].classes[j].teacher.id.Equals(classroom.teacher.id))
                                                            {
                                                                flag = true;
                                                                course[i].classes[j].teacher.id = classroom.teacher.id;
                                                                course[i].classes[j].teacher.name = classroom.teacher.name;
                                                                //break;
                                                            }
                                                        }
                                                        if (flag)
                                                        {
                                                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(course[i], course[i].id, new PartitionKey($"{course[i].code}"));
                                                        }
                                                    }*/
                        //string code = classroom.code.Substring(classroom.pk.Length + 1);
                        //[Jeff] CourseManagement表廢除 刪除預定：以下CourseManagement更新程序
                        /*                            var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"CourseManagement-{school_code}"));
                                                    if (sresponse.Status == 200)
                                                    {
                                                        using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
                                                        CourseManagement classroom1 = json.ToObject<CourseManagement>();
                                                        if (!classroom1.name.Equals(classroom.name))
                                                        {
                                                            classroom1.name = classroom.name;
                                                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
                                                        }
                                                        if (!string.IsNullOrEmpty(classroom1.teacher.id) && !string.IsNullOrEmpty(classroom.teacher.id) && !classroom1.teacher.id.Equals(classroom.teacher.id))
                                                        {
                                                            classroom1.teacher.name = classroom.teacher.name;
                                                            classroom1.teacher.id = classroom.teacher.id;
                                                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom1.code}"));
                                                        }
                                                    }*/
                        ////[Jeff] CourseManagement表廢除 刪除預定：以下CourseManagement更新程序                           
                        //}

                    //}

                }
                return Ok(new { classroom });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/Upsert()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }


        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("upsert-group")]
        public async ValueTask<IActionResult> UpsertGroup(JsonElement requert)
        {
            try
            {
                List<Student> students = new List<Student>();
                if (!requert.TryGetProperty("students", out JsonElement stus)) return BadRequest();
                students = stus.ToObject<List<Student>>();
                var client = _azureCosmos.GetCosmosClient();
                foreach (Student stu in students)
                {
                    var response = await client.GetContainer("TEAMModelOS", "Student").ReadItemStreamAsync(stu.id, new PartitionKey($"{stu.code}"));
                    if (response.Status == 200)
                    {
                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
                        Student stuInfo = json.ToObject<Student>();
                        stuInfo.groupId = stu.groupId;
                        stuInfo.groupName = stu.groupName;
                        await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(stuInfo, stuInfo.id, new PartitionKey($"{stuInfo.code}"));
                    }
                }
                /*Class classroom = new Class();
                if (!requert.TryGetProperty("classroom", out JsonElement room)) return BadRequest();
                //if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                classroom = room.ToObject<Class>();
               
                var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(classroom.id, new PartitionKey($"{classroom.code}"));
                if (sresponse.Status == 200)
                {
                    using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
                    Class classroom1 = json.ToObject<Class>();
                    //classroom1.students = classroom.students;
                    var response = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(classroom1, classroom1.id, new PartitionKey($"{classroom.code}"));
                }*/
                return Ok(new { students });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/UpsertGroup()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }

        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("find")]
        public async Task<IActionResult> Find(JsonElement requert)
        {
            //ResponseBuilder builder = ResponseBuilder.custom();
            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                List<object> classrooms = new List<object>();
                StringBuilder sql = new StringBuilder();
                sql.Append("select c.id,c.no,c.point,c.name,c.teacher,c.periodId,c.gradeId,c.sn,c.style,c.scope,c.type,c.code,c.openType,c.x,c.y,ARRAY_LENGTH(c.students) AS studCount from c ");
                Dictionary<string, object> dict = new Dictionary<string, object>();
                var emobj = requert.EnumerateObject();
                while (emobj.MoveNext())
                {
                    dict[emobj.Current.Name] = emobj.Current.Value;
                }
                //处理code
                if (dict.TryGetValue("school_code", out object _))
                {
                    dict.Remove("school_code");
                }
                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{school_code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            classrooms.Add(obj.ToObject<object>());
                        }
                    }
                }
                return Ok(new { classrooms });
                /*List<Classroom> sc = await _azureCosmos.FindByDict<Classroom>(request);
                return builder.Data(sc).build();*/
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/Find()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("find-students")]
        public async Task<IActionResult> FindStudent(JsonElement requert)
        {
            //ResponseBuilder builder = ResponseBuilder.custom();
            //if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
            if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
            if (!requert.TryGetProperty("ids", out JsonElement ids)) return BadRequest();
            if (!requert.TryGetProperty("school_code", out JsonElement schoolId)) return BadRequest();
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                List<object> stus = new List<object>();
                List<string> stuIds = new List<string>();
                string info = "";
                for (int i = 0; i < ids.GetArrayLength(); i++)
                {
                    //ids.Add(id[i].ToJsonString());
                    info += ids[i].ToJsonString() + ",";
                }
                //List<object> scList = new List<object>();
                List<object> suList = new List<object>();
                List<(string id, string name, string pic, string code, string classId ,string groupId, string groupName, string no)> listStudent = new List<(string id, string name, string pic, string code, string classId, string groupId, string groupName, string no)>();
                //var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(ids[i].GetString(), new PartitionKey($"Class-{schoolId}"));
                string className = "";
                /*                if (response.Status == 200)
                                {
                                    using var document = await JsonDocument.ParseAsync(response.ContentStream);
                                    Class @class = document.ToObject<Class>();
                                    className = @class.name;
                                }*/
                List<(string id, string name)> listClassList = new List<(string id,string name)>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(
                                    queryText: $"select c.id,c.name from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{schoolId}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                        while (accounts.MoveNext())
                        {
                            JsonElement account = accounts.Current;
                            listClassList.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
                            //stuIds.Add(account.GetProperty("id").GetString());                           
                        }
                    }
                }
                await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(
                    queryText: $"select c.id,c.name,c.classId,c.code,c.groupId,c.groupName,c.no,c.picture from c where c.classId in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                        while (accounts.MoveNext())
                        {
                            JsonElement account = accounts.Current;
                            stuIds.Add(account.GetProperty("id").GetString());

                            listStudent.Add((account.GetProperty("id").GetString(),
                                account.GetProperty("name").GetString(),
                                account.GetProperty("picture").GetString(),
                                account.GetProperty("code").GetString(),
                                account.GetProperty("classId").GetString(),
                                account.GetProperty("groupId").GetString(),
                                account.GetProperty("groupName").GetString(),
                                account.GetProperty("no").GetString()));
                        }
                    }
                }
                var grpBalance = listStudent.GroupBy(m => new { m.classId }).Distinct().Select(t =>t.ToList().Select(o =>
                                    new
                                    {
                                        o.id,
                                        o.name,
                                        o.pic,
                                        o.code,
                                        o.classId,
                                        className = listClassList.FirstOrDefault(c => c.id == o.classId).name,
                                        o.groupId,
                                        o.groupName,
                                        o.no
                                    })
                );
                stus.AddRange(grpBalance);
                //处理校本的自定义名单
                List<(string id, string name, string pic, string code, string classId, string groupId, string groupName, string no)> listStuList = new List<(string id, string name, string pic, string code, string classId, string groupId, string groupName, string no)>();
                List<(string id, string code, string stuId, string name)> stuListMore = new List<(string id, string code, string stuId, string name)>();
                if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                {
                    List<StuList> stuLists = new List<StuList>();
                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList-{schoolId}") }))
                    {
                        stuLists.Add(item);
                    }
                    List<string> stuInfo = new List<string>();
                    if (stuLists.Count > 0)
                    {
                        foreach (StuList stuList in stuLists)
                        {
                            foreach (Students stu in stuList.students)
                            {
                                stuInfo.Add(stu.id);
                                stuListMore.Add((stu.id,
                                                stu.code,
                                                stuList.id,
                                                stuList.name));
                            }

                        }
                        //根据学生ID  CODE获取学生基本信息
                        await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(
                       queryText: $"select c.id,c.name,c.classId,c.code,c.groupId,c.groupName,c.no,c.picture from c where c.id in ({string.Join(",", stuInfo.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
                        {
                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                            {
                                var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                while (accounts.MoveNext())
                                {
                                    JsonElement account = accounts.Current;
                                    listStuList.Add((account.GetProperty("id").GetString(),
                                        account.GetProperty("name").GetString(),
                                        account.GetProperty("picture").GetString(),
                                        account.GetProperty("code").GetString(),
                                        account.GetProperty("classId").GetString(),
                                        account.GetProperty("groupId").GetString(),
                                        account.GetProperty("groupName").GetString(),
                                        account.GetProperty("no").GetString()));
                                }
                            }
                        }
                        var infos = stuListMore.GroupBy(m => new { m.stuId }).Distinct().Select(t =>
                             t.ToList().Select(o =>
                                    new
                                    {
                                        o.id,
                                        o.code,
                                        name = listStuList.FirstOrDefault(c => c.id == o.id).name,
                                        pic = listStuList.FirstOrDefault(c => c.id == o.id).pic,
                                        classId = o.stuId,
                                        className = o.name,
                                        groupId = listStuList.FirstOrDefault(c => c.id == o.id).groupId,
                                        groupName = listStuList.FirstOrDefault(c => c.id == o.id).groupName,
                                        no = listStuList.FirstOrDefault(c => c.id == o.id).no
                                    })
                        );
                        stus.AddRange(infos);
                    }                                                        
                }
                else
                {
                    //处理发布对象为自选名单（个人）
                    List<StuList> stuLists1 = new List<StuList>();
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: $"select value(c) from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StuList") }))
                    {
                        stuLists1.Add(item);
                    }
                    if (stuLists1.Count > 0)
                    {
                        foreach (StuList stuList in stuLists1)
                        {
                            foreach (Students students in stuList.students)
                            {
                                //根据学生ID  CODE获取学生基本信息
                                await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(
                               queryText: $"select c.id,c.name,c.classId,c.code,c.groupId,c.groupName,c.no,c.picture from c where c.id = '{students.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{students.code}") }))
                                {
                                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
                                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                                    {
                                        var accounts = json.RootElement.GetProperty("Documents").EnumerateArray();
                                        while (accounts.MoveNext())
                                        {
                                            JsonElement account = accounts.Current;
                                            listStuList.Add((account.GetProperty("id").GetString(),
                                                account.GetProperty("name").GetString(),
                                                account.GetProperty("picture").GetString(),
                                                account.GetProperty("code").GetString(),
                                                account.GetProperty("classId").GetString(),
                                                account.GetProperty("groupId").GetString(),
                                                account.GetProperty("groupName").GetString(),
                                                account.GetProperty("no").GetString()));
                                        }
                                    }
                                }
                                stuListMore.Add((students.id,
                                                students.code,
                                                stuList.id,
                                                stuList.name));
                            }
                            if (stuList.tmids.Count > 0)
                            {
                                foreach (string tid in stuList.tmids)
                                {
                                    stuListMore.Add((tid,
                                                default,
                                                stuList.id,
                                                stuList.name));
                                }
                            }
                        }
                        var infos = stuListMore.GroupBy(m => new { m.stuId }).Distinct().Select(t => 
                            t.ToList().Select(o =>
                                    new
                                    {
                                        o.id,
                                        o.code,
                                        name = listStuList.FirstOrDefault(c => c.id == o.id).name,
                                        pic = listStuList.FirstOrDefault(c => c.id == o.id).pic,
                                        classId = o.stuId,
                                        className = o.name,
                                        groupId = listStuList.FirstOrDefault(c => c.id == o.id).groupId,
                                        groupName = listStuList.FirstOrDefault(c => c.id == o.id).groupName,
                                        no = listStuList.FirstOrDefault(c => c.id == o.id).no
                                    })
                        );
                        stus.AddRange(infos);
                    }
                }             
                return Ok(new { stus });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/FindStudent()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }


        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("delete")]
        public async Task<IActionResult> Delete(JsonElement request)
        {
            if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
            if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
            if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
            try
            {
                //string school_code = code.ToString().Substring(6);
                string school_code = code.ToString();
                Class classroom = new Class();
                var client = _azureCosmos.GetCosmosClient();
                if (scope.ToString().Equals("school"))
                {
                    var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Class-{code}"));
                    if (response.Status == 200)
                    {
                        classroom = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Class>(id.ToString(), new PartitionKey($"Class-{code}"));
                    }
                    else
                    {
                        List<TeacherCourse> classes = new List<TeacherCourse>();
                        classroom = await client.GetContainer("TEAMModelOS", "School").DeleteItemAsync<Class>(id.ToString(), new PartitionKey($"Class-{school_code}"));
                        await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"CourseManagement-{school_code}"));
                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryText: $"select value(c) from c join A0 in c.classes where A0.id = '{id}'"))
                        {
                            using var json = await JsonDocument.ParseAsync(item.ContentStream);
                            if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                            {
                                foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                                {
                                    classes.Add(obj.ToObject<TeacherCourse>());
                                }
                            }
                        }
                        for (int i = 0; i < classes.Count; i++)
                        {
                            bool flag = false;
                            for (int j = 0; j < classes[i].classes.Count; j++)
                            {
                                if (classes[i].classes[j].id.Equals(id.ToString()))
                                {
                                    classes[i].classes.Remove(classes[i].classes[j]);
                                    flag = true;
                                }
                            }
                            if (flag)
                            {
                                await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(classes[i], classes[i].id, new PartitionKey($"{classes[i].code}"));
                            }
                        }
                    }
                }
                else
                {
                    classroom = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Class>(id.ToString(), new PartitionKey($"Class-{school_code}"));
                }
                return Ok(new { classroom });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/Delete()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
            //ResponseBuilder builder = ResponseBuilder.custom();
            /*List<IdPk> idPks = new List<IdPk>();
            if (request.TryGetProperty("id", out JsonElement id))
            {
                List<Classroom> sc = await _azureCosmos.FindByDict<Classroom>(request);
                if (sc.IsNotEmpty())
                {
                    await _azureCosmos.DeleteAll<ClassStudent>(new Dictionary<string, object> { { "id", sc.Select(x => x.code).ToArray() } });
                    idPks = await _azureCosmos.DeleteAll<Classroom>(sc);
                    //builder.Data(idPks);
                }
            }
            else
            {
                return Ok(new { erro = ResponseCode.PARAMS_ERROR, V = "参数未定义！" });
            }
            return Ok(new { idPks });*/
            /*List<VoteRecord> sc = await _azureCosmos.FindByDict<VoteRecord>(request);
            await _azureCosmos.DeleteAll<VoteRecord>(sc);
            return Ok();*/
            //await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync("", new PartitionKey($"Class-{code}"));
        }

        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("hiteach-link")]
        public async Task<IActionResult> HiteachLink(JsonElement request)
        {
            // 必要檢查            
            if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
            // if (!request.TryGetProperty("linkList", out JsonElement links)) return BadRequest();

            if (!request.TryGetProperty("uuid", out JsonElement a)) return BadRequest();
            if (!request.TryGetProperty("uuid2", out JsonElement b)) return BadRequest();
            if (!request.TryGetProperty("pid", out JsonElement d)) return BadRequest();
            if (!request.TryGetProperty("action", out JsonElement e)) return BadRequest();
            if (!request.TryGetProperty("classId", out JsonElement c)) return BadRequest();

            // 如果是link classId 必填
            string action = e.ToString();
            if (action != "link" && action != "unLink") return BadRequest();
            try
            {
                // [變數宣告]
                string school_code = code.GetString(); // 學校簡碼
                string uuid = a.GetString(); // uuid
                string uuid2 = b.GetString(); // uuid2                    
                string pid = d.GetString(); // id
                string classId = c.GetString(); // classId


                // [取得DB資料]
                var client = _azureCosmos.GetCosmosClient();
                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));
                var error = 0;

                if (response.Status == 200)
                {
                    var json = await JsonDocument.ParseAsync(response.ContentStream);

                    //軟體
                    SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();

                    SerialInfoBaseWithdeviceBound updSerialInfo = schoolProductItem.serial.Where(s => s.id == pid).FirstOrDefault();
                    if (updSerialInfo != null)
                    {
                        deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.uuid == uuid && d.uuid2 == uuid2).FirstOrDefault();
                        if (updDeviceBound != null)
                        {
                            if (action == "link")
                            {
                                if (updDeviceBound.classId != null)
                                {
                                    error = 1;
                                }
                                else
                                {
                                    updDeviceBound.classId = classId;
                                }
                            }
                            else if (action == "unLink")
                            {
                                updDeviceBound.classId = null;
                            }
                            if (error == 0) await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, school_code, new PartitionKey("Product"));
                        }

                    }
                }

                return Ok(new { error });
            }
            catch (Exception ex)
            {
                return BadRequest();
            }
        }

        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("hiteach-unlink-classId")]
        public async Task<IActionResult> HiteachUnlinkByClassId(JsonElement request)
        {
            // 必要檢查
            if (!request.TryGetProperty("school_code", out JsonElement code)) return BadRequest();
            if (!request.TryGetProperty("classId", out JsonElement id)) return BadRequest();

            try
            {
                // [變數宣告]
                string school_code = code.ToString(); // 學校簡碼
                string classId = id.ToString(); // 教室ID


                // [取得DB資料]
                var client = _azureCosmos.GetCosmosClient();
                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code, new PartitionKey("Product"));

                if (response.Status == 200)
                {
                    var json = await JsonDocument.ParseAsync(response.ContentStream);

                    //軟體
                    SchoolProduct schoolProductItem = json.ToObject<SchoolProduct>();

                    foreach (SerialInfoBaseWithdeviceBound updSerialInfo in schoolProductItem.serial)
                    {
                        if (updSerialInfo.deviceBound != null)
                        {
                            deviceBound updDeviceBound = updSerialInfo.deviceBound.Where(d => d.classId == classId).FirstOrDefault();
                            if (updDeviceBound != null)
                            {
                                updDeviceBound.classId = null;
                            }
                        }

                    }

                    await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolProduct>(schoolProductItem, school_code, new PartitionKey("Product"));
                }

                return Ok(new { error = 0 });
            }
            catch (Exception ex)
            {
                return BadRequest();
            }
        }
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("name")]
        public async Task<IActionResult> GetNameList(JsonElement request)
        {
            if (!request.TryGetProperty("ids", out JsonElement ids)) return BadRequest();
            if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //List<string> id = ids.ToObject<List<string>>();
                string info = "";
                for (int i = 0; i < ids.GetArrayLength(); i++)
                {
                    //ids.Add(id[i].ToJsonString());
                    info += ids[i].ToJsonString() + ",";
                }
                List<object> ClassName = new List<object>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(
                    queryText: $"select c.id,c.name from c where c.id in ({info[0..^1]})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Class-{code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);
                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            ClassName.Add(obj.ToObject<object>());
                        }
                    }
                }
                return Ok(new { ClassName });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，class/name()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
    }
}

