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.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",
            "tmdid":"分享给谁，邀请谁的tmdid",
            "name":"分享给谁，邀请谁的name",
            "sid":"课纲的id",
            "scode":"课纲册别的分区键",
            "sname":"课纲分享节点的名称",
            "coedit":true,
            "share":true,
            "issuer":"权限颁发者tmdid",
            "snodes":["分享的节点 all 或者節點id"]
        }
         */

        /// <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"))
                {
                    Volume volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>(request.sid, new PartitionKey(request.scode));
                    if (request.opt == "del")
                    {
                        if (volume.auth.IsNotEmpty())
                        {
                            var del = volume.auth.Where(x => x.tmdid == request.tmdid).FirstOrDefault();
                            volume.auth.Remove(del);
                            await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Volume>(volume, request.sid, new PartitionKey(request.scode));
                            await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Share>(request.sid, new PartitionKey($"Share-{request.tmdid}"));
                        }
                    }
                    else if (request.opt.Equals("add") || request.opt.Equals("edit"))
                    {
                        (Volume vlm, Share share) = DoAuth(request, volume);
                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Share>(share, new PartitionKey($"Share-{request.tmdid}"));
                        await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<Volume>(volume, new PartitionKey(request.scode));
                    }
                }
                else if (request.scope.Equals("private"))
                {
                    Volume volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>(request.sid, new PartitionKey(request.scode));
                    if (request.opt == "del")
                    {
                        if (volume.auth.IsNotEmpty())
                        {
                            var del = volume.auth.Where(x => x.tmdid == request.tmdid).FirstOrDefault();
                            volume.auth.Remove(del);
                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Volume>(volume, request.sid, new PartitionKey(request.scode));
                            await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<Share>(request.sid, new PartitionKey($"Share-{request.tmdid}"));
                        }
                    }
                    else if (request.opt.Equals("add") || request.opt.Equals("edit"))
                    {
                        (Volume vlm, Share share) = DoAuth(request, volume);
                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Share>(share, new PartitionKey($"Share-{request.tmdid}"));
                        await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Volume>(volume, new PartitionKey(request.scode));
                    }
                }
                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 (Volume,Share) DoAuth(ShareData request,Volume volume) {
            long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var share = new Share
            {
                id = request.sid,
                code = $"Share-{request.tmdid}",
                pk = "Share",
                ttl = -1,
                scode = request.scode,
                issuer = request.issuer,
                createTime = now,
                school = request.school,
                scope = request.scope,
                coedit=request.coedit,
                share=request.share,
                sname=request.sname
            };
            if (volume.auth.IsNotEmpty())
            {
                bool flag = false;
                int indx = 0;
                for (int index = 0; index < volume.auth.Count; index++)
                {
                    if (volume.auth[index].tmdid == request.tmdid)
                    {
                        flag = true;
                        indx = index;
                        break;
                    }
                }
                ///更新位置上的授权信息
                if (flag)
                {
                    volume.auth[indx] = new SyllabusAuth
                    {
                        tmdid = request.tmdid,
                        name = request.name,
                        coedit = request.coedit,
                        share = request.share,
                        snodes = request.snodes
                    };
                }
                //新增
                else
                {
                    volume.auth.Add(new SyllabusAuth
                    {
                        tmdid = request.tmdid,
                        name = request.name,
                        coedit = request.coedit,
                        share = request.share,
                        snodes = request.snodes
                    });
                }
            }
            else
            {
                volume.auth = new List<SyllabusAuth>() {
                    new SyllabusAuth {
                        tmdid=request.tmdid,
                        name=request.name,
                        coedit=request.coedit,
                        share=request.share,
                        snodes=request.snodes
                    }
                };
            }
            return (volume, share);
        }
        /// <summary>
        /// {"code":"教师编码"} 
        /// 教师拉取自己收到的分享及共编
        /// </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(); }
                var client = _azureCosmos.GetCosmosClient();

                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Share>(queryText: $"select value(c) from c ",
                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Share-{code}") }))
                {
                    shares.Add(item);
                }
                return Ok(new { shares = shares });
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，teacher/share/find()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }

        }
        /*
            {
                "scope": "school/private",
                "school": "学校编码",
                "issuer": "权限颁发者",
                "id": "分享或共编的id",
                "code": "分享或共编的分区键",
                "scode": "分享或共编的scode"
            }
         */
        /// <summary>
        /// 查看分享
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("view")]
       // [AuthToken(Roles = "Teacher")]
        public async Task<IActionResult> View(Share request)
        {
            try
            {
                //var (id, _, _, school) = HttpContext.GetAuthTokenInfo();
                //if (!request.code.Equals($"Share-{id}"))
                //{
                //    return BadRequest();
                //}
                Syllabus syllabus;
                Volume volume;
                var client = _azureCosmos.GetCosmosClient();
                string code = null;
                if (request.scope == "school")
                {
                    code = request.school;
                    syllabus = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(request.id, new PartitionKey(request.scode));
                    volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>(request.id, new PartitionKey($"Volume-{code}"));
                }
                else if (request.scope == "private")
                {
                    code = request.issuer;
                    syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(request.id, new PartitionKey(request.scode));
                    volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>(request.id, new PartitionKey($"Volume-{code}"));
                }
                else
                {
                    return BadRequest();
                }
                bool coedit = false;
                bool share = false;
                SyllabusTreeNode  etree = null;
                List<string> snodes = null;
                if (volume.auth.IsNotEmpty()) {
                    foreach (var x in volume.auth) {
                        if ($"Share-{x.tmdid }" == request.code)
                        {
                            coedit = x.coedit;
                            share = x.share;
                            snodes = x.snodes;
                            break;
                        }
                    }
                }
                if (coedit)
                {
                    var treechd = SyllabusService.ListToTree(syllabus.children);
                    etree = new SyllabusTreeNode() {
                        id = syllabus.id,
                        trees = treechd
                    };
                }
                SyllabusTreeNode stree = new SyllabusTreeNode();
                if (share && snodes.IsNotEmpty()) {
                    stree = new SyllabusTreeNode()
                    {
                        id = syllabus.id,
                    };
                    snodes.ForEach(x => {
                        SyllabusTree syllabusTree = null;
                        foreach (var node in syllabus.children) {
                            if (node.id == x) {
                                syllabusTree = new SyllabusTree { 
                                    id=node.id,
                                    pid=node.pid,
                                    order=node.order,
                                    rnodes=node.rnodes,
                                    cids=node.cids
                                };
                                break;
                            }
                        }
                        HashSet<Tnode> newNodes = new HashSet<Tnode>();
                        SyllabusService.GetNewNode(syllabus.children, x, newNodes);
                        var trees = SyllabusService.ListToTree(newNodes.ToList());
                        if (syllabusTree != null) {
                            syllabusTree.children.AddRange(trees);
                            stree.trees.Add(syllabusTree);
                        }
                    });
                }
                return Ok(new { coedit, share, etree,stree });
            }
            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();

        }
    }
}
