using Azure.Cosmos;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Models.Dto;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK;
using TEAMModelOS.SDK.Context.Constant.Common;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Helper.Common.CollectionHelper;

namespace TEAMModelOS.Controllers
{
    /// <summary>
    /// 投票活动
    /// </summary>
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("common/survey")]
    [ApiController]
    public class SurveyController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly SnowflakeId _snowflakeId;
        private readonly AzureServiceBusFactory _serviceBus;
        public SurveyController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId)
        {
            _snowflakeId= snowflakeId;
            //  _timerWorkService = timerWorkService;
            _serviceBus = serviceBus;
              _azureCosmos = azureCosmos;
        }

        /// <summary>
        /// 新增 或 修改投票活动
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("upsert")]
        public async Task<IActionResult> Upsert(SurveyDto request)
        {
            //ResponseBuilder builder = ResponseBuilder.custom();
            //新增
            //string code = request.survey.code;
            var client = _azureCosmos.GetCosmosClient();
            Survey survey;            
            request.survey.school = request.survey.code;
            request.survey.code =  "Survey-" + request.survey.code;
            request.survey.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            /*if (request.survey.publishModel.Equals("0"))
            {
                //request.survey.startTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                request.survey.progress = "going";
            }
            else if (request.survey.publishModel.Equals("1"))
            {

                string msgId = _snowflakeId.NextId() + "";
                long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime, "going", msgId);
                request.survey.sequenceNumber = SequenceNumber;

            }*/
            if (string.IsNullOrEmpty(request.survey.id))
            {
                request.survey.id = Guid.NewGuid().ToString();
                //request.survey.status = 100;
                request.survey.progress = "pending";
                //await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName, info.sequenceNumber);
               /* long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime);
                request.survey.sequenceNumber = SequenceNumber;*/
                survey = await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(request.survey, new PartitionKey($"{request.survey.code}"));
                /*if (request.survey.scope.Equals("school"))
                {
                    survey = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(request.survey, new PartitionKey($"Survey-{code}"));
                }
                else
                {
                    survey = await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(request.survey, new PartitionKey($"Survey-{code}"));
                }*/
                //await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.id, request.code, request.startTime);

            }
            else {
                Survey info = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Survey>(request.survey.id, new PartitionKey($"{request.survey.code}"));
                if (info.progress.Equals("going"))
                {
                    return Ok(new { v = "活动正在进行中" });
                }
                //request.survey.code = info.code;
                request.survey.progress = info.progress;
                /*try {
                    await _serviceBus.GetServiceBusClient().cancelMessage(Constants.TopicName, info.sequenceNumber);
                    long SequenceNumber = await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.startTime);
                    request.survey.sequenceNumber = SequenceNumber;
                } catch (Exception e) {
                    return BadRequest();
                    //await _dingDing.SendBotMsg($"ServiceBusㄛExamBus()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
                }        */       
                
                survey = await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(request.survey, info.id, new PartitionKey($"{info.code}"));
                //request.survey.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                /*if (request.survey.scope.Equals("school"))
                {
                    survey = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(request.survey, request.survey.id, new PartitionKey($"{request.survey.code}"));
                }
                else
                {
                    survey = await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(request.survey, request.survey.id, new PartitionKey($"{request.survey.code}"));
                }*/


            }            
            //Survey homeWork = await _azureCosmos.SaveOrUpdate<Survey>(request.survey);

            //设定结束时间
            //await _serviceBus.GetServiceBusClient().SendLeamMessage<Survey>(Constants.TopicName, request.survey.id, request.survey.code, request.survey.endTime);

            //清除作业
            /*if (!request.reset)
            {
                //查询之前是否有 关联关系表 HomeWorkStudent 有则删除
                List<SurveyRecord> surveyRecords = await _azureCosmos.FindByDict<SurveyRecord>(new Dictionary<string, object> { { "id", request.survey.id } });
                if (surveyRecords.IsNotEmpty())
                {
                    await _azureCosmos.DeleteAll(surveyRecords);
                }

                ////根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
                //List<Target> targets = request.@params.survey.target;
                //List<SurveyRecord> surveykStudents = new List<SurveyRecord>();
                //foreach (Target target in targets)
                //{
                   
                //    List<ClassStudent> classroom = await azureCosmosDBV3Repository.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", target.classroomCode } });
                //    if (classroom.IsNotEmpty() && classroom[0].code != null)
                //    {
                //        foreach (ClassStudent student in classroom)
                //        {
                //            SurveyRecord surveyStudent = new SurveyRecord();
                //            surveyStudent.id = request.@params.survey.id;
                //            surveyStudent.code = student.code;
                //            surveyStudent.classroom.code = target.classroomCode;
                //            surveyStudent.classroom.name = target.classroomName;
                //            surveykStudents.Add(surveyStudent);
                //        }
                //    }
                //}
                //if (surveykStudents.IsNotEmpty())
                //{
                //    foreach (SurveyRecord surveyRecord in surveykStudents)
                //    {
                //        List<Student> student = await azureCosmosDBV3Repository.FindById<Student>(surveyRecord.code);
                //        if (student.IsNotEmpty())
                //        {
                //            surveyRecord.name = student[0].name;
                //            surveyRecord.code = student[0].TEAMModelId;
                //        }
                //    }
                //    await azureCosmosDBV3Repository.SaveOrUpdateAll(surveykStudents);
                //}
            }*/
            //return builder.Data(homeWork).build();
            return Ok(survey);
        }
        /// <summary>
        /// 查询投票活动
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find-summary")]
        public async Task<IActionResult> FindSummary(JsonElement requert)
        {

            var client = _azureCosmos.GetCosmosClient();
            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
            if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
            //var (id, name, picture, _) = HttpContext.GetAuthTokenInfo();
            List<object> surveys = new List<object>();
            StringBuilder sql = new StringBuilder();
            sql.Append("select c.id,c.code,c.name,c.startTime,c.endTime,c.description,c.progress from c ");
            Dictionary<string, object> dict = new Dictionary<string, object>();
            var emobj = requert.EnumerateObject();
            while (emobj.MoveNext())
            {
                dict[emobj.Current.Name] = emobj.Current.Value;
            }
            //处理code
            if (dict.TryGetValue("code", out object _))
            {
                dict.Remove("code");
            }
            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
            {
                using var json = await JsonDocument.ParseAsync(item.ContentStream);

                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                {
                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                    {
                        surveys.Add(obj.ToObject<object>());
                    }
                }
            }
            /*if (scope.ToString().Equals("school"))
            {
                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);

                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            surveys.Add(obj.ToObject<object>());
                        }
                    }
                }
            }
            else
            {
                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);

                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            surveys.Add(obj.ToObject<object>());
                        }
                    }
                }
            }*/

            return Ok(new { surveys, surveys.Count });
            /*ResponseBuilder builder = ResponseBuilder.custom();
            Dictionary<string, object> dict = new Dictionary<string, object>();
            var emobj = request.EnumerateObject();
            while (emobj.MoveNext())
            {
                dict[emobj.Current.Name] = emobj.Current.Value;
            }
            List<Survey> data = new List<Survey>();
            List<string> props = new List<string> { "id", "code", "name", "type", "status", "startTime" };
            if (dict.Keys.Count > 0)
            { 
                
                data = await _azureCosmos.FindByDict<Survey>(dict, props);
            }
            else
            {
                return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常！").build();

            }
            return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count },{ "props", props } }).build();*/
        }
        /// <summary>
        /// 查询投票活动
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find")]
        public async Task<IActionResult> Find(JsonElement requert)
        {
            var client = _azureCosmos.GetCosmosClient();
            if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
            if (!requert.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
            //var (id, name, picture, _) = HttpContext.GetAuthTokenInfo();
            List<object> surveys = new List<object>();
            StringBuilder sql = new StringBuilder();
            sql.Append("select c.id,c.code,c.name,c.questions,c.classes,c.startTime,c.endTime,c.description,c.progress,c.targetClassIds from c ");
            Dictionary<string, object> dict = new Dictionary<string, object>();
            var emobj = requert.EnumerateObject();
            while (emobj.MoveNext())
            {
                dict[emobj.Current.Name] = emobj.Current.Value;
            }
            //处理code
            if (dict.TryGetValue("code", out object _))
            {
                dict.Remove("code");
            }
            AzureCosmosQuery cosmosDbQuery = SQLHelper.GetSQL(dict, sql);
            await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
            {
                using var json = await JsonDocument.ParseAsync(item.ContentStream);

                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                {
                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                    {
                        surveys.Add(obj.ToObject<object>());
                    }
                }
            }
            /*if (scope.ToString().Equals("school"))
            {
                await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);

                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            surveys.Add(obj.ToObject<object>());
                        }
                    }
                }
            }
            else {
                await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryStreamIterator(queryDefinition: cosmosDbQuery.CosmosQueryDefinition, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
                {
                    using var json = await JsonDocument.ParseAsync(item.ContentStream);

                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                    {
                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                        {
                            surveys.Add(obj.ToObject<object>());
                        }
                    }
                }
            }*/


            return Ok(new { surveys, surveys.Count });
            /*ResponseBuilder builder = ResponseBuilder.custom();
            Dictionary<string, object> dict = new Dictionary<string, object>();
            var emobj = request.EnumerateObject();
            while (emobj.MoveNext())
            {
                dict[emobj.Current.Name] = emobj.Current.Value;
            }
            List<Survey> data = new List<Survey>();
            if (dict.Keys.Count > 0)
            {
                data = await _azureCosmos.FindByDict<Survey>(dict);
            }
            else
            {
                return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常！").build();

            }
            return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
        }

        /// <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();
                var response = await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                return Ok(new { code = response.Status });
                /*if (scope.ToString().Equals("school"))
                {
                    var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                    return Ok(new { code = response.Status });
                }
                else
                {
                    var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"{code}"));
                    return Ok(new { code = response.Status });
                }*/

            }
            catch (Exception e)
            {
                return BadRequest();
            }
            /* ResponseBuilder builder = ResponseBuilder.custom();
             List<IdPk> idPks = await _azureCosmos.DeleteAll<Survey>(request);
             if (idPks.IsNotEmpty())
             {
                 foreach (IdPk idPk in idPks)
                 {
                     List<SurveyRecord> surveys = await _azureCosmos.FindByDict<SurveyRecord>(new Dictionary<string, object> { { "id", idPk.id } });
                     await _azureCosmos.DeleteAll(surveys);
                 }
                 //builder.Data(idPks);
             }
             else
             {
                 return Ok("删除失败！");
                 //return builder.Error(ResponseCode.FAILED, "删除失败！").build();
             }
             return Ok(idPks);*/
            //return builder.build();
        }

        // TODO 代码优化

        /// <summary>
        /// 撤消问卷
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("cancel")]
        public async Task<IActionResult> Cancel(JsonElement request)
        {
            //request.TryGetProperty("id", out JsonElement surveyId);
            //ResponseBuilder builder = ResponseBuilder.custom();
            //List<Survey> surveys = await _azureCosmos.FindByDict<Survey>(new Dictionary<string, object> { { "id", surveyId } });

            //foreach (Survey survey in surveys)
            //{
            //    survey.status = 100;
            //    survey.progress = "pending";
            //}
            //List<Survey> survey1 = await _azureCosmos.UpdateAll<Survey>(surveys);

            ////查询之前是否有 关联关系表  有则删除
            //List<SurveyRecord> surveyStudents = await _azureCosmos.FindByDict<SurveyRecord>(new Dictionary<string, object> { { "id", surveyId } });
            //if (surveyStudents.IsNotEmpty())
            //{
            //    await _azureCosmos.DeleteAll(surveyStudents);
            //}
            return Ok();
        }

        /// <summary>
        /// 查询学生问卷调查记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("find-record")]
        public async Task<IActionResult> FindRecord(JsonElement requert)
        {
            var client = _azureCosmos.GetCosmosClient();
            if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
            //var (id, name, picture, _) = HttpContext.GetAuthTokenInfo();

            List<object> surveys = new List<object>();
            var query = $"select c.id,c.code,c.name,c.type,c.status,c.startTime from c where {id}";
            await foreach (var item in client.GetContainer("TEAMModelOS", "Student").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"SurveyRecord-{id}") }))
            {
                using var json = await JsonDocument.ParseAsync(item.ContentStream);

                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
                {
                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
                    {
                        surveys.Add(obj.ToObject<object>());
                    }
                }
            }

            return Ok(new { surveys, surveys.Count });
            /*ResponseBuilder builder = ResponseBuilder.custom();
            Dictionary<string, object> dict = new Dictionary<string, object>();
            var emobj = request.EnumerateObject();
            while (emobj.MoveNext())
            {
                dict[emobj.Current.Name] = emobj.Current.Value;
            }
            List<SurveyRecord> data = new List<SurveyRecord>();

            if (dict.Keys.Count > 0)
            {
                data = await _azureCosmos.FindByDict<SurveyRecord>(dict);
            }
            else
            {
                return builder.Error(ResponseCode.PARAMS_ERROR, "参数异常！").build();
            }
            return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();*/
        }        
         
    }
}