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;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using TEAMModelOS.Services.Common;

namespace TEAMModelOS.Controllers
{
    [Route("test")]
    [ApiController]
    public class TestController :ControllerBase
    {
        private readonly AzureStorageFactory _azureStorage;
        private readonly AzureRedisFactory _azureRedis;
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly DingDing _dingDing;
       

        public TestController(AzureCosmosFactory azureCosmos, AzureRedisFactory azureRedis, AzureStorageFactory azureStorage, DingDing dingDing) {
            _azureCosmos = azureCosmos;
            _azureRedis = azureRedis;
            _azureStorage = azureStorage;
            _dingDing = dingDing;
        }
        /// <summary>
        /// 测试blob多线程写入同一个文件
        /// </summary>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("blobroot")]
        public async Task<IActionResult> MultipleBlob(JsonElement jsonMsg) {
            if (jsonMsg.TryGetProperty("name", out JsonElement name) && name.ValueKind == JsonValueKind.String
                    && jsonMsg.TryGetProperty("root", out JsonElement root) && root.ValueKind == JsonValueKind.String)
            {
                List<Dictionary<string, double?>> list = new List<Dictionary<string, double?>>();
                string u = System.Web.HttpUtility.UrlDecode($"{root}", Encoding.UTF8).Split("/")[0];
                var client = _azureStorage.GetBlobContainerClient($"{name}");
                var size = await client.GetBlobsSize(u);
                await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", u);
                await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", u, size.HasValue ? size.Value : 0);
                var scores = await _azureRedis.GetRedisClient(8).SortedSetRangeByRankWithScoresAsync($"Blob:Catalog:{name}");
                double blobsize = 0;
                if (scores != default && scores != null)
                {
                    foreach (var score in scores)
                    {
                        blobsize = blobsize + score.Score;
                        list.Add(new Dictionary<string, double?>() { { score.Element.ToString(), score.Score } });
                    }
                }
                await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", new RedisValue($"{name}"), new RedisValue($"{blobsize}"));

                await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Blob() 容器:{name}使用:{root}，文件分类：{list.ToJsonString()}",
                    GroupNames.成都开发測試群組);
                return Ok(list);
            }
            else {
                return Ok();
            }
            
        }

        private async Task<int> SendNotification( )
        {


            HttpClient _httpClient = new HttpClient();
            //  _httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {token.AccessToken}");
            var pa = new { grant_type = "device", client_id= "9794e418-c4ef-4fd5-a42d-accaa2d96d6e" , client_secret = "ruL?I79h0w1AZaZXtBaZeZuQLQXLa=:-" };
            HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync("https://api2-rc.teammodel.net/oauth2/token", pa);
            if (responseMessage.StatusCode == HttpStatusCode.OK)
            {
                return 200;
            }
            else if (responseMessage.StatusCode == HttpStatusCode.Unauthorized)
            {
                return 401;
            }
            else
            {
                return 500;
            }
        }

