using Azure;
using Azure.Cosmos;
using Azure.Storage.Blobs;
using HTEXLib.COMM.Helpers;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos.Common;

namespace TEAMModelOS.Services.Common
{
    public static class BlobService
    {
        public static async Task<UsedBlob> GetBlobUsed(CosmosClient clientc, BlobContainerClient clients, IDatabase clientr, string scope, string containerName)
        {
            UsedBlob result = new UsedBlob();
            try
            {
                //学校已经分配给所有教师的空间大小GB。
                long teach = 0;
                if (scope.Equals("school"))
                {
                    await foreach (var item in clientc.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ",
                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{containerName}") }))
                    {
                        var json = await JsonDocument.ParseAsync(item.ContentStream);
                        foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
                            {
                                teach = _size.GetInt32();
                                break;
                            }
                        }
                    }
                }
                //使用blob狀況
                bool getBlobCatalogFromBlob = false; //是否直接去blob取得使用狀況 false:否(Redis)  true:是(Blob)
                long blobsize = 0;
                RedisValue value = default;
                value = clientr.HashGet($"Blob:Record", containerName);
                if (value != default && !value.IsNullOrEmpty)
                {
                    JsonElement record = value.ToString().ToObject<JsonElement>();
                    if (record.TryGetInt64(out blobsize))
                    {
                    }
                    else
                    {
                        getBlobCatalogFromBlob = true;
                    }
                }
                else
                {
                    getBlobCatalogFromBlob = true;
                }
                Dictionary<string, double?> catalog = new Dictionary<string, double?>();
                SortedSetEntry[] Scores = clientr.SortedSetRangeByScoreWithScores($"Blob:Catalog:{containerName}");
                if (Scores != null)
                {
                    foreach (var score in Scores)
                    {
                        double val = score.Score;
                        string key = score.Element.ToString();
                        catalog.Add(key, val);
                    }
                }
                if (!getBlobCatalogFromBlob)
                {
                    result.size = blobsize;
                    result.catalog = catalog;
                    result.teach = teach;
                    return result;
                }
                else
                {
                    var size = await clients.GetBlobsCatalogSize();
                    result.size = size.Item1;
                    result.catalog = size.Item2;
                    result.teach = teach;
                    return result;
                }
            }
            catch (Exception ex)
            {
                //await _dingDing.SendBotMsg($"CoreAPI2，{_option.Location}，Channel/Create()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return result;
            }
        }

        /// <param name="scope">school or private</param>
        /// <param name="containerName">school code or tmid</param>
        /// <param name="type">doc, res, item... Empty if no need.</param>
        /// <param name="periodId">Only for school</param>
        public static async Task<List<BlobCount>> BloblogCount(CosmosClient clientc, string scope, string containerName, string type, string periodId)
        {
            List<BlobCount> bloblogcnt = new List<BlobCount>();
            try
            {
                //必須項檢查
                if(scope.Equals("school") && string.IsNullOrWhiteSpace(periodId))
                {
                    return bloblogcnt;
                }
                //資料取得
                var queryslt = new StringBuilder();
                queryslt.Append($"SELECT COUNT(1) AS count, c.type FROM c ");
                if (scope.Equals("school"))
                {
                    queryslt.Append($"JOIN A1 IN c.periodId WHERE A1 IN ('{periodId}') ");
                    if(!string.IsNullOrWhiteSpace(type)) queryslt.Append($"AND c.type='{type}'");
                    queryslt.Append("GROUP BY c.type");
                   await foreach (var item in clientc.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<BlobCount>(queryText: queryslt.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Bloblog-{containerName}") }))
                    {
                        bloblogcnt.Add(item);
                    }
                }
                else if (scope.Equals("private"))
                {
                    if (!string.IsNullOrWhiteSpace(type)) queryslt.Append($"AND c.type='{type}'");
                    queryslt.Append("GROUP BY c.type");
                    await foreach (var item in clientc.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<BlobCount>(queryText: queryslt.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Bloblog-{containerName}") }))
                    {
                        bloblogcnt.Add(item);
                    }
                }

                return bloblogcnt;
            }
            catch (Exception ex)
            {
                return bloblogcnt;
            }
        }

        public class UsedBlob
        {
            public long teach { get; set; }
            public long? size { get; set; }
            public Dictionary<string, double?> catalog { get; set; }

        }

        public class BlobCount
        {
            public string type { get; set; }
            public int count { get; set; }
        }
    }
}
