using Azure.Cosmos;
using Microsoft.Azure.WebJobs;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using HTEXLib.COMM.Helpers;

namespace TEAMModelFunction
{
    public class CourseServiceBus
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        public CourseServiceBus(AzureCosmosFactory azureCosmos, DingDing dingDing)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
        }

        /// <summary>
        /// 完善课程变更
        /// </summary>
        /// <data msg>
        /// CourseChange
        ///// </data>
        /// <param name="msg"></param>
        /// <returns></returns>
        [FunctionName("Course")]
        public async Task Course([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "course", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
        {
            var client = _azureCosmos.GetCosmosClient();
            try
            {
                //await _dingDing.SendBotMsg($"ServiceBus,CourseChange:{msg}", GroupNames.醍摩豆服務運維群組);
                var jsonMsg = JsonDocument.Parse(msg);
                CourseChange courseChange = msg.ToObject<CourseChange>();
                if (courseChange == null)
                {
                    return;
                }
                foreach (var cls in courseChange.addClass)
                {
                    (List<TmdInfo> addTmdidsCls, List<StuInfo> addStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { cls }, courseChange.school);
                    foreach (var stu in addStudentsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                            if (!stuCourse.Value.classId.Contains(cls))
                            {
                                stuCourse.Value.classId.Add(cls);
                            }
                            await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Response.Status == 404)
                            {
                                var course = new StuCourse
                                {
                                    id = courseChange.id,
                                    scode = courseChange.code,
                                    name = courseChange.name,
                                    code = $"StuCourse-{courseChange.school}-{stu.id}",
                                    scope = courseChange.scope,
                                    school = courseChange.school,
                                    creatorId = courseChange.creatorId,
                                    classId = new List<string> { cls },
                                    pk = "StuCourse",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                await client.GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync(course, new PartitionKey(course.code));
                            }
                        }
                    }
                    foreach (var tmd in addTmdidsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            if (!stuCourse.Value.classId.Contains(cls))
                            {
                                stuCourse.Value.classId.Add(cls);
                            }
                            await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Response.Status == 404)
                            {
                                var course = new StuCourse
                                {
                                    id = courseChange.id,
                                    scode = courseChange.code,
                                    name = courseChange.name,
                                    code = $"StuCourse-{tmd.id}",
                                    scope = courseChange.scope,
                                    school = courseChange.school,
                                    creatorId = courseChange.creatorId,
                                    classId = new List<string> { cls },
                                    pk = "StuCourse",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                await client.GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync(course, new PartitionKey(course.code));
                            }
                        }
                    }
                }

                foreach (var list in courseChange.addList)
                {
                    (List<TmdInfo> addTmdidsCls, List<StuInfo> addStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { list }, courseChange.school);
                    foreach (var stu in addStudentsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{stu.schoolId}-{stu.id}"));
                            if (!stuCourse.Value.stulist.Contains(list))
                            {
                                stuCourse.Value.stulist.Add(list);
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{stu.schoolId}-{stu.id}"));
                            }
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Response.Status == 404)
                            {
                                var course = new StuCourse
                                {
                                    id = courseChange.id,
                                    scode = courseChange.code,
                                    name = courseChange.name,
                                    code = $"StuCourse-{courseChange.school}-{stu.id}",
                                    scope = courseChange.scope,
                                    school = courseChange.school,
                                    creatorId = courseChange.creatorId,
                                    stulist = new List<string> { list },
                                    pk = "StuCourse",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                await client.GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync(course, new PartitionKey(course.code));
                            }
                        }
                    }
                    foreach (var tmd in addTmdidsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            if (!stuCourse.Value.stulist.Contains(list))
                            {
                                stuCourse.Value.stulist.Add(list);
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            }

                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Response.Status == 404)
                            {
                                var course = new StuCourse
                                {
                                    id = courseChange.id,
                                    scode = courseChange.code,
                                    name = courseChange.name,
                                    code = $"StuCourse-{tmd.id}",
                                    scope = courseChange.scope,
                                    school = courseChange.school,
                                    creatorId = courseChange.creatorId,
                                    stulist = new List<string> { list },
                                    pk = "StuCourse",
                                    createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                };
                                await client.GetContainer(Constant.TEAMModelOS, "Student").CreateItemAsync(course, new PartitionKey(course.code));
                            }
                        }
                    }
                }

                foreach (var delCls in courseChange.delClass)
                {
                    (List<TmdInfo> delTmdidsCls, List<StuInfo> delStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { delCls }, courseChange.school);
                    foreach (var stu in delStudentsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));

                            if (stuCourse.Value.classId.Contains(delCls))
                            {
                                stuCourse.Value.classId.Remove(delCls);
                            }

                            if (!stuCourse.Value.classId.IsNotEmpty() && !stuCourse.Value.stulist.IsNotEmpty())
                            {
                                //当两个列表都不存在时则直接删除
                                await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                            }
                            else
                            {
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                            }

                        }
                        catch (CosmosException ex)
                        {

                        }
                    }
                    foreach (var tmd in delTmdidsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));

                            if (stuCourse.Value.classId.Contains(delCls))
                            {
                                stuCourse.Value.classId.Remove(delCls);
                            }

                            if (!stuCourse.Value.classId.IsNotEmpty() && !stuCourse.Value.stulist.IsNotEmpty())
                            {
                                //当两个列表都不存在时则直接删除
                                await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            }
                            else
                            {
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            }

                        }
                        catch (CosmosException ex)
                        {

                        }
                    }
                }
                foreach (var delList in courseChange.delList)
                {
                    (List<TmdInfo> delTmdidsCls, List<StuInfo> delStudentsCls, List<ClassListInfo> classLists) = await TriggerStuActivity.GetStuList(client, _dingDing, new List<string> { delList }, courseChange.school);
                    foreach (var stu in delStudentsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));

                            if (stuCourse.Value.stulist.Contains(delList))
                            {
                                stuCourse.Value.stulist.Remove(delList);
                            }

                            if (!stuCourse.Value.classId.IsNotEmpty() && !stuCourse.Value.stulist.IsNotEmpty())
                            {
                                //当两个列表都不存在时则直接删除
                                await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                            }
                            else
                            {
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{courseChange.school}-{stu.id}"));
                            }

                        }
                        catch (CosmosException ex)
                        {

                        }
                    }
                    foreach (var tmd in delTmdidsCls)
                    {
                        try
                        {
                            ItemResponse<StuCourse> stuCourse = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));

                            if (stuCourse.Value.stulist.Contains(delList))
                            {
                                stuCourse.Value.stulist.Remove(delList);
                            }

                            if (!stuCourse.Value.classId.IsNotEmpty() && !stuCourse.Value.stulist.IsNotEmpty())
                            {
                                //当两个列表都不存在时则直接删除
                                await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<StuCourse>(courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            }
                            else
                            {
                                await client.GetContainer(Constant.TEAMModelOS, "Student").ReplaceItemAsync<StuCourse>(stuCourse, courseChange.id, new PartitionKey($"StuCourse-{tmd.id}"));
                            }

                        }
                        catch (CosmosException ex)
                        {

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"CourseServiceBus-Course\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
            }
        }
    }
}