        /// <summary>
        /// 测试redis通配符
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpGet("test-delete-read")]
        public async Task<IActionResult> TestDelete() {

            foreach (var cnt in _azureStorage.GetBlobServiceClient().GetBlobContainers()) {
               Console.WriteLine(cnt.Name);
            }

            await  SendNotification();
            var client = _azureCosmos.GetCosmosClient();
            string aaa = "0";
            try { 
                ItemResponse<Student> a = await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemAsync<Student>("1111111", new PartitionKey($"Course-111111"));
                Ok(a.GetRawResponse().Status);
            } catch (CosmosException ex) {
                if (ex.Response.Status == 404) {
                    aaa = "404";
                }
            }

            try
            {
                ItemResponse<Student> a = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemAsync<Student>("1111111", new PartitionKey($"Course-111111"));
                Ok(a.GetRawResponse().Status);
            }
            catch (CosmosException ex)
            {
                if (ex.Response.Status == 404)
                {
                    aaa = aaa+ " 404";
                }
            }
            try
            {
                var a = await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemStreamAsync("1111111", new PartitionKey($"Course-111111"));
                Ok(a.Status);
            }
            catch (CosmosException ex)
            {
                if (ex.Response.Status == 404)
                {
                    aaa = "404";
                }
            }

            try
            {
                var a = await client.GetContainer(Constant.TEAMModelOS, "Student").ReadItemStreamAsync("1111111", new PartitionKey($"Course-111111"));
                Ok(a.Status);
            }
            catch (CosmosException ex)
            {
                if (ex.Response.Status == 404)
                {
                    aaa = aaa + " 404";
                }
            }
            return Ok(new { aaa });
        }
        /// <summary>
        /// 测试redis通配符
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpGet("test-redis")]
        public async Task<IActionResult> TestRedis( ) {
            
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                List<ItemInfo> items = new List<ItemInfo>();
                var queryslt = $"SELECT  value(c) FROM c where  c.pid = null ";
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ItemInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-hbcn") }))
                {

                    items.Add(item);
                }
                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-hbcn", 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 { itemConds });
            }
            catch (Exception ex) { await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-itemcond()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組); }
            return  Ok(new { });
            
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("fix-blob-content")]
        public async Task<IActionResult> FixBlobContent(JsonElement request)
        {
            try
            {
                if (!request.TryGetProperty("name", out JsonElement name)) return BadRequest();
                if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
                
                
                    var client = _azureCosmos.GetCosmosClient();
                    List<string> prefixs = new List<string>() { "audio", "doc", "image", "other", "res", "video", "thum" };
                    var ContainerClient = _azureStorage.GetBlobContainerClient($"{name}");
                    string scope = "private";
                     
                     
                        scope = $"{_scope}";
                   
                    var tb = "Teacher";
                    if (scope != "private")
                    {
                        tb = "School";
                    }
                    long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    
                    foreach (var prefix in prefixs)
                    {
                        List<string> items = await ContainerClient.List(prefix);
                        foreach (var item in items)
                        {
                            var urlsSize = await ContainerClient.GetBlobsSize(item);
                            Bloblog bloblog = new Bloblog { id = Guid.NewGuid().ToString(), code = $"Bloblog-{name}", pk = "Bloblog", time = now, size = urlsSize != null && urlsSize.HasValue ? urlsSize.Value : 0, type = prefix };
                           await client.GetContainer(Constant.TEAMModelOS, tb).UpsertItemAsync(bloblog, new Azure.Cosmos.PartitionKey(bloblog.code)) ;
                        }
                    }
                     
               
                return new OkObjectResult(new { });

            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"TEAMModelFunction，ActivityHttpTrigger，fix-blob-content()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return new BadRequestResult();
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("delete")]
        public async Task<IActionResult> Delete(JsonElement request)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                var query = $"select c.id ,c.code from c where c.pk='StuCourse' ";
                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<IdCode>(queryText: query))
                {
                  await  client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemStreamAsync(item.id, new PartitionKey(item.code));
                }
                return Ok(new { code = 1 });
            }
            catch (Exception e)
            {
                return BadRequest(e.StackTrace);
            }
        }/// <summary>
         /// 删除
         /// </summary>
         /// <param name="request"></param>
         /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "teacher")]
        [HttpPost("get-data")]
        public async Task<IActionResult> GetData(JsonElement request)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                (List<TmdInfo> tchList, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, new List<string> { "76739d39-b9c1-d34f-8407-836369a4f3a2", "82c216a2-2595-ffc7-1b80-5455e064bc03" , "a981419a-6c35-22fe-f339-8f46e5a41456" }, "hbcn");
                return Ok(new { code = 1, tchList, classInfos });
            }
            catch (Exception e)
            {
                return BadRequest(e.StackTrace);
            }
        }
    }
    public class IdCode
    {
        public string id { get; set; }
        public string code { get; set; }
    }
}
