using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using AutoMapper;
using Datory;
using GxPress.Common.Exceptions;
using GxPress.Common.Page;
using GxPress.Common.Tools;
using GxPress.Repository.Interface;
using GxPress.Repository.Interface.Collection;
using GxPress.Repository.Interface.Missive;
using GxPress.Repository.Interface.Note;
using GxPress.Repository.Interface.Visit;
using GxPress.Request.Analyze;
using GxPress.Request.App.Middle;
using GxPress.Request.App.Note;
using GxPress.Result;
using GxPress.Result.App.Note;
using GxPress.Service.Interface.Analyze;
using GxPress.Service.Interface.Middle;
using GxPress.Service.Interface.Note;
using GxPress.Service.Interface.Visit;
using Newtonsoft.Json;
using GxPress.Service.Interface.UserMiddle;
using GxPress.Repository.Interface.RecordFolder;
using GxPress.EnumConst;
using GxPress.Request.App.Analyze;

namespace GxPress.Service.Implement.Note
{
    public class NoteService : INoteService
    {
        private readonly IMiddleService _middleService;
        private readonly INoteRepository _noteRepository;
        private readonly IMiddleRepository _middleRepository;
        private readonly IUserRepository _userRepository;
        private readonly IMapper _mapper;
        private readonly IArticleRepository _articleRepository;
        private readonly INoticeRepository _noticeRepository;
        private readonly IMissiveRepository _missiveRepository;
        private readonly ITopicRepository _topicRepository;
        private readonly IGroupRepository _groupRepository;
        private readonly ICollectionRepository _collectionRepository;
        private readonly ICommentRepository _commentRepository;
        private readonly IVisitRepository _visitRepository;
        private readonly IVisitService _visitService;
        private readonly IFolderUserRepository _folderUserRepository;
        private readonly IAnalyzeService _analyzeService;
        private readonly IUserMiddleService _userMiddleService;
        private readonly IRecordFolderRepository recordFolderRepository;
        public NoteService(IMiddleService middleService, INoteRepository noteRepository,
            IMiddleRepository middleRepository, IMapper mapper, IUserRepository userRepository,
            IArticleRepository articleRepository, INoticeRepository noticeRepository,
            IMissiveRepository missiveRepository, ITopicRepository topicRepository, IGroupRepository groupRepository,
            ICollectionRepository collectionRepository, ICommentRepository commentRepository, IVisitRepository visitRepository, IVisitService visitService, IFolderUserRepository folderUserRepository, IAnalyzeService analyzeService, IUserMiddleService userMiddleService, IRecordFolderRepository recordFolderRepository)
        {
            _middleService = middleService;
            _noteRepository = noteRepository;
            _middleRepository = middleRepository;
            _mapper = mapper;
            _userRepository = userRepository;
            _articleRepository = articleRepository;
            _missiveRepository = missiveRepository;
            _noteRepository = noteRepository;
            _noticeRepository = noticeRepository;
            _topicRepository = topicRepository;
            _groupRepository = groupRepository;
            _collectionRepository = collectionRepository;
            _commentRepository = commentRepository;
            _visitRepository = visitRepository;
            _visitService = visitService;
            _folderUserRepository = folderUserRepository;
            _analyzeService = analyzeService;
            _userMiddleService = userMiddleService;
            this.recordFolderRepository = recordFolderRepository;
        }

