using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using TEAMModelOS.SDK.DI;
using Azure.Cosmos;
using System.Text.Json;
using System.Collections.Generic;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using TEAMModelOS.TEAMModelFunction;
using System.Linq;

namespace TEAMModelFunction
{
    public   class ActivityHttpTrigger
    {


        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        private readonly AzureStorageFactory _azureStorage;
        private readonly AzureRedisFactory _azureRedis;
        public ActivityHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage
             , AzureRedisFactory azureRedis)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
            _azureStorage = azureStorage;
            _azureRedis = azureRedis;
        }

        /// <summary>
        /// 修复已存在的课程且未初始化学生课程列表的业务。
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-stu-course")]
        public async Task<IActionResult> StuCourse([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
        {
            log.LogInformation("fix-stu-course...");
            string originCode = await new StreamReader(req.Body).ReadToEndAsync();
            List<Course> courses = new List<Course>();
            var client = _azureCosmos.GetCosmosClient();
            var query = $"select  *  from c ";
            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Course>(queryText: query,
                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
            {
                courses.Add(item);
            }
            await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Course>(queryText: query,
                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Course-{originCode}") }))
            {
                courses.Add(item);
            }
            //2.获取课程的id 并尝试添加或移除对应的学生课程记录StuCourse。
            foreach (var course in courses)
            {
                if (course.schedule.IsNotEmpty())
                {
                    foreach (var sc in course.schedule)
                    {
                        if (!string.IsNullOrEmpty(sc.stulist))
                        {
                            (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string>() { sc.stulist }, course.school);
                            foreach (var addStu in studentss)
                            {
                                var stuCourse = new StuCourse
                                {
                                    id = course.id,
                                    scode = course.code,
                                    name = course.name,
                                    code = $"StuCourse-{course.school}-{addStu.id}",
                                    scope = course.scope,
                                    school = course.school,
                                    creatorId = course.creatorId,
                                    pk = "StuCourse"
                                };
                                await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stuCourse, new PartitionKey(stuCourse.code));
                            }
                            foreach (var addTmd in tmdids)
                            {
                                var tmdCourse = new StuCourse
                                {
                                    id = course.id,
                                    scode = course.code,
                                    name = course.name,
                                    code = $"StuCourse-{addTmd}",
                                    scope = course.scope,
                                    //school = courseChange.school,
                                    creatorId = course.creatorId,
                                    pk = "StuCourse"
                                };
                                await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(tmdCourse, new PartitionKey(tmdCourse.code));
                            }
                        }
                    }
                }
            }
            return new OkObjectResult(new { });
        }
        /// <summary>
        /// 设置评测未初始化学生列表的
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-exam-activity")]
        public   async Task<IActionResult> ExamActivity([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,ILogger log)
        {
            log.LogInformation("fix-exam-activity...");
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            List<string> datas = JsonSerializer.Deserialize<List<string>>(requestBody);
            var client = _azureCosmos.GetCosmosClient();
           
            var query = $"select  *  from c ";
            foreach (string data in datas) {
                List<ExamInfo> exams = new List<ExamInfo>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
                    queryText: query,  requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{data}") }))
                {
                    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())
                        {
                            exams.Add(obj.ToObject<ExamInfo>());
                        }
                    }
                }
                log.LogInformation($"{exams.ToJsonString()}");
                foreach (var info in exams)
                {
                    if (!info.classes.IsNotEmpty())
                    {
                        continue;
                    }
                    List<string> sub = new List<string>();
                    foreach (ExamSubject subject in info.subjects)
                    {
                        sub.Add(subject.id);
                    }
                    (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school);
                    List<StuActivity> stuActivities = new List<StuActivity>();
                    List<StuActivity> tmdActivities = new List<StuActivity>();
                    if (tmdids.IsNotEmpty())
                    {
                        tmdids.ForEach(x => {
                            tmdActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{x}",
                                type = "exam",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = sub,
                                blob = null,
                                owner = info.owner

                            });
                        });
                    }
                    if (studentss.IsNotEmpty())
                    {
                        studentss.ForEach(x => {
                            stuActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{info.school}-{x.id}",
                                type = "exam",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = sub,
                                blob=null,
                                owner = info.owner
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities);
                }
            }
            return new OkObjectResult(new { });
        }
        /// <summary>
        /// 设置投票未初始化学生列表的业务
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-vote-activity")]
        public async Task<IActionResult> VoteActivity(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {

            log.LogInformation("fix-vote-activity...");
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            List<string> datas = JsonSerializer.Deserialize<List<string>>(requestBody);
            var client = _azureCosmos.GetCosmosClient();

            var query = $"select  *  from c ";
            foreach (string data in datas)
            {
                List<Vote> votes = new List<Vote>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
                    queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{data}") }))
                {
                    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())
                        {
                            votes.Add(obj.ToObject<Vote>());
                        }
                    }
                }
                log.LogInformation($"{votes.ToJsonString()}");
                foreach (var info in votes)
                {
                    if (!info.classes.IsNotEmpty())
                    {
                        continue;
                    }
                   
                    (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school);
                    List<StuActivity> stuActivities = new List<StuActivity>();
                    List<StuActivity> tmdActivities = new List<StuActivity>();
                    if (tmdids.IsNotEmpty())
                    {
                        tmdids.ForEach(x => {
                            tmdActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{x}",
                                type = "vote",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = new List<string>() { "" },
                                blob = null,
                                owner = info.owner

                            });
                        });
                    }
                    if (studentss.IsNotEmpty())
                    {
                        studentss.ForEach(x => {
                            stuActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{info.school}-{x.id}",
                                type = "vote",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = new List<string>() { "" },
                                blob = null,
                                owner = info.owner
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities);
                }
            }
            return new OkObjectResult(new { });
        }

        /// <summary>
        /// 设置问卷调查未初始化学生列表的业务
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-survey-activity")]
        public async Task<IActionResult> SurveyActivity(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("fix-survey-activity...");
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            List<string> datas = JsonSerializer.Deserialize<List<string>>(requestBody);
            var client = _azureCosmos.GetCosmosClient();

            var query = $"select  *  from c ";
            foreach (string data in datas)
            {
                List<Survey> surveys = new List<Survey>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
                    queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{data}") }))
                {
                    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())
                        {
                            surveys.Add(obj.ToObject<Survey>());
                        }
                    }
                }
                log.LogInformation($"{surveys.ToJsonString()}");
                foreach (var info in surveys)
                {
                    if (!info.classes.IsNotEmpty())
                    {
                        continue;
                    }
                    (List<string> tmdids, List<Students> studentss) = await TriggerStuActivity.GetStuList(client, _dingDing, info.classes, info.school);
                    List<StuActivity> stuActivities = new List<StuActivity>();
                    List<StuActivity> tmdActivities = new List<StuActivity>();
                    if (tmdids.IsNotEmpty())
                    {
                        tmdids.ForEach(x => {
                            tmdActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{x}",
                                type = "survey",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = new List<string>() { "" },
                                blob = info.blob,
                                owner=info.owner
                                
                            });
                        });
                    }
                    if (studentss.IsNotEmpty())
                    {
                        studentss.ForEach(x => {
                            stuActivities.Add(new StuActivity
                            {
                                pk = "Activity",
                                id = info.id,
                                code = $"Activity-{info.school}-{x.id}",
                                type = "survey",
                                name = info.name,
                                startTime = info.startTime,
                                endTime = info.endTime,
                                scode = info.code,
                                scope = info.scope,
                                school = info.school,
                                creatorId = info.creatorId,
                                subjects = new List<string>() { "" },
                                blob=info.blob,
                                owner = info.owner
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities);
                }
            }
            return new OkObjectResult(new { });
        }
        /// <summary>
        //获取题目摘要信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [FunctionName("fix-itemcond")]
        public async Task<IActionResult> FixItemCond(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var client = _azureCosmos.GetCosmosClient();
            List<ItemInfo> items = new List<ItemInfo>();
            var queryslt = $"SELECT  value(c) FROM c ";
            
            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<ItemInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-hbcn") }))
            {
                
                items.Add(item);
            }
            List<ItemCond> itemConds = new List<ItemCond>();
            items.GroupBy(x => x.periodId).ToList().ForEach( x=> {
                ItemCond cond = new ItemCond() { id=x.Key,code=$"ItemCond-hbcn" };
                x.ToList().ForEach(y => {
                   ItemService.CountItemCond(y, null, cond);
                });
               
                itemConds.Add(cond);
            });
            itemConds.ForEach(async cond =>
            {
                await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ItemCond>(cond, new PartitionKey(cond.code));
            });
            return new OkObjectResult(new { itemConds });
        }
        /// <summary>
        /// 设置问卷调查未初始化学生列表的业务
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("refresh-stu-activity")]
        public async Task<IActionResult> RefreshStuActivity(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic json = JsonSerializer.Deserialize<dynamic>(requestBody);
            string id = json.id;
            string code = json.code;
            if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(code)) {
                return new BadRequestResult();
            }
            var client = _azureCosmos.GetCosmosClient();
           // var query = $"SELECT distinct c.owner, c.id,c.code, c.classes,c.subjects,c.progress,c.scope,c.startTime,c.school,c.creatorId,c.name,c.pk ,c.endTime   FROM c  join A1 in c.classes  where  c.pk='{type}' and A1 in('{stuListChange.listid}') "; 
            MQActivity activity = null;
            try {
                var aactivity= await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id, new Azure.Cosmos.PartitionKey(code));
                using var da = await JsonDocument.ParseAsync(aactivity.ContentStream);
                activity = da.ToObject<MQActivity>();
            } catch (Exception ex) { 
            }
            if (activity != null)
            {
                (List<string> tmdids, List<Students> students) = await TriggerStuActivity.GetStuList(client, _dingDing, activity.classes, activity.school);
                if (tmdids.IsNotEmpty())
                {
                    foreach (string tmdid in tmdids)
                    {
                        var stucourse = new StuActivity
                        {
                            id = activity.id,
                            scode = activity.code,
                            name = activity.name,
                            code = $"Activity-{tmdid}",
                            scope = activity.scope,
                            school = activity.school,
                            creatorId = activity.creatorId,
                            pk = "Activity",
                            type = activity.pk,
                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
                            startTime = activity.startTime,
                            endTime = activity.endTime,
                            blob = activity.blob,
                            owner = activity.owner
                        };
                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
                    }
                }
                if (students.IsNotEmpty())
                {
                    foreach (Students student in students)
                    {
                        var stucourse = new StuActivity
                        {
                            id = activity.id,
                            scode = activity.code,
                            name = activity.name,
                            code = $"Activity-{activity.school}-{student.id}",
                            scope = activity.scope,
                            school = activity.school,
                            creatorId = activity.creatorId,
                            pk = "Activity",
                            type = activity.pk,
                            subjects = activity.pk.ToLower().Equals("exam") && activity.subjects.IsNotEmpty() ? new List<string>() { activity.subjects[0].id } : new List<string>() { "" },
                            startTime = activity.startTime,
                            endTime = activity.endTime,
                            blob = activity.blob,
                            owner = activity.owner
                        };
                        await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
                    }
                }
                return new OkObjectResult(new { code = 200 });
            }
            else {
                return new BadRequestResult();
            }
        }
        /// <summary>
        ///获取单个目录的大小，用于获取评测，试题，试卷，问卷，投票等 文件层级超过两层的文件。
        ///例如 /exam/uuid/xxx  /item/uuid/xxx   /paper/uuid/xxx  /vote/uuid/xxx  /suervy/uuid/xxx
        /// {"name":"hbcn","/item/uuid/xxx"}
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("get-prefixsize")]
        public async Task<IActionResult> GetPrefixsize(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            try {
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                var data = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(requestBody);
                if (data.TryGetProperty("name", out JsonElement name) && data.TryGetProperty("root", out JsonElement root))
                {
                    var size = await _azureStorage.GetBlobContainerClient($"{name}").GetBlobsSize($"{root}");
                    return new OkObjectResult(new { size = size });
                }
                else
                {
                    return new BadRequestResult();
                }
            } catch (Exception ex) {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，get-prefixsize()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return new BadRequestResult();
            }

        }
        /// <summary>
        ///获取多个blob路径的文件大小
        /// {"name"："hbcn","blobs"：["/paper/uuid/xxx.json","/paper/uuid/aaa.json"]}
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("get-blobsize")]
        public async Task<IActionResult> GetBlobsize(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            try { 
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                var data = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(requestBody);
                if (data.TryGetProperty("name", out JsonElement name) && data.TryGetProperty("blobs", out JsonElement blob))
                {
                    List<string> blobs = JsonSerializer.Deserialize<List<string>>(blob.ToJsonString());
                   var size= await _azureStorage.GetBlobContainerClient($"{name}").GetBlobsSize(blobs);
                    return new OkObjectResult(new { size = size });
                }
                else {
                    return new BadRequestResult();
                }
              
            } catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，get-blobsize()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return new BadRequestResult();
            }
        }
    }
  
}
