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;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using System.Linq;
using TEAMModelOS.Services.Common;
using TEAMModelOS.SDK.Models.Service;
using HTEXLib.COMM.Helpers;

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<TmdInfo> tmdids, List<StuInfo> students, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string>() { sc.stulist }, course.school);
                            foreach (var addStu in students)
                            {
                                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",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                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",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                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)
                {
                    List<string> classes = ExamService.getClasses(info.classes,info.stuLists);
                    if (!classes.IsNotEmpty())
                    {
                        continue;
                    }
                    List<string> sub = new List<string>();
                    foreach (ExamSubject subject in info.subjects)
                    {
                        sub.Add(subject.id);
                    }
                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, 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.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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes

                            });
                        });
                    }
                    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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities,null);
                }
            }
            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)
                {
                    List<string> classes = ExamService.getClasses(info.classes, info.stuLists);
                    if (classes.IsNotEmpty())
                    {
                        continue;
                    }

                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, 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.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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes

                            });
                        });
                    }
                    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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
                }
            }
            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)
                {
                    List<string> classes = ExamService.getClasses(info.classes, info.stuLists);
                    if (!classes.IsNotEmpty())
                    {
                        continue;
                    }
                    (List<TmdInfo> tmdids, List<StuInfo> studentss, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, 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.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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes

                            });
                        });
                    }
                    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,
                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                                taskStatus = -1,
                                classIds = classes
                            });
                        });
                    }
                    await TriggerStuActivity.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, null);
                }
            }
            return new OkObjectResult(new { });
        }
        
        /// <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();
            await TriggerStuActivity.RefreshStuActivity(client, _dingDing, id, code);
            return new OkObjectResult(new {code=200 });
        }
        /// <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("used-space")]
        public async Task<IActionResult> UsedSpace(
            [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();
            }
        }
        /// <summary>
        /// 修复容器的内容显示
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-blob-content")]
        public async Task<IActionResult> FixBlobContent(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
                var data = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(requestBody);
                await FixDataService.FixBlobContent(client, _dingDing, _azureStorage, data);
                return new OkObjectResult(new { });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-blob-content()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return new BadRequestResult();
            }
        }
        /// <summary>
        /// 修复容器的内容显示
        /// </summary>
        /// <param name="req"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        [FunctionName("fix-student-info")]
        public async Task<IActionResult> FixStudentInfo(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var client = _azureCosmos.GetCosmosClient();
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            var data = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(requestBody);
            await FixDataService.FixStudentInfo(client, _dingDing, _azureStorage, data);
            return new OkObjectResult(new { });
        }
    }
}