        /// <summary>
        /// 添加个人笔记
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> InsertNoteAsync(NoteInRequest request)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    if (string.IsNullOrEmpty(request.Content))
                        throw new BusinessException("内容未填写");
                    var noteContent = JsonConvert.DeserializeObject<List<ContentJsonData>>(request.Content);
                    foreach (var item in noteContent)
                        item.File = StringUtils.RemoveDomain(item.File);
                    //添加笔记
                    var note = new Entity.Note.Note
                    { Title = request.Title, Content = JsonConvert.SerializeObject(noteContent), HtmlContent = request.HtmlContent, UserId = request.UserId, IsDelete = false, IsTopic = request.IsTopic, FolderId = request.FolderId };
                    var noteId = await _noteRepository.InsertAsync(note);
                    //添加中间件
                    var middleInsertTypes = new MiddleInsertTypeRequest
                    {
                        FolderId = request.FolderId,
                        MiddleId = noteId,
                        FolderType = 4,
                        UserId = request.UserId,
                        MiddleSonId = 0,
                        AttributeValue = 1,
                        IsAdmin = true
                    };
                    await _middleService.InsertAsync(middleInsertTypes);
                    //修改话题访问量
                    await _visitService.AddVisit(request.UserId, 4, noteId);
                    //添加默认文件夹
                    await recordFolderRepository.AddAsync(request.IsTopic ? 21 : 4, request.UserId, request.FolderId);
                    transactionScope.Complete();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            return true;
        }
        /// <summary>
        /// 获取笔记分页
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PagedList<NotePageListRequest>> NotePageListAsync(NoteSearchPageListRequest request)
        {
            var result = await _noteRepository.NotePageListAsync(request);
            if (request.FolderId > 0)
            {
                var middle = await _middleRepository.GetMiddleAsync(request.FolderId);
                result.RoleId = middle != null ? middle.RoleId : 0;
            }
            //是否收藏和转发数量
            if (request.VisitUserId > 0)
            {
                var analyzeRequest = new AnalyzeRequest();
                analyzeRequest.SourceUserId = request.VisitUserId;
                analyzeRequest.AnalyzeType = 3;
                analyzeRequest.CommentId = 0;
                analyzeRequest.SourceId = request.FolderId;
                analyzeRequest.UserId = request.UserId;
                analyzeRequest.TypeValue = 13;
                result.IsCollect = await _analyzeService.ExistsSourceUserAsync(analyzeRequest);
                analyzeRequest.AnalyzeType = 4;
                result.RetransmissionCount = await _analyzeService.RetransmissionCountAsync(analyzeRequest);
            }
            foreach (var item in result.Items)
            {
                if (string.IsNullOrWhiteSpace(item.Content))
                    item.Content = "[]";
                var contentJsonData = JsonConvert.DeserializeObject<List<ContentJsonData>>(item.Content);
                foreach (var contentJsonDataItem in contentJsonData)
                    contentJsonDataItem.File = StringUtils.AddDomain(contentJsonDataItem.File);
                if (contentJsonData.Count == 0)
                    item.DataType = 1;
                item.Content = "";
                if (contentJsonData.Count > 0)
                {
                    var imgData = new List<ContentJsonData>();
                    var FileData = new List<ContentJsonData>();
                    var forCount = 1;
                    var firstContent = string.Empty;
                    foreach (var jsonData in contentJsonData)
                    {
                        if (jsonData.TypeValue == OldTextEditorTypeConst.Text.GetHashCode() && forCount == 1)
                            //文本
                            firstContent = jsonData.Text;
                        else if (jsonData.TypeValue == OldTextEditorTypeConst.Text.GetHashCode() && forCount > 1)
                            //文本
                            continue;
                        //图片
                        else if (jsonData.TypeValue == OldTextEditorTypeConst.Image.GetHashCode() && FileData.Count == 0)
                        {
                            if (imgData.Count > 9)
                                break;
                            imgData.Add(jsonData);
                        }
                        //附件
                        else
                        {
                            FileData.Add(jsonData);
                            break;
                        }
                        forCount++;
                    }
                    item.Content = string.IsNullOrWhiteSpace(firstContent) ? "" : firstContent;
                    if (imgData.Count > 0) { item.DataType = 2; item.Data = imgData; }
                    else if (FileData.Count > 0) { item.DataType = 3; item.Data = FileData; }
                    else item.DataType = 1;
                    var contType = new List<int> { OldTextEditorTypeConst.Text.GetHashCode(), OldTextEditorTypeConst.Image.GetHashCode() };
                    item.FileCount = contentJsonData.Count(n => !contType.Contains(n.Type));
                }
                if (item.Data == null || item.Data.Count == 0)
                    item.Data = new List<ContentJsonData>();
                // //获取共享人员
                // if (item.RoleId == 3)
                // {
                //     var sourceId = item.Id;
                //     if (item.ParentId > 0)
                //         sourceId = item.MiddleSonId;
                //     var userMiddles = await _userMiddleService.FindUserMiddlesAsync(item.FolderType, sourceId);
                //     item.EnjoyUser = StringUtils.ObjectCollectionToString(userMiddles.Select(n => n.SourceName), "、");
                //     // var folderUsers = await _folderUserRepository.GetAllAsync(Q.Where(nameof(FolderUser.MiddleId), item.Id).OrderByDesc(nameof(FolderUser.CreatedDate)).Take(10));
                //     // item.EnjoyUser = StringUtils.ObjectCollectionToString(folderUsers.Select(n => n.UserName), "、");
                // }
            }

            return result;
        }
        /// <summary>
        /// 笔记解析
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<List<ContentJsonData>> AnalyzeAsync(List<ContentJsonData> data)
        {
            var result = new List<ContentJsonData>();
            var fileCount = data.Count(n => n.Type == 3);
            //提取图片
            if (data.Any(n => n.Type == 2))
            {
                var contentJsonData = new ContentJsonData { FileCount = fileCount, Type = 2 };
                //获取图片
                var imgList = data.Where(n => n.Type == 2);
                contentJsonData.ArticleImgUrl = imgList.Select(n => StringUtils.AddDomain(n.File)).ToList();
                result.Add(contentJsonData);
                return result;
            }
            //获取
            foreach (var item in data.Where(n => n.Type != 1 && n.Type != 3))
            {
                return await StructNoteData(item.Id, item.Type);
            }
            return result;
        }

