using Azure.Cosmos;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Filter;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using TEAMModelOS.Services.Common;

namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("student")]
    [ApiController]
    public class StudentCommonController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly AzureRedisFactory _azureRedis;
        public StudentCommonController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis)
        {

            _azureCosmos = azureCosmos;
            _azureRedis = azureRedis;
        }

        /// <summary>
        /// 查询活动所有活动类型的列表，学生端
        /// </summary>
        /// <param name="request">
        ///加入的班级信息                      ?classes:[{"classid":"S-C-00001","scope":"school"},{"classid":"P-C-00004","scope":"private"}]
        ///活动类型                            ?"type":"Vote"/"Exam"/"Homework"/"Learn"/"Survey"" // Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
        ///时间筛选范围开始时间 默认30天之前   ?"stime":1608274766154  
        ///时间筛选范围结束时间 默认当前时间   ?"etime":1608274766666 
        ///是否展示列表的 Tips                 ? "tips":true/false
        ///每页大小     ?"count":10/null/Undefined  
        ///分页Token    ?"continuationToken":Undefined/null/"[{\"token\":\"+RID:~omxMAP3ipcSEEwAAAAAAAA==#RT:2#TRC:20#ISV:2#IEO:65551#QCF:1#FPC:AYQTAAAAAAAAiRMAAAAAAAA=\",\"range\":{\"min\":\"\",\"max\":\"FF\"}}]"
        /// 当前状态    ?"progress":Undefined/null/"" 表示两种状态都要查询/ "going"/"finish" 表示查询进行中/ 或者已完成 学生端只能查询正在进行或已经结束 going 已发布|finish 已结束  
        /// </param>
        /// 
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("stu-activity")]
        // [AuthToken(Roles = "student")]
        public async Task<IActionResult> StuActivity(JsonElement request)
        {
            var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
            (List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(request, id, school, _azureCosmos, _azureRedis);
            return Ok(new { datas, continuationToken });
        }
        /// <summary>
        /// 查询活动所有活动类型的列表，学生端
        /// </summary>
        /// <param name="request">
        /// userid
        /// school
        /// </param>
        /// 
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("stu-course")]
        // [AuthToken(Roles = "student")]
        public async Task<IActionResult> StuCourse(JsonElement request)
        {
            var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
            if (string.IsNullOrWhiteSpace(id))
            {
                if (request.TryGetProperty("userid", out JsonElement userid))
                {
                    if (!userid.ValueKind.Equals(JsonValueKind.Undefined) && !userid.ValueKind.Equals(JsonValueKind.Null) && userid.ValueKind.Equals(JsonValueKind.String))
                    {
                        id = userid.GetString();
                    }
                }
            }
            if (string.IsNullOrWhiteSpace(school))
            {
                if (request.TryGetProperty("school", out JsonElement schooljson))
                {
                    if (!schooljson.ValueKind.Equals(JsonValueKind.Undefined) && !schooljson.ValueKind.Equals(JsonValueKind.Null) && schooljson.ValueKind.Equals(JsonValueKind.String))
                    {
                        school = schooljson.GetString();
                    }
                }

            }
            /// tmdid, schoolid
            var userType = "tmdid";
            if (request.TryGetProperty("userType", out JsonElement usertype))
            {
                if (!usertype.ValueKind.Equals(JsonValueKind.Undefined) && !usertype.ValueKind.Equals(JsonValueKind.Null) && usertype.ValueKind.Equals(JsonValueKind.String))
                {
                    userType = usertype.GetString();
                }
            }
            string containerId = "";
            string PartitionKey = "";
            if (!string.IsNullOrWhiteSpace(school) && userType.Equals("schoolid"))
            {
                containerId = "Student";
                PartitionKey = $"StuCourse-{school}-{id}";
            }
            else
            {
                containerId = "Student";
                PartitionKey = $"StuCourse-{id}";
            }



            List<StuCourse> stus = new List<StuCourse>();
            List<CourseDto> sc = new List<CourseDto>();
            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, containerId).GetItemQueryIterator<StuCourse>(queryText: $"select value(c) from c ",
              requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey(PartitionKey) }))
            {
                stus.Add(item);
            }
            foreach (var cos in stus)
            {
                if (cos.scope.Equals("school"))
                {
                    Course course = new();
                    try
                    {
                        course = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Course>(cos.id, new Azure.Cosmos.PartitionKey(cos.scode));
                    }
                    catch (CosmosException ex) { course = null; }
                    sc.Add(new CourseDto { course = course, stuCourse = cos });
                }
                else
                {
                    Course course = new();
                    try
                    {
                        course = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Course>(cos.id, new Azure.Cosmos.PartitionKey(cos.scode));
                    }
                    catch (CosmosException ex) { course = null; }
                    sc.Add(new CourseDto { course = course, stuCourse = cos });
                }
            }
            //获取老师详细信息
            HashSet<string> info = new HashSet<string>();
            HashSet<string> room = new HashSet<string>();
            foreach (CourseDto dto in sc)
            {
                if (dto.course != null)
                {
                    if (dto.course.schedule.Count > 0)
                    {
                        foreach (Schedule schedule in dto.course.schedule)
                        {
                            if (!string.IsNullOrEmpty(schedule.teacherId))
                            {
                                info.Add(schedule.teacherId);
                            }
                            if (!string.IsNullOrEmpty(schedule.room))
                            {
                                room.Add(schedule.room);
                            }
                        }
                    }
                }
            }
            //处理教师基础信息
            List<(string id, string name)> teachers = new();
            if (info.Count > 0)
            {
                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIterator(
                                    queryText: $"select c.id,c.name from c where c.id in ({ string.Join(",", info.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
                {
                    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;
                            teachers.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
                        }
                    }
                }
            }
            //处理教室基础信息
            List<(string id, string name)> rooms = new();
            if (room.Count > 0)
            {
                await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(
                                    queryText: $"select c.id,c.name from c where c.id in ({ string.Join(",", room.Select(o => $"'{o}'"))})", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Room-{school}") }))
                {
                    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;
                            rooms.Add((account.GetProperty("id").GetString(), account.GetProperty("name").GetString()));
                        }
                    }
                }
            }
            var courses = sc.Select(s => new
            {
                course = s.course != null ? new
                {
                    id = s.course.id,
                    name = s.course.name,
                    code = s.course.code,
                    creatorId = s.course.creatorId,
                    no = s.course.no,
                    period = s.course.period,
                    desc = s.course.desc,
                    school = s.course.school,
                    scope = s.course.scope,
                    pk = s.course.pk,
                    subject = s.course.subject,
                    schedule = s.course.schedule.Select(c => new
                    {
                        room = c.room,
                        roomName = rooms.FirstOrDefault(t => t.id == c.room).name,
                        classId = c.classId,
                        teacherId = c.teacherId,
                        teacherName = teachers.FirstOrDefault(t => t.id == c.teacherId).name,
                        time = c.time,
                        stulist = c.stulist
                    })
                } : null,
                s.stuCourse
            });
            return Ok(new { courses });
        }
    }
    public class CourseDto
    {
        public StuCourse stuCourse { get; set; }
        public Course course { get; set; }
    }
}
