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;
using System.Text.Json;
using System.Threading.Tasks;
using TEAMModelOS.Models;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK;
using TEAMModelOS.SDK.Models;
using TEAMModelOS.SDK.Extension;
using static TEAMModelOS.Controllers.SchoolTeacherController;
using System.Dynamic;
using HTEXLib.COMM.Helpers;

namespace TEAMModelOS.Controllers.Research
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    //[Authorize(Roles = "IES5")]
    [Route("research/appraise")]
    [ApiController]
    public class AppraiseController : ControllerBase
    {
        private readonly AzureCosmosFactory _azureCosmos;
        private readonly SnowflakeId _snowflakeId;
        private readonly DingDing _dingDing;
        private readonly Option _option;
        public AppraiseController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option)
        {
            _azureCosmos = azureCosmos;
            _snowflakeId = snowflakeId;
            _dingDing = dingDing;
            _option = option?.Value; ;
        }
        /// <summary>
        ///课堂实录操作接口
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [ProducesDefaultResponseType]
        [HttpPost("opt")]
        public async Task<IActionResult> Opt(JsonElement request) {
            var client = _azureCosmos.GetCosmosClient();
            if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return BadRequest();
            if (!request.TryGetProperty("videoId", out JsonElement _videoId)) return BadRequest();
            if (!request.TryGetProperty("opt", out JsonElement _opt)) return BadRequest();
            string code = $"Appraise-{_tmdid}";
            
            try {
                switch (true)
                {
                    case bool when $"{_opt}".Equals("Score", StringComparison.OrdinalIgnoreCase):
                        if (!request.TryGetProperty("dimensions", out JsonElement _dimensions)) return BadRequest();
                        if (!request.TryGetProperty("commentTmdid", out JsonElement _scoreTmdid)) return BadRequest();
                        if (!request.TryGetProperty("score", out JsonElement _score)) return BadRequest();
                        if (!request.TryGetProperty("roleType", out JsonElement _roleType)) return BadRequest();
                        Appraise appraise = null;
                        bool isnew = false;
                        try
                        {
                            appraise = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Appraise>($"{_videoId}", new PartitionKey(code));
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Status == 404)
                            {
                                isnew = true;
                                appraise = new Appraise { id = $"{_videoId}", pk = "Appraise", code = code, ttl = -1, roles = new List<AppraiseRole> { new AppraiseRole { commentTmdid=$"{_scoreTmdid}", roleType = $"{_roleType}" } } };
                            }
                        }
                        List<AppraiseDimension> dimensions = _dimensions.ToObject<List<AppraiseDimension>>();
                        int score = -1;
                        if (int.TryParse($"{_score}", out int oscore))
                        {
                            score = oscore;
                        }
                        if ($"{_roleType}".Equals("school"))
                        {
                            //学校的身份不管是谁，只能以学校的身份进行一次评论
                            AppraiseRole schoolRole = appraise.roles.Find(x => x.roleType.Equals($"{_roleType}"));
                            if (schoolRole != null)
                            {
                                schoolRole.dimensions = dimensions;
                                schoolRole.score = score;
                            }
                            else
                            {
                                appraise.roles.Add(new AppraiseRole { commentTmdid = $"{_scoreTmdid}", roleType = $"{_roleType}", dimensions = dimensions, score = score, timeLines = new List<TimeLine>() });
                            }
                            if (!request.TryGetProperty("school", out JsonElement _school)) return BadRequest();
                            string videoCode = $"ClassVideo-{_school}";
                            ClassVideo classVideo = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<ClassVideo>($"{_tmdid}", new PartitionKey(videoCode));
                            if (classVideo.files.IsNotEmpty()) {
                                var video= classVideo.files.Find(x => x.id.Equals($"{_videoId}"));
                                video.score = score;
                                await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<ClassVideo>(classVideo,$"{_tmdid}", new PartitionKey(videoCode));
                            }
                        }
                        else
                        { //其他身份的同一个人可以以不同身份进行点评
                            AppraiseRole otherRole =appraise.roles.Find(x => x.commentTmdid.Equals($"{_scoreTmdid}") && x.roleType.Equals($"{_roleType}"));
                            if (otherRole != null) {
                                otherRole.dimensions = dimensions;
                                otherRole.score = score;
                            }
                            else
                            {
                                appraise.roles.Add(new AppraiseRole { commentTmdid = $"{_scoreTmdid}", roleType = $"{_roleType}", dimensions = dimensions, score = score, timeLines = new List<TimeLine>() });
                            }
                        }
                         
                        if (isnew)
                        {
                            await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Appraise>(appraise, new PartitionKey(code));
                        }
                        else {
                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Appraise>(appraise, appraise.id, new PartitionKey(code));
                        }
                        return Ok(new { dimensions, score });
                    case bool when $"{_opt}".Equals("Comment", StringComparison.OrdinalIgnoreCase):
                        if (!request.TryGetProperty("comment", out JsonElement _comment)) return BadRequest();
                        if (!request.TryGetProperty("roleType", out JsonElement _roleTypeComment)) return BadRequest();
                        if (!request.TryGetProperty("commentTmdid", out JsonElement _commentTmdid)) return BadRequest();
                        AppraiseComment comment = _comment.ToObject<AppraiseComment>();
                        if (string.IsNullOrEmpty(comment.atSchool) ||
                            string.IsNullOrEmpty(comment.atTmdid) ||
                            string.IsNullOrEmpty(comment.atTmdname) ||
                            string.IsNullOrEmpty(comment.videoName))
                        {
                            return BadRequest("parmas error!");
                        }
                        string debateCode = $"Debate-{comment.atSchool}";
                        Debate debate = null;
                        long nowTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                        try
                        {
                            debate = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_videoId}", new PartitionKey(debateCode));
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Status == 404)
                            {
                                debate = new Debate
                                {
                                    comid = $"{_videoId}",
                                    code=debateCode,
                                    id = $"{_videoId}",
                                    tmdid = $"{comment.atTmdid}",
                                    tmdname = $"{comment.atTmdname}",
                                    title = $"{comment.atTmdname}-{comment.videoName}",
                                    time = nowTime,
                                    comment = "",
                                    school = $"{comment.atSchool}",
                                    replies = new List<DebateReply>(),
                                    source = "classvideo",
                                    openType = 0,
                                    ttl = -1,
                                    pk = "Debate"
                                };
                                await client.GetContainer("TEAMModelOS", "School").CreateItemAsync<Debate>(debate, new PartitionKey(debateCode));
                            }
                        }
                        string replyId = Guid.NewGuid().ToString();
                        DebateReply reply = new DebateReply { id = replyId, tmdid = $"{_tmdid}", tmdname = comment.tmdname, atTmdid = comment.atTmdid, atTmdname = comment.atTmdname, pid = debate.id, comment = comment.content, time = nowTime };
                        if (debate.replies.IsNotEmpty())
                        {
                            debate.replies.Add(reply);
                        }
                        else
                        {
                            debate.replies = new List<DebateReply> { reply };
                        }
                        await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Debate>(debate, debate.id, new PartitionKey(debateCode));
                        TimeLine timeLine = new TimeLine { videoTime = comment.videoTime, tag = comment.tag, per = comment.per, replyId = replyId };
                        Appraise appraiseComment = null;
                        bool isnewComment = false;
                        try
                        {
                            appraiseComment = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Appraise>($"{_videoId}", new PartitionKey(code));
                        }
                        catch (CosmosException ex)
                        {
                            if (ex.Status == 404)
                            {
                                isnewComment = true;
                                appraiseComment = new Appraise { id = $"{_videoId}", pk = "Appraise", code = code, ttl = -1, roles = new List<AppraiseRole> { new AppraiseRole {commentTmdid=$"{_commentTmdid}", roleType = $"{_roleTypeComment}" } } };
                            }
                        }
                        if ($"{_roleTypeComment}".Equals("school"))
                        {
                            //学校的身份不管是谁，只能以学校的身份进行一次评论
                            AppraiseRole schoolRole = appraiseComment.roles.Find(x => x.roleType.Equals($"{_roleTypeComment}"));
                            if (schoolRole != null)
                            {
                                if (schoolRole.timeLines.IsNotEmpty())
                                {
                                    schoolRole.timeLines.Add(timeLine);
                                }
                                else {
                                    schoolRole.timeLines = new List<TimeLine>() { timeLine };
                                }
                            }
                            else
                            {
                                appraiseComment.roles.Add(new AppraiseRole { commentTmdid = $"{_commentTmdid}", roleType = $"{_roleTypeComment}", dimensions = new List<AppraiseDimension>(), score = -1, timeLines = new List<TimeLine>() { timeLine} });
                            }
                        }
                        else
                        { //其他身份的同一个人可以以不同身份进行点评
                            AppraiseRole otherRole = appraiseComment.roles.Find(x => x.commentTmdid.Equals($"{_commentTmdid}") && x.roleType.Equals($"{_roleTypeComment}"));
                            if (otherRole != null)
                            {
                                if (otherRole.timeLines.IsNotEmpty())
                                {
                                    otherRole.timeLines.Add(timeLine);
                                }
                                else
                                {
                                    otherRole.timeLines = new List<TimeLine>() { timeLine };
                                }
                            }
                            else
                            {
                                appraiseComment.roles.Add(new AppraiseRole { commentTmdid = $"{_commentTmdid}", roleType = $"{_roleTypeComment}", dimensions = new List<AppraiseDimension>(), score = -1, timeLines = new List<TimeLine>() { timeLine } });
                            }
                        }
                         
                        if (isnewComment)
                        {
                            await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Appraise>(appraiseComment, new PartitionKey(code));
                        }
                        else {
                            await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Appraise>(appraiseComment, appraiseComment.id, new PartitionKey(code));
                        }
                        return Ok(new { timeLine, reply });
                    case bool when $"{_opt}".Equals("ReadAllComment", StringComparison.OrdinalIgnoreCase):
                        if (!request.TryGetProperty("atSchool", out JsonElement _atSchool)) return BadRequest();
                        dynamic schoolAppraise =   new ExpandoObject();
                        List<dynamic> comments = new List<dynamic>();
                        Appraise appraises = null;
                        try {
                            appraises = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Appraise>($"{_videoId}", new PartitionKey(code));
                        } catch (CosmosException ex) {
                            return Ok(new { comments, schoolAppraise });
                        }
                        Debate rdebate = null;
                        try {
                              rdebate = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Debate>($"{_videoId}", new PartitionKey($"Debate-{_atSchool}"));
                        } catch (CosmosException ex) {
                            rdebate = null;
                        }
                        if (appraises.roles != null) {
                            appraises.roles.ToList().ForEach(x => {
                                if (x.roleType.Equals("school")) {
                                    schoolAppraise = new { x.roleType, x.dimensions, x.score };
                                }
                                x.timeLines.ForEach(t => {
                                    if (rdebate != null)
                                    {
                                       var reply= rdebate.replies.Find(r => r.id.Equals(t.replyId));
                                        if (reply != null) {
                                            comments.Add(new { x.roleType, comment = new { videoTime = t.videoTime,t.per,t.tag,t.replyId,reply.comment,reply.tmdid,reply.tmdname,reply.time } });
                                        }
                                    }
                                });
                            });
                        }
                        return Ok(new { comments, schoolAppraise });
                }
            } catch (Exception ex) {
                await _dingDing.SendBotMsg($"OS，{_option.Location}，AppraiseController/Opt()\n{ex.Message}{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
                return BadRequest();
            }
            return Ok(); 
        }
    }
    public record AppraiseComment
    {  
        //课堂实录上传教师所在的学校 并非当前登录者的学校编码
        public string atSchool { get; set; }
        //课堂实录上传教师的醍摩豆ID
        public string atTmdid { get; set; }
        //课堂实录上传教师的醍摩豆昵称
        public string atTmdname { get; set; }
        //当前课堂实录视频的名称
        public string videoName { get; set; }
        public double per { get; set; }
        public long videoTime { get; set; }
        public string tag { get; set; }
        public string tmdname { get; set; }
        public string content { get; set; }
    }
}