        /// <summary>
        ///  类型1 txt文字 2 img:图片 3 file:文件 4 Article:文章 5 notice通知 6 topic话题 7 note笔记 8 collection收藏 9站内信 10小组
        /// </summary>
        /// <param name="collectionDataId"></param>
        /// <param name="collectionType"></param>
        /// <returns></returns>
        public async Task<List<ContentJsonData>> StructNoteData(int collectionDataId, int collectionType)
        {
            var list = new List<ContentJsonData>();
            //文章类型
            if (collectionType == 4)
            {
                var article = await _articleRepository.GetArticleAsync(collectionDataId);
                if (article == null)
                    return new List<ContentJsonData>();
                var imageUrls = StringUtils.StringCollectionToStringList(article.ImageUrls).ToList();
                var articleImgUrl = new List<string>();
                foreach (var t in imageUrls)
                    articleImgUrl.Add(StringUtils.AddDomain(t));
                list.Add(new ContentJsonData
                {
                    Author = article.Source,
                    Title = article.Title,
                    CreatedData = article.CreatedDate,
                    Type = 4,
                    Id = article.Id,
                    ArticleImgUrl = articleImgUrl,
                    ReadCount = article.ReadCount
                });
            }

            //话题类型
            if (collectionType == 6)
            {
                var topic = await _topicRepository.GetAsync(collectionDataId);
                if (topic == null)
                    return list;
                //查询ID
                var user = await _userRepository.GetAsync(topic.UserId);
                list.Add(new ContentJsonData
                {
                    Author = user.Name,
                    Title = topic.Title,
                    CreatedData = topic.CreatedDate,
                    Type = 6,
                    Id = topic.Id,
                    File = StringUtils.AddDomain(user.AvatarUrl),
                    ReadCount = topic.ReadCount
                });
            }

            //收藏
            if (collectionType == 8)
            {
                var collection = await GetCollectionRecursion(collectionDataId);
                if (collection == null)
                    return new List<ContentJsonData>();
                //1文章 2话题 3 收藏 4笔记 5通知 6站内信  7小组 8会议
                if (collection.CollectionType == 1)
                    //4 Article:文章 5 notice通知 6 topic话题 7 note笔记 8 collection收藏 9站内信 10小组 11会议
                    collection.CollectionType = 4;
                else if (collection.CollectionType == 2)
                    collection.CollectionType = 6;
                else if (collection.CollectionType == 4)
                    collection.CollectionType = 7;
                else if (collection.CollectionType == 6)
                    collection.CollectionType = 9;
                else if (collection.CollectionType == 7)
                    collection.CollectionType = 10;
                else if (collection.CollectionType == 8)
                    collection.CollectionType = 11;
                list = await StructNoteData(collection.CollectionDataId, collection.CollectionType);
                // foreach (var item in list)
                // {
                //     item.Type = 8;
                // }
            }

            //笔记
            if (collectionType == 7)
            {
                var note = await _noteRepository.GetAsync(collectionDataId);
                if (note == null)
                    return list;
                var user = await _userRepository.GetAsync(note.UserId);
                list.Add(new ContentJsonData
                {
                    Author = user.Name,
                    NickName = user.Nick,
                    Title = note.Title,
                    CreatedData = note.CreatedDate,
                    Type = 7,
                    Id = note.Id,
                    File = ""
                });
            }

            //通知
            if (collectionType == 5)
            {
                var notice = await _noticeRepository.GetAsync(collectionDataId);
                if (notice == null)
                    return new List<ContentJsonData>();
                var user = await _userRepository.GetAsync(notice.UserId);
                list.Add(new ContentJsonData
                {
                    Author = user.Name,
                    Title = notice.Title,
                    CreatedData = notice.CreatedDate,
                    Type = 5,
                    Id = notice.Id,
                    File = ""
                });
            }

            //站内信
            if (collectionType == 9)
            {
                var missive = await _missiveRepository.GetAsync(collectionDataId);
                if (missive == null)
                    return new List<ContentJsonData>();
                var user = await _userRepository.GetAsync(missive.UserId);
                list.Add(new ContentJsonData
                {
                    Author = user.Name,
                    Title = missive.Title,
                    CreatedData = missive.CreatedDate,
                    Type = 6,
                    Id = missive.Id,
                    File = ""
                });
            }

            //小组
            if (collectionType == 10)
            {
                if (collectionDataId == 0)
                    return new List<ContentJsonData>();
                var group = await _groupRepository.GetAsync(collectionDataId);
                var user = await _userRepository.GetAsync(group.UserId);
                list.Add(new ContentJsonData
                {
                    Author = user.Name,
                    Title = group.Name,
                    CreatedData = group.CreatedDate,
                    Type = 7,
                    Id = group.Id,
                    File = StringUtils.AddDomain(group.AvatarUrl)
                });
            }

            return list;
        }

