using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TEAMModelOS.Models;
using TEAMModelOS.SDK;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using TEAMModelOS.SDK.DI;
using System.Text.Json;
using TEAMModelOS.SDK.Helper.Common.StringHelper;
using TEAMModelOS.SDK.Models;
using Microsoft.AspNetCore.Http;
using TEAMModelOS.SDK.Extension;
using Azure.Cosmos;
using Microsoft.AspNetCore.Authentication;
using System.Text;
using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
using Microsoft.Extensions.Options;
using Azure.Messaging.ServiceBus;
using Microsoft.Extensions.Configuration;
using TEAMModelOS.Services.Common;

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

        [ProducesDefaultResponseType]
        [HttpPost("upsert")]
        public async Task<IActionResult> Upsert(JsonElement request)
        {

            /*            if (string.IsNullOrEmpty(request.id))
                        {
                            request.id = _snowflakeId.NextId() + "";
                            request.code = typeof(ItemInfo).Name + "-" + request.code;
                        };
                        request.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                        return Ok(await _azureCosmos.SaveOrUpdate(request));*/
            var client = _azureCosmos.GetCosmosClient();
            if (!request.TryGetProperty("itemInfo", out JsonElement item)) return BadRequest();
            if (!request.TryGetProperty("option", out JsonElement option)) return BadRequest();
            try
            {
                ItemInfo itemInfo;
                itemInfo = item.ToObject<ItemInfo>();
                itemInfo.size = await _azureStorage.GetBlobContainerClient(itemInfo.code).GetBlobsSize($"item/{itemInfo.id}");
                var messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "update", root = $"item/{itemInfo.id}", name = $"{itemInfo.code}" }.ToJsonString());
                messageBlob.ApplicationProperties.Add("name", "BlobRoot");
                var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
                await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
                if (option.ToString().Equals("insert"))
                {
                    itemInfo.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    //DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    if (!itemInfo.code.Contains("Item"))
                    {
                        itemInfo.code = "Item-" + itemInfo.code;
                        // itemInfo = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(itemInfo, itemInfo.id, new PartitionKey($"{itemInfo.code}"));
                    }
                    var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(itemInfo.id, new PartitionKey($"{itemInfo.code}"));
                    if (response.Status == 200)
                    {
                        return Ok();
                    }
                    else
                    {
                        if (itemInfo.scope.Equals("private"))
                        {
                            itemInfo = await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(itemInfo, new PartitionKey($"{itemInfo.code}"));
                        }
                        else
                        {
                            itemInfo = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(itemInfo, new PartitionKey($"{itemInfo.code}"));
                        }
                    }
                }
                else
                {
                    itemInfo.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    if (itemInfo.scope.Equals("private"))
                    {
                        if (!itemInfo.code.Contains("Item"))
                        {
                            itemInfo.code = "Item-" + itemInfo.code;
                            // itemInfo = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(itemInfo, itemInfo.id, new PartitionKey($"{itemInfo.code}"));
                        }
                        itemInfo = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(itemInfo, itemInfo.id, new PartitionKey($"{itemInfo.code}"));

                    }
                    else
                    {
                        if (!itemInfo.code.Contains("Item"))
                        {
                            itemInfo.code = "Item-" + itemInfo.code;
                            //itemInfo = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(itemInfo, itemInfo.id, new PartitionKey($"{itemInfo.code}"));
                        }
                        itemInfo = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(itemInfo, itemInfo.id, new PartitionKey($"{itemInfo.code}"));


                    }
                }
                return Ok(new { itemInfo });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，item/upsert()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }
        /// <summary>
        //获取题目摘要信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("find-summary")]
        public async Task<IActionResult> FindSummary(JsonElement requert)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                StringBuilder sql = new StringBuilder();
                sql.Append("select c.id, c.question,c.useCount,c.level,c.field,c.knowledge,c.type,c.option,c.createTime from c ");
                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                /*            if (!requert.TryGetProperty("@CURRPAGE", out JsonElement page)) return BadRequest();
                            if (!requert.TryGetProperty("@PAGESIZE", out JsonElement size)) return BadRequest();*/
                if (!requert.TryGetProperty("@DESC", out JsonElement desc)) return BadRequest();
                if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
                List<object> summary = new List<object>();
                Dictionary<string, object> dict = new Dictionary<string, object>();
                /*            dict.Add("@CURRPAGE", page.GetInt32());
                            dict.Add("@PAGESIZE", size.GetInt32());*/
                dict.Add("@DESC", desc.ToString());
                if (requert.TryGetProperty("periodId", out JsonElement periodId))
                {
                    dict.Add("periodId", periodId);
                }
                if (requert.TryGetProperty("subjectId", out JsonElement subjectId))
                {
                    dict.Add("subjectId", subjectId);
                }
                if (requert.TryGetProperty("level", out JsonElement level))
                {
                    dict.Add("level", level);
                }
                if (requert.TryGetProperty("type", out JsonElement type))
                {
                    dict.Add("type", type);
                }
                if (requert.TryGetProperty("field", out JsonElement field))
                {
                    dict.Add("field", field);
                }
                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
                //List<object> items = new List<object>();
                if (scope.ToString().Equals("private"))
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{code}") }))
                    {
                        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())
                            {
                                summary.Add(obj.ToObject<object>());
                            }
                        }
                    }
                }
                if (scope.ToString().Equals("school"))
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{code}") }))
                    {
                        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())
                            {
                                summary.Add(obj.ToObject<object>());
                            }
                        }
                    }
                }
                return Ok(new { summary });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，item/FindSummary()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("delete")]
        public async Task<IActionResult> Delete(JsonElement request)
        {
            try
            {
                if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
                if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
                if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
                var client = _azureCosmos.GetCosmosClient();
                //删除blob 相关资料
                await _azureStorage.GetBlobServiceClient().DelectBlobs(code.ToString().Replace("Item-",""), $"item/{id}");
                //通知删除信息
                var messageBlob = new ServiceBusMessage(new { id = Guid.NewGuid().ToString(), progress = "delete", root = $"item/{id}", name = code.ToString().Replace("Item-", "") }.ToJsonString());
                messageBlob.ApplicationProperties.Add("name", "BlobRoot");
                var ActiveTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
                await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageBlob);
                if (scope.ToString().Equals("school"))
                {
                    var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                    return Ok(new { code = response.Status });
                }
                else
                {
                    var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                    return Ok(new { code = response.Status });
                }

            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，item/FindSummary()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

            /* ResponseBuilder builder = ResponseBuilder.custom();
             IdPk idPk = await _azureCosmos.DeleteAsync<ItemInfo>( request );
             return Ok(idPk);*/
        }

        /// <summary>
        /// 手动挑题
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("find")]
        public async Task<IActionResult> Find(JsonElement requert)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                StringBuilder sql = new StringBuilder();
                sql.Append("select c.id,c.code,c.repairResource, c.periodId,c.question,c.useCount,c.level,c.field,c.knowledge,c.type,c.option,c.createTime,c.answer,c.explain,c.children,c.score,c.gradeIds,c.subjectId,c.blob,c.scope from c ");
                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                /*            if (!requert.TryGetProperty("@CURRPAGE", out JsonElement page)) return BadRequest();
                            if (!requert.TryGetProperty("@PAGESIZE", out JsonElement size)) return BadRequest();*/
                if (!requert.TryGetProperty("@DESC", out JsonElement desc)) return BadRequest();
                if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
                Dictionary<string, object> dict = new Dictionary<string, object>();
                /*var emobj = requert.EnumerateObject();
                while (emobj.MoveNext())
                {
                    dict[emobj.Current.Name] = emobj.Current.Value;
                }
                //处理code
                if (dict.TryGetValue("code", out object _))
                {
                    dict.Remove("code");
                }*/
                /*            dict.Add("@CURRPAGE", page.GetInt32());
                            dict.Add("@PAGESIZE", size.GetInt32());*/

                dict.Add("@DESC", desc.ToString());
                if (requert.TryGetProperty("periodId", out JsonElement periodId))
                {
                    dict.Add("periodId", periodId);
                }
                if (requert.TryGetProperty("subjectId", out JsonElement subjectId))
                {
                    dict.Add("subjectId", subjectId);
                }
                if (requert.TryGetProperty("level", out JsonElement level))
                {
                    dict.Add("level", level);
                }
                if (requert.TryGetProperty("type", out JsonElement type))
                {
                    dict.Add("type", type);
                }
                if (requert.TryGetProperty("field", out JsonElement field))
                {
                    dict.Add("field", field);
                }
                if (requert.TryGetProperty("gradeIds[*]", out JsonElement gradeIds))
                {
                    dict.Add("gradeIds[*]", gradeIds);
                }
                if (requert.TryGetProperty("pid", out JsonElement pd))
                {
                    if (pd.ValueKind != JsonValueKind.Null)
                    {
                        dict.Add("pid", pd.ToString());
                    }
                    else
                    {
                        dict.Add("pid", null);
                    }

                }
                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
                List<object> items = new List<object>();
                if (scope.ToString().Equals("private"))
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{code}") }))
                    {
                        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())
                            {
                                items.Add(obj.ToObject<object>());
                            }
                        }
                    }
                }
                if (scope.ToString().Equals("school"))
                {
                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{code}") }))
                    {
                        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())
                            {
                                items.Add(obj.ToObject<object>());
                            }
                        }
                    }
                }
                //ResponseBuilder builder = ResponseBuilder.custom();
                /* List<ItemInfo> items = new List<ItemInfo>();
                 if (StringHelper.getKeyCount(requert) > 0)
                 {
                     items = await _azureCosmos.FindByDict<ItemInfo>(requert);
                 }*/
                return Ok(new { items });
                //return builder.Data(items).build();
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，item/Find()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest(e.StackTrace);
            }

        }

        /// <summary>
        /// 手动挑题
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("Find-cache-shell")]
        public async Task<IActionResult> FindCacheShell(JsonElement requert)
        {
            var client = _azureCosmos.GetCosmosClient();
            if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
            if (!requert.TryGetProperty("ids", out JsonElement id)) return BadRequest();
            //List<string> ids = new List<string>();
            string info = "";
            for (int i = 0; i < id.GetArrayLength(); i++)
            {
                //ids.Add(id[i].ToJsonString());
                info += id[i].ToJsonString() + ",";
            }
            List<object> items = new List<object>();
            var query = $"select c.id, c.question,c.useCount,c.level,c.field,c.knowledge,c.type,c.option,c.createTime from c where c.id in ({info[0..^1]})";
            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{school_code}") }))
            {
                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())
                    {
                        items.Add(obj.ToObject<object>());
                    }
                }
            }

            return Ok(new { items });

        }

        /// <summary>
        /// 自动组题
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost("Automatic")]
        public async Task<IActionResult> Automatic(List<Compose> request)
        {
            try
            {
                //ResponseBuilder builder = ResponseBuilder.custom();
                List<Dictionary<string, object>> list = new List<Dictionary<string, object>>();
                var client = _azureCosmos.GetCosmosClient();
                for (int i = 0; i < request.Count; i++)
                {

                    ///处理知识点均分问题
                    int avg = 0;
                    Dictionary<string, int> point = new Dictionary<string, int>();
                    if (request[i].points.IsNotEmpty())
                    {
                        avg = (int)Math.Ceiling(request[i].count * 1.0 / request[i].points.Count);

                        foreach (string p in request[i].points)
                        {
                            point.TryAdd(p, avg);
                        }
                    }
                    List<ItemInfo> retnInfos = new List<ItemInfo>();
                    List<ItemInfo> itemInfos = new List<ItemInfo>();
                    List<TempItem> tempItems = new List<TempItem>();
                    if (request[i].quInfos.IsNotEmpty())
                    {
                        List<string> types = new List<string>();
                        List<int> levels = new List<int>();
                        foreach (QuInfo quInfo in request[i].quInfos)
                        {
                            StringBuilder sql = new StringBuilder();
                            sql.Append("select c.id,c.code,c.repairResource, c.periodId,c.question,c.useCount,c.level,c.field,c.knowledge,c.type,c.option,c.createTime,c.answer,c.explain,c.children,c.score,c.gradeIds,c.subjectId,c.blob,c.scope from c ");
                            // 自定义
                            if (quInfo.custom.IsNotEmpty() && quInfo.policy.Equals("custom"))
                            {
                                foreach (Custom custom in quInfo.custom)
                                {
                                    for (int j = 0; j < custom.count; j++)
                                    {
                                        tempItems.Add(new TempItem { level = custom.level, type = quInfo.type });
                                    }
                                    Dictionary<string, object> dict = new Dictionary<string, object>();
                                    if (!string.IsNullOrEmpty(request[i].code))
                                    {
                                        dict.Add("code", request[i].code);
                                    }
                                    if (!string.IsNullOrEmpty(request[i].period))
                                    {
                                        dict.Add("periodId", request[i].period);
                                    }
                                    if (request[i].points.IsNotEmpty())
                                    {
                                        dict.Add("knowledge[*]", request[i].points.ToArray());
                                    }
                                    //dict.Add("lite", false);
                                    dict.Add("pid", null);
                                    ///
                                    dict.Add("type", quInfo.type);
                                    dict.Add("level", custom.level);
                                    List<ItemInfo> items = new List<ItemInfo>();
                                    AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
                                    if (request[i].scope.Equals("school"))
                                    {
                                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{request[i].code}") }))
                                        {
                                            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())
                                                {
                                                    items.Add(obj.ToObject<ItemInfo>());
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{request[i].code}") }))
                                        {
                                            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())
                                                {
                                                    items.Add(obj.ToObject<ItemInfo>());
                                                }
                                            }
                                        }
                                    }
                                    //List<ItemInfo> items = await _azureCosmos.FindByDict<ItemInfo>(dict);
                                    //id去重
                                    items = items.Where((x, i) => items.FindIndex(z => z.id == x.id) == i).ToList();
                                    ////均分知识点题目
                                    itemInfos.AddRange(items);
                                }
                            }
                            else
                            {
                                Dictionary<string, object> dict = new Dictionary<string, object>();
                                if (!string.IsNullOrEmpty(request[i].code))
                                {
                                    dict.Add("code", request[i].code);
                                }
                                if (!string.IsNullOrEmpty(request[i].period))
                                {
                                    dict.Add("periodId", request[i].period);
                                }
                                if (request[i].points.IsNotEmpty())
                                {
                                    dict.Add("knowledge[*]", request[i].points.ToArray());
                                }
                                if (!string.IsNullOrEmpty(request[i].subject))
                                {
                                    dict.Add("subjectId", request[i].subject);
                                }
                                //dict.Add("lite", false);
                                dict.Add("pid", null);
                                dict.Add("type", quInfo.type);
                                List<ItemInfo> items = new List<ItemInfo>();
                                AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
                                if (request[i].scope.Equals("school"))
                                {
                                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{request[i].code}") }))
                                    {
                                        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())
                                            {
                                                items.Add(obj.ToObject<ItemInfo>());
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{request[i].code}") }))
                                    {
                                        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())
                                            {
                                                items.Add(obj.ToObject<ItemInfo>());
                                            }
                                        }
                                    }
                                }
                                //List<ItemInfo> items = await _azureCosmos.FindByDict<ItemInfo>(dict);
                                //id去重
                                items = items.Where((x, i) => items.FindIndex(z => z.id == x.id) == i).ToList();
                                itemInfos.AddRange(items);
                                //均分
                                if (quInfo.policy.Equals("average"))
                                {
                                    //按等级去重 获取所有等级
                                    List<int> lvls = items.Where((x, i) => items.FindIndex(z => z.level == x.level) == i).Select(x => x.level).ToList();
                                    foreach (int k in lvls)
                                    {
                                        int count = quInfo.count / lvls.Count;
                                        for (int j = 0; j < count; j++)
                                        {
                                            tempItems.Add(new TempItem { level = k, type = quInfo.type });
                                        }
                                    }
                                    //  余数 取模 随机处理
                                    if (lvls.Count != 0)
                                    {
                                        int mod = quInfo.count % lvls.Count;
                                        for (int m = 0; m < mod; m++)
                                        {
                                            int lv = lvls.OrderBy(x => Guid.NewGuid()).Take(1).FirstOrDefault();
                                            tempItems.Add(new TempItem { level = lv, type = quInfo.type });
                                            lvls.Remove(lv);
                                        }
                                    }
                                }
                                //随机
                                if (quInfo.policy.Equals("random"))
                                {
                                    List<int> lvls = items.Where((x, i) => items.FindIndex(z => z.level == x.level) == i).Select(x => x.level).ToList();
                                    for (int n = 0; n < quInfo.count; n++)
                                    {
                                        int lv = lvls.OrderBy(x => Guid.NewGuid()).FirstOrDefault();
                                        tempItems.Add(new TempItem { level = lv, type = quInfo.type, policy = "random" });
                                    }
                                }
                            }
                        }
                    }
                    itemInfos = itemInfos.OrderBy(x => Guid.NewGuid()).ToList();
                    tempItems = tempItems.OrderBy(x => Guid.NewGuid()).ToList();
                    foreach (TempItem temp in tempItems)
                    {
                        ItemInfo itemInfo = new ItemInfo();
                        if (temp.policy != null && temp.policy.Equals("random"))
                        {
                            itemInfo = itemInfos.Where(x => x.type == temp.type).OrderBy(x => Guid.NewGuid()).FirstOrDefault();
                        }
                        else
                        {
                            itemInfo = itemInfos.Where(x => x.level == temp.level && x.type == temp.type).OrderBy(x => Guid.NewGuid()).FirstOrDefault();
                        }

                        if (itemInfo != null)
                        {
                            retnInfos.Add(itemInfo);
                            itemInfos.Remove(itemInfo);
                        }
                    }

                    List<ItemInfo> restItem = new List<ItemInfo>();
                    //处理综合题问题
                    foreach (var item in retnInfos)
                    {
                        if (!string.IsNullOrWhiteSpace(item.pid))
                        {
                            if (item.scope == "school")
                            {
                                var iteme = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<ItemInfo>(item.id, new PartitionKey(item.code));
                                if (iteme != null)
                                {
                                    restItem.Add(iteme.Value);
                                }

                            }
                            else if (item.scope == "private")
                            {
                                var iteme = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<ItemInfo>(item.id, new PartitionKey(item.code));
                                if (iteme != null)
                                {
                                    restItem.Add(iteme.Value);
                                }
                            }
                        }
                        else
                        {
                            restItem.Add(item);
                        }
                    }
                    List<List<ItemInfo>> listInfo = new List<List<ItemInfo>>();
                    //处理综合题id重复
                    restItem = restItem.Where((x, i) => restItem.FindIndex(z => z.id == x.id) == i).ToList();
                    foreach (IGrouping<string, ItemInfo> group in restItem.GroupBy(c => c.type))
                    {
                        Dictionary<string, object> dictInfo = new Dictionary<string, object>();
                        listInfo.Add(group.ToList());
                    }
                    foreach (List<ItemInfo> infos in listInfo)
                    {
                        List<Dictionary<string, object>> dict = new List<Dictionary<string, object>>();
                        foreach (IGrouping<int, ItemInfo> group in infos.GroupBy(c => c.level))
                        {
                            Dictionary<string, object> dictInfo = new Dictionary<string, object>();
                            dictInfo.Add("level", group.Key);
                            dictInfo.Add("count", group.Count());
                            dict.Add(dictInfo);
                        }
                        Dictionary<string, object> typeDict = new Dictionary<string, object>();
                        typeDict.Add("info", dict);
                        typeDict.Add("item", infos);
                        typeDict.Add("count", infos.Count);
                        typeDict.Add("type", infos.FirstOrDefault().type);
                        list.Add(typeDict);
                    }
                }

                //return builder.Data(list).build();
                return Ok(list);
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，item/Automatic()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }
    }

    public class TempItem
    {
        public string type { get; set; }
        public int level { get; set; }
        public ItemInfo itemInfo { get; set; }
        public string policy { get; set; }
    }


    public class Compose
    {
        /// <summary>
        /// 科目
        /// </summary>
        public string subject { get; set; }
        /// <summary>
        /// 来源，个人题库，校本题库
        /// </summary>
        public string code { get; set; }
        /// <summary>
        /// 适用学段，小学，初中，高中
        /// </summary>
        public string period { get; set; }
        /// <summary>
        /// 关联知识点
        /// </summary>
        public List<string> points { get; set; }
        /// <summary>
        /// 题目组合
        /// </summary>
        public List<QuInfo> quInfos { get; set; }
        /// <summary>
        /// 题目总数
        /// </summary>
        public int count { get; set; }
        public string scope { get; set; }
    }
    public class QuInfo
    {
        /// <summary>
        /// 题目类型，单选，多选，判断，填空，问答，综合  Single单选，Multiple多选，Judge判断，Complete填空，Subjective问答，Compose综合
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 随机 random  平均的 average ,自定义 custom
        /// </summary>
        public string policy { get; set; }
        /// <summary>
        /// 自定义题目类型
        /// </summary>
        public List<Custom> custom { get; set; }
        /// <summary>
        /// 总题
        /// </summary>
        public int count { get; set; }
    }
    public class Custom
    {
        /// <summary>
        /// 难易程度
        /// </summary>
        public int level { get; set; }
        /// <summary>
        /// 数量
        /// </summary>
        public int count { get; set; }
    }
}
