using Azure.Cosmos;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Models;
using TEAMModelOS.Models.Dto;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK;
using TEAMModelOS.SDK.Helper.Common.StringHelper;
using System.Dynamic;
using Azure;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using Azure.Messaging.ServiceBus;
using Microsoft.Extensions.Configuration;
using TEAMModelOS.Filter;
using Azure.Storage.Blobs.Models;
using HTEXLib.COMM.Helpers;
using TEAMModelFunction;

namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("tchlist")]
    [ApiController]
    public class TchListController : ControllerBase
    {
        private AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        private readonly Option _option;
        private readonly AzureServiceBusFactory _serviceBus;
        private readonly AzureStorageFactory _azureStorage;
        public IConfiguration _configuration { get; set; }
        public TchListController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option, AzureServiceBusFactory serviceBus, AzureStorageFactory azureStorage, IConfiguration configuration)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
            _option = option?.Value;
            _serviceBus = serviceBus;
            _configuration = configuration;
            _azureStorage = azureStorage;
        }


        //查询名单
        [ProducesDefaultResponseType]
        // [AuthToken(Roles = "admin,teacher")]
        [HttpPost("get-research-list")]
        public async Task<IActionResult> getResearch(JsonElement requert)
        {
            try
            {
                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                requert.TryGetProperty("ids", out JsonElement _stuids);
                var client = _azureCosmos.GetCosmosClient();
                List<TchList> tchLists = new();
                List<string> ids = new();
                if (!_stuids.ValueKind.Equals(JsonValueKind.Undefined) && _stuids.ValueKind.Equals(JsonValueKind.Array))
                {
                    ids = _stuids.ToObject<List<string>>();
                }
                // var query = $"select c.id,c.name,c.students,c.tmids,c.periodId from c";
                StringBuilder query = new StringBuilder($"select value(c) from c where c.type='research' ");
                if (ids.IsNotEmpty())
                {
                    string sql = $" and c.id in ({string.Join(",", ids.Select(o => $"'{o}'"))})";
                    query.Append(sql);
                }
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TchList>(queryText: query.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"TchList-{code}") }))
                {
                    tchLists.Add(item);
                }
                return Ok(new { tchLists });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，course/get-summary-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
        //处理教师名单
        [ProducesDefaultResponseType]
        [AuthToken(Roles = "teacher,admin")]
        [HttpPost("find-list-members")]
        public async Task<IActionResult> FindListMembers(JsonElement json) {
            try
            {
                var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
                if (!json.TryGetProperty("school_code", out JsonElement _code)) return BadRequest();
                if (!json.TryGetProperty("ids", out JsonElement _ids)) return BadRequest();
                var client = _azureCosmos.GetCosmosClient();
                List<string> classes = _ids.ToObject<List<string>>();
                List<dynamic> list = new List<dynamic>();
                foreach (string cls in classes)
                {
                    (List<TmdInfo> tmdids,List<ClassListInfo> classLists) = await TriggerStuActivity.GetTchList(client, _dingDing, new List<string> { cls }, $"{_code}");
                    if (classLists.IsNotEmpty())
                    {
                        list.Add(new { tmdids,  @class = classLists.First() });
                    }
                }
                return Ok(new { list });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{json}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }


        //处理教师名单
        [ProducesDefaultResponseType]
        [AuthToken(Roles = "teacher,admin")]
        [HttpPost("upsert-list")]
        public async Task<IActionResult> upsertList(JsonElement json)
        {
            try
            {
                var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
                TchList tchList =null;
                if (!string.IsNullOrEmpty(school))
                {
                    tchList = json.ToObject<TchList>();
                    tchList.creatorId = userid;
                    tchList.school = school;
                    tchList.pk = "TchList";
                    tchList.code = $"TchList-{school}";
                    tchList.scope = "school";
                    tchList.ttl = -1;
                    tchList = await upsertList(tchList);
                }
                return Ok(new { tchList });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{json}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
        //处理教师名单
        [ProducesDefaultResponseType]
        [AuthToken(Roles = "teacher,admin")]
        [HttpPost("delete-list")]
        public async Task<IActionResult> deleteList(JsonElement request)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
                if (!request.TryGetProperty("id", out JsonElement _id)) return BadRequest();
                await client.GetContainer(Constant.TEAMModelOS, "School").DeleteItemStreamAsync($"{_id}", new PartitionKey($"TchList-{school}"));
                return Ok(new {  });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{request}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }

        private async Task<TchList> upsertList(TchList tchList)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //todo 需要校验是否重复
                if (string.IsNullOrEmpty(tchList.no))
                {
                    tchList.no = $"{Utils.CreatSaltString(6, "0123456789")}";
                    for (int i = 0; i < 10; i++)
                    {
                        var queryNo = $"SELECT  c.no  FROM c where  c.no ='{tchList.no}'";
                        List<string> noStus = new();
                        await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: queryNo,
                                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"{tchList.code}") }))
                        {
                            using var jsonNo = await JsonDocument.ParseAsync(item.ContentStream);
                            if (jsonNo.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                            {
                                var accounts = jsonNo.RootElement.GetProperty("Documents").EnumerateArray();
                                while (accounts.MoveNext())
                                {
                                    JsonElement account = accounts.Current;
                                    noStus.Add(account.GetProperty("no").GetString());
                                }
                            }
                        }
                        if (noStus.Count == 0)
                        {
                            break;
                        }
                        else
                        {
                            if (i == 9)
                            {
                                string msg = $"OS，{_option.Location}，upsert-list()\n 编号生成异常，重复生成次数超过10次";
                                await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組);
                                throw new Exception(msg);
                            }
                            else
                            {
                                tchList.no = $"{Utils.CreatSaltString(6, "0123456789")}";
                            }
                        }
                    }
                }
                ListChange change = new ListChange()
                {
                    type = tchList.type,
                    listid = tchList.id,
                    scope = "school",
                    originCode = tchList.school,
                    school = tchList.school,
                    creatorId = tchList.creatorId
                };
                var query = $"SELECT distinct value(c)  FROM c where  c.id='{tchList.id}'";
                List<TchList> odlStus = new List<TchList>();
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<TchList>(queryText: query,
                        requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"TchList-{tchList.school}") }))
                {
                    odlStus.Add(item);
                }
                if (odlStus.Count > 0)
                {
                    if (tchList.teachers != null)
                    {
                        if (odlStus[0].teachers != null)
                        {
                        TchList oldStu = odlStus[0];
                            foreach (var teacher in tchList.teachers)
                            {
                                bool flag = false;
                                //判断新增名单成员不在已经存在的名单
                                foreach (var old in oldStu.teachers)
                                {
                                    if (old.Equals(teacher))
                                    {
                                        flag = true;
                                    }
                                }
                                if (flag == false)
                                {
                                    change.tchjoin.Add(teacher);
                                }
                            }
                            foreach (var old in oldStu.teachers)
                            {
                                bool flag = false;
                                //判断已存在名单成员不在变更后的名单里
                                foreach (var teacher in tchList.teachers)
                                {
                                    if (old.Equals(teacher))
                                    {
                                        flag = true;
                                    }
                                }
                                if (flag == false)
                                {
                                    change.tchleave.Add(old);
                                }
                            }
                        }
                    }
                    if (change.tmdjoin.Count != 0 || change.tmdhleave.Count != 0 || change.stujoin.Count != 0 || change.stuleave.Count != 0 || change.tchjoin.Count != 0 || change.tchleave.Count != 0)
                    {
                        var messageChange = new ServiceBusMessage(change.ToJsonString());
                        messageChange.ApplicationProperties.Add("name", "StuList");
                        var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
                        await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
                    }
                }
                tchList = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(tchList, new PartitionKey($"TchList-{tchList.school}"));
                return tchList;
            }
            catch (Exception ex)
            {
                string msg = $"OS，{_option.Location}，course/upsert-list()\n{ex.Message}{ex.StackTrace}\n{tchList.ToJsonString()}";
                await _dingDing.SendBotMsg(msg, GroupNames.醍摩豆服務運維群組);
                throw new Exception(msg, ex);
            }
        }
    }
}