        /// <summary>
        /// 递归获取不是收藏的数据
        /// </summary>
        /// <param name="middleId"></param>
        /// <returns></returns>
        public async Task<Entity.Collection> GetCollectionRecursion(int middleId)
        {
            //var middle = await _middleRepository.GetMiddleAsync(middleId);
            var collection = await _collectionRepository.GetAsync(middleId);
            if (collection == null)
                return new Entity.Collection();
            if (collection.CollectionType == 3)
                await GetCollectionRecursion(collection.CollectionType);
            return collection;
        }

        /// <summary>
        /// 获取笔记详情
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<NoteDetailResult> GetNoteDetailAsync(int id, int userId)
        {
            var note = await _noteRepository.GetAsync(id);
            if (note == null || note.IsDelete)
                throw new BusinessException("笔记已被删除！");
            var result = _mapper.Map<NoteDetailResult>(note);
            var user = await _userRepository.GetAsync(result.UserId);
            result.Name = user.Name;
            var list = JsonConvert.DeserializeObject<List<ContentJsonData>>(note.Content);
            foreach (var item in list)
            {
                item.File = StringUtils.AddDomain(item.File);
            }
            if (userId == 0)
                return result;
            //获取共享文件夹名称
            if (result.FolderId > 0)
            {
                var middle = await _middleRepository.GetMiddleAsync(result.FolderId);
                result.FolderName = middle != null ? middle.FolderName : "";
            }
            var analyzeRequest = new Request.App.Analyze.AnalyzeRequest();
            analyzeRequest.TypeValue = 3;
            analyzeRequest.AnalyzeType = 1;
            analyzeRequest.SourceId = id;
            analyzeRequest.UserId = userId;
            //点赞数量
            result.PraiseCount = await _analyzeService.CountAsync(analyzeRequest);
            //是否点赞
            result.IsPraise = await _analyzeService.ExistsAsync(analyzeRequest);
            //获取话题的评论数量
            var commentCount =
                await _commentRepository.CountAsync(Q.Where(nameof(Entity.Comment.ArticleId), id).Where(nameof(Entity.Comment.TypeValue), analyzeRequest.TypeValue).Where(nameof(Entity.Comment.Pid), 0));
            result.CommentCount = commentCount;
            //获取话题的转发数量
            analyzeRequest.AnalyzeType = 4;
            var retransmissionCount = await _analyzeService.CountAsync(analyzeRequest);
            result.RetransmissionCount = retransmissionCount;
            result.IsRetransmission = await _analyzeService.ExistsAsync(analyzeRequest);
            //获取话题的收藏数量
            analyzeRequest.AnalyzeType = 3;
            var collectCount = await _analyzeService.CountAsync(analyzeRequest);
            result.CollectCount = collectCount;
            //是否收藏
            result.IsCollect = await _analyzeService.ExistsAsync(analyzeRequest);
            result.Data = list;
            //修改访问量
            await _visitService.AddVisit(userId, 4, id);
            //是否自建
            result.IsAdmin = note.UserId == userId;
            var praisePageSearchRequest = new PraisePageSearchRequest { SourceId = id, TypeValue = 3, Page = 1, PerPage = 3 };
            result.NotePraisePagedList = await _analyzeService.GetPraisePageAsync(praisePageSearchRequest);
            return result;
        }
        /// <summary>
        /// 修改笔记
        /// </summary>
        /// <param name="note"></param>
        /// <returns></returns>
        public async Task<bool> UpdateNoteAsync(Entity.Note.Note note)
        {
            var entity = await _noteRepository.GetAsync(note.Id);
            if (string.IsNullOrWhiteSpace(note.Content) && string.IsNullOrWhiteSpace(note.Title))
                throw new BusinessException("标题和内容至少一项必填！");
            if (!string.IsNullOrWhiteSpace(note.Content))
            {
                var json = JsonConvert.DeserializeObject<List<ContentJsonData>>(note.Content);
                foreach (var item in json)
                    item.File = StringUtils.RemoveDomain(item.File);
                entity.Content = JsonConvert.SerializeObject(json);
                entity.HtmlContent = note.HtmlContent;
            }
            else
                entity.Content = "";
            if (note.FolderId > 0)
            {
                entity.FolderId = note.FolderId;
                //获取middle
                var middle = await _middleRepository.GetMiddleAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), note.Id).Where(nameof(Entity.Middle.Middle.FolderType), 4).Where(nameof(Entity.Middle.Middle.UserId), entity.UserId));
                if (middle != null)
                {
                    //修改middle
                    middle.ParentId = note.FolderId;
                    await _middleRepository.UpdateAsync(middle);
                }
            }
            //if (!string.IsNullOrWhiteSpace(note.Title))
            entity.Title = note.Title;
            return await _noteRepository.UpdateAsync(entity);
        }

        public async Task<bool> DeleteAsync(int id, int userId)
        {
            //获取笔记
            var note = await _noteRepository.GetAsync(id);
            if (note == null || note.UserId != userId)
                throw new BusinessException("不满足删除条件！");
            try
            {
                using (var transactionScope = new TransactionScope())
                {
                    //修改笔记
                    note.IsDelete = true;
                    await _noteRepository.UpdateAsync(note);
                    //获取middle修改middle
                    var middle = await _middleRepository.GetMiddleAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), id).Where(nameof(Entity.Middle.Middle.UserId), userId));
                    await _middleRepository.DeleteAsync(Q.Where(nameof(Entity.Middle.Middle.Id), middle.Id));
                    transactionScope.Complete();
                }
            }
            catch (System.Exception ex)
            {
                throw new BusinessException(ex.Message);
            }
            return true;
        }



    }

}
