using Azure.Cosmos;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
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 TEAMModelOS.SDK.Models.Service;
using TEAMModelOS.Services.Common;
using HTEXLib.COMM.Helpers;

namespace TEAMModelOS.Controllers
{
    [Route("fix-data")]
    [ApiController]
    public class FixDataController : ControllerBase
    {
        private readonly AzureStorageFactory _azureStorage;
        private readonly AzureRedisFactory _azureRedis;
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        public FixDataController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, DingDing dingDing)
        {
            _azureCosmos = azureCosmos;
            _azureRedis = azureRedis;
            _azureStorage = azureStorage;
            _dingDing = dingDing;
        }
        /// <summary>
        /// 修复学生的id
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-student-id")]
        public async Task<IActionResult> FixStudentId(JsonElement data) {
            var client = _azureCosmos.GetCosmosClient();
            var queryslt = $"SELECT  value(c) FROM c ";
            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<Student>(queryText: queryslt)) { 
                //item.id
            }
                return Ok();
        }

        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-item")]
        public async Task<IActionResult> FixItem(JsonElement data) {

            var client = _azureCosmos.GetCosmosClient();
            List<School> schools = new List<School>();
            await foreach (var item in   client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText:"SELECT  value(c) FROM c", requestOptions: new QueryRequestOptions { PartitionKey= new PartitionKey("Base") })){
                schools.Add(item);
            }
            Random random = new Random();
            foreach (var school in schools) {
                List<ItemInfo> items = new List<ItemInfo>();
                var queryslt = $"SELECT  value(c) FROM c where  c.pid = null ";
                List<ItemInfo> noPeriodId = new List<ItemInfo>();
                List<ItemInfo> noSubjectId = new List<ItemInfo>();
                List<ItemInfo> noGradeIds = new List<ItemInfo>();
               
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ItemInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{school.id}") }))
                {
                    if (string.IsNullOrEmpty(item.periodId))
                    {
                        noPeriodId.Add(item);
                    }
                    if (string.IsNullOrEmpty(item.subjectId))
                    {
                        noSubjectId.Add(item);
                    }
                    if (!item.gradeIds.IsNotEmpty())
                    {
                        noGradeIds.Add(item);
                    }
                    bool errorData = false;
                    foreach (var x in item.gradeIds)
                    {
                        if (string.IsNullOrEmpty(x))
                        {
                            errorData = true;
                        }
                    }
                    if (errorData)
                    {
                        List<string> grds = new List<string>();
                        item.gradeIds.ForEach(x => {
                            if (string.IsNullOrEmpty(x))
                            {
                                grds.Add($"{random.Next(0, 5)}");
                            }
                            else
                            {
                                grds.Add(x);
                            }
                        });
                        item.gradeIds = grds;
                        await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<ItemInfo>(item, item.id, new PartitionKey(item.code));
                    }
                    items.Add(item);
                }
                List<ItemInfo> unMatch = new List<ItemInfo>();
                foreach (var item in items)
                {
                    bool match = false;
                    school.period.ForEach(x =>
                    {
                        if (item.periodId.Equals(x.id))
                        {
                            if (x.subjects.Select(y => y.id).Contains(item.subjectId))
                            {
                                match = true;
                            }
                        }
                    });
                    if (!match)
                    {
                        unMatch.Add(item);
                    }
                }
                if (noGradeIds.IsNotEmpty())
                {
                    var ids = noGradeIds.Select(x => x.id);
                    await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemsAsync<ItemInfo>(ids.ToList(), $"Item-{school.id}");
                    foreach (var rm in noGradeIds)
                    {
                        items.Remove(rm);
                    }
                }
                if (noPeriodId.IsNotEmpty())
                {
                    var ids = noPeriodId.Select(x => x.id);
                    await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemsAsync<ItemInfo>(ids.ToList(), $"Item-{school.id}");
                    foreach (var rm in noPeriodId)
                    {
                        items.Remove(rm);
                    }
                }
                if (noSubjectId.IsNotEmpty())
                {
                    var ids = noSubjectId.Select(x => x.id);
                    await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemsAsync<ItemInfo>(ids.ToList(), $"Item-{school.id}");
                    foreach (var rm in noSubjectId)
                    {
                        items.Remove(rm);
                    }
                }
                if (unMatch.IsNotEmpty())
                {
                    var ids = unMatch.Select(x => x.id);
                    await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemsAsync<ItemInfo>(ids.ToList(), $"Item-{school.id}");
                    foreach (var rm in unMatch)
                    {
                        items.Remove(rm);
                    }
                }
                List<ItemCond> itemConds = new List<ItemCond>();
                items.GroupBy(x => x.periodId).Select(y => new { key = y.Key, list = y.ToList() }).ToList().ForEach(z =>
                {
                    ItemCond cond = new ItemCond() { id = z.key, code = $"ItemCond-{school.id}", pk = "ItemCond", ttl = -1, count = z.list.Count, grades = new List<GradeCount>(), subjects = new List<SubjectCount>() };
                    z.list.ForEach(y =>
                    {
                        ItemService.CountItemCond(y, null, cond);
                    });
                    itemConds.Add(cond);
                });
                itemConds.ForEach(async cond =>
                {
                    await client.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ItemCond>(cond, new PartitionKey(cond.code));
                });
            }
            return Ok(new {  });
        }


        /// <summary>
        /// 修复名单的scope,school,creatorid
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-stulist-scope&school&creatorid")]
        public async Task<IActionResult> FixStulist(JsonElement data)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //先处理未关联课程的教师私人名单 
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<StuList>(queryText: "select value(c) from c ", requestOptions: new  QueryRequestOptions{PartitionKey= new PartitionKey("StuList") })) {
                    string scdsql = $"SELECT value(A1) FROM c  join A1 in c.schedule  where    A1.stulist='{item.id}'";
                    int count = 0;
                    await foreach (var schedule in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Schedule>(queryText: scdsql ))
                    {
                        count += 1;
                    }
                    if (count == 0) {
                      await  client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemStreamAsync(item.id, new PartitionKey("StuList"));
                    }
                }
                HashSet<string> plistId = new HashSet<string>();
                List<KeyValuePair<string, string>> pkeyValuePairs = new List<KeyValuePair<string, string>>();
                List<StuList> pstuLists = new List<StuList>();
                //List<Course> pcourses = new List<Course>();
                //处理私人名单
                string sql = "select value(c) from c where c.pk='Course' ";
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Course>(queryText: sql))
                {
                    if (item.schedule.IsNotEmpty()) {
                        foreach (var scd in item.schedule) {
                            if (!string.IsNullOrEmpty(scd.stulist)) {
                                plistId.Add(scd.stulist);
                                var  tmdid= item.code.Replace("Course-", "");
                                pkeyValuePairs.Add(new KeyValuePair<string, string>(scd.stulist, tmdid));
                                item.creatorId = tmdid;
                                item.scope = "private";
                                await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(item, item.id, new PartitionKey(item.code));
                            }
                        }
                    }
                }
                List<string> pfaildId = new List<string>();
                foreach (var list in plistId) {
                    try {
                        StuList stuList= await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<StuList>(list, new PartitionKey("StuList"));
                        var a =  pkeyValuePairs.Where(x => x.Key == list).FirstOrDefault();
                        if (stuList.students.IsNotEmpty()) {
                            stuList.school = stuList.students[0].code.Replace("Base-", "");
                        }
                        stuList.creatorId = a.Value;
                        stuList.scope = "private";
                        await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<StuList>(stuList, list, new PartitionKey("StuList"));
                    } catch (CosmosException ex) {
                        pfaildId.Add(list);
                    }
                }
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-stulist-scope&school&creatorid()\n修复失败私人的名单pfaildId:\n  {pfaildId.ToJsonString()}", GroupNames.醍摩豆服務運維群組);

                //处理学校的名单
                HashSet<string> slistId = new HashSet<string>();
                List<KeyValuePair<string, string>> skeyValuePairs = new List<KeyValuePair<string, string>>();
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Course>(queryText: sql))
                {
                    if (item.schedule.IsNotEmpty())
                    {
                        foreach (var scd in item.schedule)
                        {
                            if (!string.IsNullOrEmpty(scd.stulist))
                            {
                                slistId.Add(scd.stulist);
                                var school = item.code.Replace("Course-", "");
                                skeyValuePairs.Add(new KeyValuePair<string, string>(scd.stulist, school));
                                item.scope = "school";
                                item.school = school;
                                await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(item, item.id, new PartitionKey(item.code));
                            }
                        }
                    }
                }

                List<string> sfaildId = new List<string>();
                foreach (var list in skeyValuePairs)
                {
                    try
                    {
                        StuList stuList = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<StuList>(list.Key, new PartitionKey($"StuList-{list.Value}"));
                        stuList.scope = "school";
                        stuList.school = list.Value;
                        await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<StuList>(stuList, list.Key, new PartitionKey(stuList.code));
                    }
                    catch (CosmosException ex)
                    {
                        sfaildId.Add(list.Key);
                    }
                }
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-stulist-scope&school&creatorid()\n修复失败学校的的名单sfaildId:\n  {sfaildId.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
                return Ok(new { });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-stulist-scope&school&creatorid()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }

        /// <summary>
        /// 修复blob容器逻辑
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-blob-content")]
        public async Task<IActionResult> FixBlobContent(JsonElement data) {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                await FixDataService.FixBlobContent(client, _dingDing, _azureStorage, data);
                return Ok(new { });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-blob-content()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
        /// <summary>
        /// 修复blob容器逻辑
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-student-info")]
        public async Task<IActionResult> FixStudentInfo(JsonElement data)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
               var list= await FixDataService.FixStudentInfo(client, _dingDing, _azureStorage, data);
                return Ok(new { list});
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-blob-content()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }

        /// <summary>
        /// 修正學段ID非英數邏輯
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-periodid")]
        public async Task<IActionResult> FixPeriodid(JsonElement data)
        {
            try
            {
                if (!data.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
                string schoolCode = school_code.GetString();
                var client = _azureCosmos.GetCosmosClient();
                //學校 Base
                List<string> periodList = await FixDataService.FixSchoolPeriodId(client, schoolCode);
                if (periodList.Count > 0)
                {
                    string periodId = periodList[0]; //修正的問題校都只有一個學段，以第一個學段ID為其餘資料的學段ID
                    Dictionary<string, string> dataDic = new Dictionary<string, string>();
                    dataDic["periodId"] = periodId;
                    //班級 Class
                    List<string> fixClassIdList = await FixDataService.FixClassInfo(client, schoolCode, dataDic);
                    //課程 Course
                    List<string> fixCourseIdList = await FixDataService.FixCourseInfo(client, schoolCode, dataDic);
                    //知識點 Knowledge
                    List<string> fixKnowledgeIdList = await FixDataService.FixKnowledgeInfo(client, schoolCode, dataDic);
                    //試題 Item
                    List<string> fixItemIdList = await FixDataService.FixItemInfo(client, schoolCode, dataDic);
                    //試卷 Paper
                    List<string> fixPaperIdList = await FixDataService.FixPaperInfo(client, schoolCode, dataDic);
                    //課綱 Volume
                    List<string> fixVolumeIdList = await FixDataService.FixVolumeInfo(client, schoolCode, dataDic);
                    //評測 Exam
                    List<string> fixExamIdList = await FixDataService.FixExamInfo(client, schoolCode, dataDic);
                    //學生 Student
                    List<string> fixStudentIdList = await FixDataService.FixStudentInfo(client, schoolCode, dataDic);

                    return Ok(new { schoolCode, fixClassIdList, fixCourseIdList, fixKnowledgeIdList, fixItemIdList, fixPaperIdList, fixVolumeIdList, fixExamIdList, fixStudentIdList });
                }
                else
                {
                    string message = "No period is changed";
                    return Ok(new { message });
                }
            }
            catch (Exception ex)
            {
                //await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-periodid()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
    }
}
