using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using TEAMModelOS.SDK;

using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
using System;
using TEAMModelOS.SDK.Helper.Common.JsonHelper;
using System.Linq;
using TEAMModelOS.Models;
using System.Text.Json;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models;
using Microsoft.AspNetCore.Http;
using TEAMModelOS.SDK.Models.Cosmos.Common;
using Azure.Cosmos;
using TEAMModelOS.Services.Common;
using Microsoft.Extensions.Options;

namespace TEAMModelOS.Controllers
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("common/syllabus")]
    [ApiController]
    //[Authorize]
    public class SyllabusController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly Option _option;
        private readonly DingDing _dingDing;
        public SyllabusController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
        {
            _azureCosmos = azureCosmos;
            _dingDing = dingDing;
            _option = option?.Value;
        }
        /*
         [
            {
                "id": "章节id",
                "volumeId": "册别id",
                "scope": "school",
                "trees": [
                    {
                        "id": "b2b15c99-83cc-eca7-5b4b-e58d2a457c8e",
                        "pid": "0baf00db-0768-4b62-a8f7-280f6bcebf71",
                        "title": "第一单元",
                        "type": 1,
                        "children": []
                    }
                ]
            }
        ]
         */
        /// <summary>
        /// 批量保存或更新课纲
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("upsert-tree")]
        public async Task<IActionResult> SaveOrUpdateAsTree(List<SyllabusTreeNode> request)
        {
            foreach (SyllabusTreeNode syllabusTree in request) {
                List<Tnode> nodes = new List<Tnode>();
                SyllabusService.TreeToList(syllabusTree.trees, nodes);
                if (!string.IsNullOrEmpty(syllabusTree.id))
                {
                    Syllabus syllabus = null;
                    if (syllabusTree.scope == "school")
                    {
                        try
                        {
                            syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }
                        catch
                        {
                        }
                        if (syllabus == null)
                        {
                            syllabus = new Syllabus();
                            syllabus.id = syllabusTree.id;
                            syllabus.children = nodes;
                            syllabus.code = $"Syllabus-{syllabusTree.volumeId}";
                            syllabus.pk = "Syllabus";
                            syllabus.ttl = -1;
                            syllabus.volumeId = syllabusTree.volumeId;
                            syllabus.scope = syllabusTree.scope;
                            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }
                        else
                        {
                            syllabus.children = nodes;
                            syllabusTree.auth = syllabus.auth;
                            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Syllabus>(syllabus,syllabus.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }

                    }
                    else {
                        try
                        {
                            syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }
                        catch
                        {
                        }
                        if (syllabus == null)
                        {
                            syllabus = new Syllabus();
                            syllabus.id = syllabusTree.id;
                            syllabus.children = nodes;
                            syllabus.code = $"Syllabus-{syllabusTree.volumeId}";
                            syllabus.pk = "Syllabus";
                            syllabus.ttl = -1;
                            syllabus.volumeId = syllabusTree.volumeId;
                            syllabus.scope = syllabusTree.scope;
                            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }
                        else
                        {
                            syllabus.children = nodes;
                            syllabusTree.auth = syllabus.auth;
                            await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                        }
                    }
                }
                else {
                    string id = Guid.NewGuid().ToString();
                    syllabusTree.id = id;
                    Syllabus syllabus = new Syllabus {
                        id = id,
                        code = $"Syllabus-{syllabusTree.volumeId}",
                        pk = "Syllabus",
                        ttl = -1,
                        volumeId=syllabusTree.volumeId,
                        children=nodes,
                        scope = syllabusTree.scope
                    };
                    if (syllabusTree.scope == "school") {
                        await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                    } else {
                        await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.volumeId}"));
                    }
                }
            }
            return Ok(request);
        }

        /*
            {"volumeId":"册别id：0baf00db-0768-4b62-a8f7-280f6bcebf71","scope":"school","volumeCode":"册别分区键"}
         */
        /// <summary>
        /// 查找课纲 
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find-id")]
        public async Task<IActionResult> Find(JsonElement request)
        {
            var client = _azureCosmos.GetCosmosClient();
            if (!request.TryGetProperty("volumeId", out JsonElement volumeId)) return BadRequest();
            if (!request.TryGetProperty("volumeCode", out JsonElement volumeCode)) return BadRequest();
            if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
            Volume volume = null;
            List<SyllabusTreeNode> treeNodes = new List<SyllabusTreeNode>();
            List<SyllabusTreeNode> redt = new List<SyllabusTreeNode>();
            try {
                if (scope.ToString().Equals("school"))
                {
                      volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
                      await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c ",
                    requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{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);
                    }
                }
                else
                {
                    volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c ",
                     requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{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);
                    }
                }
                if (volume.syllabusIds.IsNotEmpty())
                {
                    volume.syllabusIds.ForEach(x =>
                    {
                        for (int index = 0; index < treeNodes.Count; index++)
                        {
                            if (treeNodes[index].id == x)
                            {
                                redt.Add(treeNodes[index]);
                                treeNodes.RemoveAt(index);
                            }
                        }
                    });
                    redt.AddRange(treeNodes);
                    return Ok(new { tree = redt });
                }
                else {
                    return Ok(new { tree = treeNodes });
                }
               
            } catch (Exception ex) {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，common/syllabus/find-id\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
                return Ok(new { tree= treeNodes });
            }
        }

        /*
            {"id":"章节id","code":"册别id","scope":"school/private"}
         */

        /// <summary>
        /// 删除章节
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("delete")]
        public async Task<IActionResult> Delete(JsonElement request)
        {
            try
            {
                if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
                if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
                if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
                var client = _azureCosmos.GetCosmosClient();
                if (scope.ToString().Equals("school"))
                {
                    var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
                    return Ok(new { code = response.Status });
                }
                else
                {
                    var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
                    return Ok(new { code = response.Status });
                }
            }
            catch {
                return Ok(new { code = 404});
            }
        }
    }
}