using Azure.Cosmos;
using HTEXLib.COMM.Helpers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Filter;
using TEAMModelOS.Models;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using TEAMModelOS.Services.Common;

namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("teacher/share")]
    [ApiController]
    public class ShareController: ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly SnowflakeId _snowflakeId;
        private readonly DingDing _dingDing;
        private readonly Option _option;

        public ShareController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
        {
            _azureCosmos = azureCosmos;
            _snowflakeId = snowflakeId;
            _dingDing = dingDing;
            _option = option?.Value;
        }
        /*
         {
            "school": "学校编码",
            "scope":"school|private",
            "tmdInfo":["tmdid":"id1","tmdname":"name1"],
            "coedit":true,
            "share":true,
            "issuer":"权限颁发者tmdid",
            "opt":"add/del/edit"
            "syllabusId":"分享的课纲章节id",
            "syllabusName":"章节名称",
            "volumeId":"册别id",
            "volumeName":"册别name"
        }
         */

        /// <summary>
        /// 分享及邀请共编，并设置TTL过期时间
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("to")]
       // [AuthToken(Roles = "Teacher")]
        public async Task<IActionResult> To(ShareData request) {
            // var (id, _, _, _) = HttpContext.GetAuthTokenInfo();

            try {
                var client = _azureCosmos.GetCosmosClient();
                //需要判断id== req.issuer  才能进行授权操作
                if (request.scope.Equals("school"))
                {
                    Syllabus syllabusD = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(request.syllabusId, new PartitionKey($"Syllabus-{request.volumeId}"));
                    if (request.opt == "del")
                    {
                        if (syllabusD.auth.IsNotEmpty())
                        {
                            List<SyllabusAuth> syllabusAuths = new List<SyllabusAuth>();
                            syllabusD.auth.ForEach(x=> {
                                if (request.tmdInfo.Select(tmd=>tmd.tmdid).Contains(x.tmdid)) {
                                    syllabusAuths.Add(x);
                                }   
                            }) ;
                            syllabusAuths.ForEach(x => {
                                syllabusD.auth.Remove(x);
                            });
                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Syllabus>(syllabusD, request.volumeId, new PartitionKey($"Syllabus-{request.volumeId}"));
                            request.tmdInfo.ForEach(async x => {
                                await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Share>(request.syllabusId, new PartitionKey($"Share-{x.tmdid}"));
                            });
                            
                        }
                    }
                    else if (request.opt.Equals("add") || request.opt.Equals("edit"))
                    {
                        (Syllabus syllabus, List<Share> shares) = DoAuth(request, syllabusD);
                        shares.ForEach(async x=> {
                            await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Share>(x, new PartitionKey($"Share-{x.code}"));
                        });
                       
                        await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<Syllabus>(syllabus, new PartitionKey($"Syllabus-{request.volumeId}"));
                    }
                }
                else if (request.scope.Equals("private"))
                {
                    Syllabus syllabusD = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(request.syllabusId, new PartitionKey($"Syllabus-{request.volumeId}"));
                    if (request.opt == "del")
                    {
                        if (syllabusD.auth.IsNotEmpty())
                        {
                            List<SyllabusAuth> syllabusAuths = new List<SyllabusAuth>();
                            syllabusD.auth.ForEach(x => {
                                if (request.tmdInfo.Select(tmd=>x.tmdid).Contains(x.tmdid))
                                {
                                    syllabusAuths.Add(x);
                                }
                            });
                            syllabusAuths.ForEach(x => {
                                syllabusD.auth.Remove(x);
                            });
                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Syllabus>(syllabusD, request.syllabusId, new PartitionKey($"Syllabus-{request.volumeId}"));
                            request.tmdInfo.ForEach(async x => {
                                await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Share>(request.syllabusId, new PartitionKey($"Share-{x.tmdid}"));
                            });
                        }
                    }
                    else if (request.opt.Equals("add") || request.opt.Equals("edit"))
                    {
                        (Syllabus vlm, List<Share> shares) = DoAuth(request, syllabusD);
                        shares.ForEach(async x => {
                            await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Share>(x, new PartitionKey($"Share-{x.code}"));
                        });
                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabusD, new PartitionKey($"Syllabus-{request.volumeId}"));
                    }
                }
                return Ok(new { code=200});
            }
            catch (Exception ex ) {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，teacher/share/to\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
            }
            return Ok(new { code = 500 });
        }

        private (Syllabus, List<Share>) DoAuth(ShareData request, Syllabus syllabus)
        {
            long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            List<Share> shares = new List<Share>();
            request.tmdInfo.ForEach(xmd => {
                var share = new Share
                {
                    id = request.syllabusId,
                    volumeId = request.volumeId,
                    volumeName = request.volumeName,
                    syllabusName = request.syllabusName,
                    code = $"Share-{xmd.tmdid}",
                    pk = "Share",
                    ttl = -1,
                    issuer = request.issuer,
                    createTime = now,
                    school = request.school,
                    scope = request.scope,
                    coedit = request.coedit,
                    share = request.share
                };
                shares.Add(share);
            });
            
            if (syllabus.auth.IsNotEmpty())
            {
                request.tmdInfo.ForEach(xmd => {

                    bool flag = false;
                    int indx = 0;
                    for (int index = 0; index < syllabus.auth.Count; index++)
                    {
                        if (syllabus.auth[index].tmdid == xmd.tmdid)
                        {
                            flag = true;
                            indx = index;
                            break;
                        }
                    }
                    ///更新位置上的授权信息
                    if (flag)
                    {
                        syllabus.auth[indx] = new SyllabusAuth
                        {
                            tmdid = xmd.tmdid,
                            tmdname = xmd.tmdname,
                            coedit = request.coedit,
                            share = request.share,
                        };
                    }
                    //新增
                    else
                    {
                        syllabus.auth.Add(new SyllabusAuth
                        {
                            tmdid = xmd.tmdid,
                            tmdname = xmd.tmdname,
                            coedit = request.coedit,
                            share = request.share,
                        });
                    }
                });
            }
            else
            {
                request.tmdInfo.ForEach(xmd => {
                    syllabus.auth = new List<SyllabusAuth>() {
                        new SyllabusAuth {
                            tmdid = xmd.tmdid,
                            tmdname = xmd.tmdname,
                            coedit=request.coedit,
                            share=request.share,
                        }
                    };
                });
            }
            return (syllabus, shares);
        }



        /// <summary>
        /// {"code":"教师编码","type":"coedit/share"} 
        /// 教师拉取自己收到的分享及共编
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find")]
       // [AuthToken(Roles = "Teacher")]
        public async Task<IActionResult> Find(JsonElement request)
        {
            try
            {
                List<Share> shares = new List<Share>();
                if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
                if (!request.TryGetProperty("type", out JsonElement type)) { return BadRequest(); }
                if (!request.TryGetProperty("id", out JsonElement id)) { return BadRequest(); }
                var client = _azureCosmos.GetCosmosClient();
                StringBuilder queryText = new StringBuilder("select value(c) from c");
                if (type.ValueKind.Equals(JsonValueKind.String) && type.GetString() == "coedit")
                {
                    queryText.Append(" where c.coedit=true");
                }
                else if (type.ValueKind.Equals(JsonValueKind.String) && type.GetString() == "share")
                {
                    queryText.Append(" where c.share=true");
                }
                else {
                    await _dingDing.SendBotMsg($"OS，{_option.Location}，teacher/share/find()\n type== coedit|share 参数必选一个", GroupNames.醍摩豆服務運維群組);
                    return BadRequest();
                }
                if (id.ValueKind.Equals(JsonValueKind.String) && !string.IsNullOrEmpty(id.GetString())) {
                    queryText.Append($" and c.id='{id}'");
                }
                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Share>(queryText: queryText.ToString(),
                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Share-{code}") }))
                {
                    shares.Add(item);
                }
                var sharesGp  =  shares.GroupBy(x => new {id= x.volumeId ,code=x.scope=="school"?x.school:x.issuer}).Select(y=>new { id=y.Key.id,code=y.Key.code,list=y.ToList()});
                return Ok(new { shares = sharesGp });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，teacher/share/find()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }

        public record ShareView
        {
            public string scope { get; set; }
           // public string code { get; set; }
            public string school { get; set; }
            public string issuer { get; set; }
            public string volumeId { get; set; }
            public List<string> syllabusId { get; set; }
        }

        /*
            {
                "scope": "school/private",
                "school": "学校编码",
                "issuer": "权限颁发者",
                "volumeId": "册别id",
                "syllabusId": ["id1课纲章节节点id","id2课纲章节节点id"],
            }
         */
        /// <summary>
        /// 查看分享
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("view-share")]
       // [AuthToken(Roles = "Teacher")]
        public async Task<IActionResult> View(ShareView request)
        {
            try
            {
                List<SyllabusTreeNode> treeNodes = new List<SyllabusTreeNode>();
                Volume volume;
                var client = _azureCosmos.GetCosmosClient();
                string code = null;
                List<string> sid = new List<string>();
                request.syllabusId.ForEach(x => { sid.Add($"'{x}'"); });
                var sidSql= string.Join(",", sid);
                if (request.scope == "school")
                {
                    code = request.school;
                    var queryslt = $"SELECT  value(c) FROM c where c.id in ({sidSql})";
                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Syllabus>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{request.volumeId}") }))
                    {
                        List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
                        SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth };
                        treeNodes.Add(tree);

                    }
                    volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>(request.volumeId, new PartitionKey($"Volume-{code}"));
                    
                }
                else if (request.scope == "private")
                {
                    code = request.issuer;
                    var queryslt = $"SELECT  value(c) FROM c where c.id in ({sidSql})";
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Syllabus>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{request.volumeId}") }))
                    {
                        List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
                        SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth };
                        treeNodes.Add(tree);
                    }
                    volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>(request.volumeId, new PartitionKey($"Volume-{code}"));
                }
                else
                {
                    return BadRequest();
                }
                
                return Ok(new { volume,tree= treeNodes });
            }
            catch (Exception ex) {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，teacher/share/view()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }
        /// <summary>
        ///二维码扫码方式
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("qrcode")]
        //[AuthToken(Roles = "Teacher")]
        public async Task<IActionResult> Qrcode(Favorite request)
        {
            return Ok();
        }
    }
   
}
