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;
namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("knowledges")]
    [ApiController]
    public class KnowledgesController: ControllerBase
    {
        private readonly SnowflakeId _snowflakeId;
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
        private readonly Option _option;
        private readonly AzureRedisFactory _azureRedis;
        public KnowledgesController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureRedisFactory azureRedis)
        {
            _azureCosmos = azureCosmos;
            _snowflakeId = snowflakeId;
            _dingDing = dingDing;
            _option = option?.Value;
            _azureRedis = azureRedis;
        }
        /**
         * 
         {
           "periodId": "ca484aa8-e7b5-4a7c-8ef3-bd9e7b7d4fp2",
            "subjectId":"ac73f07d-2cc8-4174-85ae-b39cc5b6beef",
            "scope":"school",
            "owner":"hbcn",
            "points": [
                "一元一次方程","二元一次方程","一元二次方程","直线方程","三元一次方程","鸡兔同笼问题","微积分方程","函数有界性","函数单调性","函数奇偶性","函数周期性","函数连续性","函数凹凸性",
                "常函数","一次函数","二次函数","三次函数","四次函数","五次函数","幂函数","指数函数","对数函数","三角函数","反三角函数","常数函数",
                "正弦函数","余弦函数","正切函数","余切函数","正割函数","余割函数","正矢函数","余矢函数","半正矢函数","半余矢函数","外正割函数","外余割函数"
            ],
            "blocks":[
                {
                    "name": "方程式" ,
                    "points":["一元一次方程","二元一次方程","一元二次方程","直线方程","三元一次方程","鸡兔同笼问题","微积分方程"]
                },
                {
                    "name": "函数的特性" ,
                    "points": ["函数有界性","函数单调性","函数奇偶性","函数周期性","函数连续性","函数凹凸性"]
                },
                {
                    "name": "多项式函数" ,
                    "points": ["常函数","一次函数","二次函数","三次函数","四次函数","五次函数"]
                },
                {
                    "name":  "基本初等函数" ,
                    "points": ["幂函数","指数函数","对数函数","三角函数","反三角函数","常数函数"]
                },
                {
                    "name": "三角函数" ,
                    "points":["正弦函数","余弦函数","正切函数","余切函数","正割函数","余割函数","正矢函数","余矢函数","半正矢函数","半余矢函数","外正割函数","外余割函数"]
                }
            ]
        }
         */
        [ProducesDefaultResponseType]
        [HttpPost("upsert")]
        public async Task<IActionResult> Upsert(TEAMModelOS.SDK.Models.Cosmos.Knowledge knowledge) {
            var client = _azureCosmos.GetCosmosClient();
            knowledge.code = $"Knowledge-{knowledge.owner}-{knowledge.subjectId}";
            StringBuilder sql = new StringBuilder($"select value(c) from c where c.periodId = '{knowledge.periodId}'");
            TEAMModelOS.SDK.Models.Cosmos.Knowledge old = null;
            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<TEAMModelOS.SDK.Models.Cosmos.Knowledge>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{ knowledge.code}") }))
            {
                old = item;
                break;
            }
            if (old != null)
            {
                knowledge.id = old.id;
                knowledge = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(knowledge, old.id, new PartitionKey($"{knowledge.code}"));
            }
            else {
                knowledge.id = Guid.NewGuid().ToString();
                knowledge = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(knowledge, new PartitionKey($"{knowledge.code}"));
            }
            var count= new { pcount = knowledge.points!=null ? knowledge.points.Count:0,bcount= knowledge.blocks!=null? knowledge.blocks.Count:0 };
            //处理知识点，知识块计数问题
            await _azureRedis.GetRedisClient(8).HashSetAsync($"Knowledge:Count:{knowledge.owner}-{knowledge.subjectId}", knowledge.periodId, count.ToJsonString());
            return Ok(knowledge);
        }
        /// <summary>
        /**
        
        {
            !"hbcn-ac73f07d-2cc8-4174-85ae-b39cc5b6beef":"ca484aa8-e7b5-4a7c-8ef3-bd9e7b7d4fp2",
        }
       
        单个Item查询一个学校某个科目知识点，知识块数量，如果需要确定某一个学段，则需要加学段。
         **/
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find-count")]
        public async Task<IActionResult> FindCount(Dictionary<string,string> request) 
        {
            List<dynamic> datas = new List<dynamic>();
            foreach (var kp in request) {
                var countPoint = 0;
                var countBlock = 0;
                if (!string.IsNullOrWhiteSpace(kp.Value))
                {
                    var value =await _azureRedis.GetRedisClient(8).HashGetAsync($"Knowledge:Count:{kp.Key}", kp.Value);
                    if (value != default && !value.IsNullOrEmpty)
                    {
                        
                        JsonElement record = value.ToString().ToObject<JsonElement>();
                        if (record.TryGetProperty("pcount", out JsonElement pcout))
                        {
                            int.TryParse($"{pcout}", out countPoint);
                        }
                        if (record.TryGetProperty("bcount", out JsonElement bcout))
                        {
                            int.TryParse($"{bcout}", out countBlock);
                        }
                    }
                }
                else {
                    var values = await _azureRedis.GetRedisClient(8).HashGetAllAsync($"Knowledge:Count:{kp.Key}");
                    if (values != null) {
                        foreach (var value in values) 
                        {
                            JsonElement record = value.ToString().ToObject<JsonElement>();
                            if (record.TryGetProperty("pcount", out JsonElement pcout))
                            {
                                if (int.TryParse($"{pcout}", out int countP)) 
                                {
                                    countPoint = countPoint + countP;
                                }
                            }
                            if (record.TryGetProperty("bcount", out JsonElement bcout))
                            {
                                if(int.TryParse($"{bcout}", out int countB)) 
                                {
                                    countBlock = countBlock + countB;
                                }
                            }
                        }
                    }
                }
                datas.Add( new { key = kp.Key, countPoint, countBlock });
            }
            return Ok(new { datas });
        }


          
        /**
         * {
            ?"periodId": "ca484aa8-e7b5-4a7c-8ef3-bd9e7b7d4fp2",
            !"subjectId": "ac73f07d-2cc8-4174-85ae-b39cc5b6beef",
            !"school_code": "hbcn"
            }
         **/
        [ProducesDefaultResponseType]
        [HttpPost("find")]
        public async Task<IActionResult> Find(JsonElement request) {
            var client = _azureCosmos.GetCosmosClient();
            request.TryGetProperty("periodId", out JsonElement periodId);
            if (!request.TryGetProperty("subjectId", out JsonElement subjectId)) return BadRequest();
            if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
            string code = $"Knowledge-{school_code}-{subjectId}";
            StringBuilder sql = new StringBuilder($"select value(c) from c");
            if (periodId.ValueKind.Equals(JsonValueKind.String)) {
                sql.Append($" where c.periodId = '{periodId}'");
            }
            List<TEAMModelOS.SDK.Models.Cosmos.Knowledge> knowledges = new List<SDK.Models.Cosmos.Knowledge>() ;
            await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<TEAMModelOS.SDK.Models.Cosmos.Knowledge>(queryText: sql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
            {
                knowledges.Add(item);
            }
            return Ok(knowledges);
        }
    }
}
