using Azure.Cosmos;
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;

namespace TEAMModelOS.Controllers.Core
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    [Route("open-api")]
    [ApiController]
    public class OpenApiController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly AzureStorageFactory _azureStorage;
        private readonly AzureRedisFactory _azureRedis;
        private readonly DingDing _dingDing;
        private readonly Option _option;
        public OpenApiController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, DingDing dingDing, IOptionsSnapshot<Option> option) {

            _azureCosmos = azureCosmos;
            _azureStorage = azureStorage;
            _azureRedis = azureRedis;
            _dingDing = dingDing;
            _option = option?.Value;
        }
        /// <summary>
        /// {"code":"hbcn学校编码"} 
        /// </summary>
        /// <param name="requert"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "admin")]
        [HttpPost("find-app")]
        public async Task<IActionResult> FindApp(JsonElement request)
        {
            try
            {
                if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
                var client = _azureCosmos.GetCosmosClient();
                List<OpenApp> apps = new List<OpenApp>();
                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<OpenApp>(queryText: $"select value(c) from c ",
                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"OpenApp-{code}") }))
                {
                    apps.Add(item);
                }
                return Ok(new { apps });

            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，open-api/find-app()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }



        /*
         数据实例
         {}
         */
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
      //  [AuthToken(Roles = "admin")]
        [HttpPost("get")]
        public async Task<IActionResult> Get(JsonElement json) {
            List<OpenApi> apis = await _azureStorage.FindListByDict<OpenApi>(new Dictionary<string, object>() { { "PartitionKey", "IES5-API" } });
            return Ok(new { apis });
        }
        /*
        {
           "id": "4a54e95e-ef13-46ec-91ac-e55919d09f9e", //新增没有id  ,更新带id  
           "code":"hbcn",√
           "pk":"OpenApp",
           "name":"醍摩豆接入紫藤课纲应用",√
           "descr":"xxxxxx",√
           "auths":[1,2,3,4],√
           "school":"hbcn",√
           "token":null,
           "status":1√
       }
        */
        /// <summary>
        /// {
        ///   
        /// }
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "Teacher")]
        [HttpPost("upsert-app")]
        public async ValueTask<IActionResult> Upsert(OpenApp request)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                request.pk = "OpenApp";
                request.code = request.pk + "-" + request.code;
                request.ttl = -1;
                if (string.IsNullOrEmpty(request.id))
                {
                    request.id = Guid.NewGuid().ToString();
                    request = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request, new PartitionKey($"{request.code}"));
                }
                else
                {
                    var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(request.id, new PartitionKey($"{request.code}"));
                    if (response.Status == 200)
                    {
                        using var json = await JsonDocument.ParseAsync(response.ContentStream);
                        var info = json.ToObject<OpenApp>();
                        request.token = info.token;
                        request = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(request, info.id, new PartitionKey($"{info.code}"));
                    }
                    else
                    {
                        request = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request, new PartitionKey($"{request.code}"));
                    }
                }
                return Ok(new { app = request });
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，open-api/upsert()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }


        /// <summary>
        /// {"id":"uuid","code":"hbcn学校编码"} 
        /// </summary>
        /// <param name="requert"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        //[AuthToken(Roles = "admin")]
        [HttpPost("create-token")]
        public async Task<IActionResult> CreateToken(JsonElement request) {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //id
                if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
                //
                if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
                var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(id.GetString(), new PartitionKey($"OpenApp-{code}")) ;
                if (response.Status == 200)
                {
                    using var json = await JsonDocument.ParseAsync(response.ContentStream);
                    var info = json.ToObject<OpenApp>();
                    //创建Token
                    //域名  应用的id, jwtkey  学校编码
                    var auth_token = JwtAuthExtension.CreateApiToken(_option.HostName, info.id, _option.JwtSecretKey,info.name, info.auths, info.school);
                    info.token = auth_token;
                    info = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(info, info.id, new PartitionKey($"{info.code}"));
                    return Ok(new { auth_token });
                }
                else
                {
                    return BadRequest();
                }
            }
            catch (Exception e)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，open-api/upsert()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }


       

        
        /// <summary>
        /// {"id":"id","code":"hbcn"} 
        /// </summary>
        /// <param name="requert"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("delete-app")]
        public async Task<IActionResult> Delete(JsonElement requert)
        {
            try
            {
                var client = _azureCosmos.GetCosmosClient();
                //id
                if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
                //
                if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
                var room = await client.GetContainer("TEAMModelOS", "School").DeleteItemAsync<Room>(id.GetString(), new PartitionKey($"OpenApp-{code}"));
                return Ok();
            }
            catch (Exception ex)
            {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，open-api/delete-app()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
        }
    }
}
