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.Entity;
using GxPress.EnumConst;
using GxPress.Repository.Interface;
using GxPress.Request.Analyze;
using GxPress.Request.App.Middle;
using GxPress.Request.Notice;
using GxPress.Result;
using GxPress.Result.Notice;
using GxPress.Service.Interface.Analyze;
using GxPress.Service.Interface.Middle;
using GxPress.Service.Interface.Notice;
using GxPress.Service.Interface.Visit;
using Newtonsoft.Json;
using GxPress.Service.Interface.UserMiddle;

namespace GxPress.Service.Implement.Notice
{
    public partial class NoticeService : INoticeService
    {
        private readonly IUserRepository _userRepository;
        private readonly INoticeRepository _noticeRepository;
        private readonly INoticeCcRepository _noticeCcRepository;
        private readonly INoticeAddresseeRepository _noticeAddresseeRepository;
        private readonly IDepartmentRepository _departmentRepository;
        private readonly IMiddleService _middleService;
        private readonly IMiddleRepository _middleRepository;
        private readonly IMapper _mapper;
        private readonly IAnalyzeService _analyzeService;
        private readonly IVisitService _visitService;
        private readonly ICommentRepository _commentRepository;
        private readonly IUserMiddleService _userMiddleService;
        public NoticeService(IUserRepository userRepository, IMapper mapper, INoticeRepository noticeRepository,
            INoticeCcRepository noticeCcRepository, INoticeAddresseeRepository noticeAddresseeRepository,
            IDepartmentRepository departmentRepository, IMiddleService middleService,
            IMiddleRepository middleRepository, IAnalyzeService analyzeService, ICommentRepository commentRepository, IVisitService visitService, IUserMiddleService userMiddleService)
        {
            _noticeRepository = noticeRepository;
            _userRepository = userRepository;
            _noticeAddresseeRepository = noticeAddresseeRepository;
            _noticeCcRepository = noticeCcRepository;
            _departmentRepository = departmentRepository;
            _mapper = mapper;
            _middleService = middleService;
            _middleRepository = middleRepository;
            _analyzeService = analyzeService;
            _commentRepository = commentRepository;
            _visitService = visitService;
            _userMiddleService = userMiddleService;
        }
        /// <summary>
        /// 获取通知的点赞列表
        /// </summary>
        /// <param name="id"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<NoticeDetailResult> GetNoticeDetailAsync(int id, int userId)
        {

            var notice = await _noticeRepository.GetAsync(id);
            if (notice == null)
                throw new BusinessException("通知不存在");
            var noticeDetailResult = new Result.Notice.NoticeDetailResult();
            var result = _mapper.Map<Result.Notice.NoticeDetailResult>(notice);
            //获取新版
            result.AddresseeUserMiddles = await _userMiddleService.FindUserMiddlesAsync(10, id);
            result.CcUserMiddles = await _userMiddleService.FindUserMiddlesAsync(20, id);
            //json
            var contentJsonData = JsonConvert.DeserializeObject<List<ContentJsonData>>(result.Content);
            foreach (var item in contentJsonData)
                item.File = StringUtils.AddDomain(item.File);
            result.Data = contentJsonData;
            //获取用户
            var user = await _userRepository.GetAsync(result.UserId);
            result.UserName = user.Name;
            result.AllCount = await _noticeAddresseeRepository.CountAsync(Q.Where(nameof(NoticeAddressee.NoticeId), id));
            result.ReadCount = await _noticeAddresseeRepository.CountAsync(Q.Where(nameof(NoticeAddressee.NoticeId), id).Where(nameof(NoticeAddressee.IsRead), true));
            //获取收件人
            var noticeAddresseeList =
                await _noticeAddresseeRepository.GetUserByNoticeIdAsync(id);
            result.NoticeAddresseeNames = noticeAddresseeList.Select(n => n.Name).ToList();
            var IsRead = await _noticeAddresseeRepository.ExistsAsync(Q.Where(nameof(Entity.Middle.Middle.IsRead), true)
                  .Where(nameof(NoticeAddressee.NoticeId), id)
                  .Where(nameof(NoticeAddressee.UserId), userId));
            //修改阅读量
            if (IsRead == false)
            {
                if (await _noticeAddresseeRepository.UpdateAsync(Q.Set(nameof(Entity.Middle.Middle.IsRead), true)
                    .Where(nameof(NoticeAddressee.NoticeId), id)
                    .Where(nameof(NoticeAddressee.UserId), userId)))
                    result.ReadCount++;
            }
            //修改访问量
            await _visitService.AddVisit(userId, 5, id);
            //修改middle的阅读
            // await _middleRepository.UpdateAsync(Q.Set(nameof(Entity.Middle.Middle.IsRead), true).Where(nameof(Entity.Middle.Middle.UserId), userId).Where(nameof(Entity.Middle.Middle.MiddleId), id).Where(nameof(Entity.Middle.Middle.FolderType), 1));
            var analyzeRequest = new Request.App.Analyze.AnalyzeRequest();
            analyzeRequest.TypeValue = 2;
            analyzeRequest.AnalyzeType = 1;
            analyzeRequest.SourceId = id;
            analyzeRequest.UserId = userId;
            //点赞数量
            result.PraiseCount = await _analyzeService.CountAsync(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);
            //获取话题的点赞数量
            analyzeRequest.AnalyzeType = 1;
            var praiseCount = await _analyzeService.CountAsync(analyzeRequest);
            result.PraiseCount = praiseCount;
            //是否点赞
            result.IsPraise = await _analyzeService.ExistsAsync(analyzeRequest);
            var request = new PraisePageSearchRequest { SourceId = id, TypeValue = 2, Page = 1, PerPage = 3 };
            result.NoticePraisePagedList = await _analyzeService.GetPraisePageAsync(request);
            //是否是当前用户创建
            result.IsAdmin = notice.UserId == userId;
            return result;
        }
        /// <summary>
        /// 根据通知ID获取通知详情
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<NoticeEditDetailResult> NoticeEditDetailAsync(int id)
        {
            var notice = await _noticeRepository.GetAsync(id);
            var result = _mapper.Map<NoticeEditDetailResult>(notice);
            //抄送人
            var noticeCcList = await _noticeCcRepository.GetNoticeCcByNoticeIdAsync(id);
            //收件人
            var noticeAddressee = await _noticeAddresseeRepository.GetNoticeAddresseeByNoticeIdAsync(id);
            //获取新版
            result.AddresseeUserMiddles = await _userMiddleService.FindUserMiddlesAsync(10, id);
            result.CcUserMiddles = await _userMiddleService.FindUserMiddlesAsync(20, id);
            var noticeAddresseeUsers =
                await _userRepository.UserListInsAsync(noticeAddressee.Select(n => n.UserId).ToList());
            result.NoticeAddresseeUsers =
                noticeAddresseeUsers.Select(n => _mapper.Map<NoticeAddresseeUser>(n)).ToList();

            var noticeCcUsers = await _userRepository.UserListInsAsync(noticeCcList.Select(n => n.UserId).ToList());
            result.NoticeCcUsers = noticeCcUsers.Select(n => _mapper.Map<NoticeCcUser>(n)).ToList();
            foreach (var noticeAddresseeUser in result.NoticeAddresseeUsers)
            {
                noticeAddresseeUser.AvatarUrl = StringUtils.AddDomainMin(noticeAddresseeUser.AvatarUrl);
            }

            foreach (var noticeCcUser in result.NoticeCcUsers)
            {
                noticeCcUser.AvatarUrl = StringUtils.AddDomainMin(noticeCcUser.AvatarUrl);
            }
            var jsonData = JsonConvert.DeserializeObject<List<ContentJsonData>>(result.Content);
            foreach (var item in jsonData)
                item.File = StringUtils.AddDomain(item.File);
            result.Data = jsonData;
            return result;
        }

        /// <summary>
        /// 获取通知详情
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<Result.Notice.NoticeDetailResult> GetNoticeDetailResultAsync(int id, int userId)
        {
            var notice = await _noticeRepository.GetAsync(id);
            if (notice == null)
                throw new BusinessException("通知不存在");
            var noticeDetailResult = new Result.Notice.NoticeDetailResult();
            var result = _mapper.Map<Result.Notice.NoticeDetailResult>(notice);
            //获取新版
            result.AddresseeUserMiddles = await _userMiddleService.FindUserMiddlesAsync(10, id);
            result.CcUserMiddles = await _userMiddleService.FindUserMiddlesAsync(20, id);
            //json
            var contentJsonData = JsonConvert.DeserializeObject<List<ContentJsonData>>(result.Content);
            foreach (var item in contentJsonData)
                item.File = StringUtils.AddDomain(item.File);
            result.Data = contentJsonData;
            //获取用户
            var user = await _userRepository.GetAsync(result.UserId);
            result.UserName = user.Name;
            result.AllCount =
                await _noticeAddresseeRepository.CountAsync(Q.Where(nameof(NoticeAddressee.NoticeId), id));
            result.ReadCount = await _noticeAddresseeRepository.CountAsync(Q
                .Where(nameof(NoticeAddressee.NoticeId), id).Where(nameof(NoticeAddressee.IsRead), true));
            //获取收件人
            var noticeAddresseeList =
                await _noticeAddresseeRepository.GetAllAsync(Q.Where(nameof(NoticeAddressee.NoticeId), id)
                    .Where(nameof(Entity.Middle.Middle.IsAdmin), false));
            result.NoticeAddresseeNames = noticeAddresseeList.Select(n => n.UserName).ToList();
            //修改阅读量
            await _noticeAddresseeRepository.UpdateAsync(Q.Set(nameof(Entity.Middle.Middle.IsRead), true)
                .Where(nameof(NoticeAddressee.NoticeId), id)
                .Where(nameof(NoticeAddressee.UserId), userId));
            //修改middle的阅读
            await _middleRepository.UpdateAsync(Q.Set(nameof(Entity.Middle.Middle.IsRead), true).Where(nameof(Entity.Middle.Middle.UserId), userId).Where(nameof(Entity.Middle.Middle.MiddleId), id).Where(nameof(Entity.Middle.Middle.FolderType), 1));
            var analyzeRequest = new Request.App.Analyze.AnalyzeRequest();
            analyzeRequest.TypeValue = 2;
            analyzeRequest.AnalyzeType = 1;
            analyzeRequest.SourceId = id;
            analyzeRequest.UserId = userId;
            //点赞数量
            result.PraiseCount = await _analyzeService.CountAsync(analyzeRequest);
            //获取话题的评论数量
            var commentCount =
                await _commentRepository.CountAsync(Q.Where(nameof(Entity.Comment.ArticleId), id).Where(nameof(Entity.Comment.TypeValue), 1));
            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);
            //获取话题的点赞数量
            analyzeRequest.AnalyzeType = 1;
            var praiseCount = await _analyzeService.CountAsync(analyzeRequest);
            result.PraiseCount = praiseCount;
            //是否点赞
            result.IsPraise = await _analyzeService.ExistsAsync(analyzeRequest);
            return result;
        }

        /// <summary>
        /// 编辑通知
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> NoticeUpAsync(NoticeUpRequest request)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    var notice = await _noticeRepository.GetAsync(request.Id);
                    if (notice == null)
                        throw new BusinessException("通知不存在");
                    var noticeInRequest = new NoticeInRequest();
                    noticeInRequest.Content = request.Content;
                    noticeInRequest.HtmlContent = request.HtmlContent;
                    noticeInRequest.NoticeType = request.NoticeType;
                    noticeInRequest.AddresseeUserMiddles = request.AddresseeUserMiddles;
                    noticeInRequest.CcUserMiddles = request.CcUserMiddles;
                    noticeInRequest.Title = request.Title;
                    noticeInRequest.UserId = request.UserId;
                    noticeInRequest.SoureId = 0;
                    noticeInRequest.Id = request.Id;
                    if (request.NoticeType == NoticeTypeConst.Send)
                    {
                        if (notice.NoticeType == NoticeTypeConst.Draft)
                        {
                            //删除
                            await _noticeRepository.DeleteAsync(Q.Where(nameof(Entity.Notice.Id), notice.Id));
                            //删除middle
                            await _middleRepository.DeleteAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), notice.Id).Where(nameof(Entity.Middle.Middle.FolderType), 1));
                            if (notice.SourceId > 0)
                            {
                                var noticeSource = await _noticeRepository.GetAsync(notice.SourceId);
                                if (noticeSource != null)
                                    noticeInRequest.Id = noticeSource.Id;
                                else
                                    noticeInRequest.Id = 0;
                            }
                            else
                                noticeInRequest.Id = 0;
                        }
                    }
                    else
                    {
                        if (notice.NoticeType == NoticeTypeConst.Draft)
                            noticeInRequest.Id = request.Id;
                        else
                        {
                            noticeInRequest.SoureId = notice.Id;
                            var noticeSource = await _noticeRepository.GetAsync(Q.Where(nameof(Entity.Notice.SourceId), notice.Id));
                            if (noticeSource != null)
                                noticeInRequest.Id = noticeSource.Id;
                            else noticeInRequest.Id = 0;
                        }
                    }
                    await InsertAsync(noticeInRequest);
                    transactionScope.Complete();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
            return true;
        }
        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> SendNoticeAsync(NoticeUpRequest request)
        {
            if (request.AddresseeUserMiddles.Count > 0)
            {
                await _userMiddleService.DeleteAsync(Q.Where(nameof(Entity.UserMiddle.UserMiddle.MiddleType), 10).Where(nameof(Entity.UserMiddle.UserMiddle.DataSourceId), request.Id));
                foreach (var item in request.AddresseeUserMiddles)
                {
                    item.DataSourceId = request.Id;
                    item.MiddleType = 10;
                }
                await _userMiddleService.AddUserMiddleAsync(request.AddresseeUserMiddles);
                var users = await _userMiddleService.FindUsersAsync(request.AddresseeUserMiddles, request.UserId);
                request.NoticeAddresseeUserIds = users.Select(n => n.Id).ToList();
                request.NoticeAddresseeUserIds.Remove(request.UserId);
            }
            if (request.CcUserMiddles.Count > 0)
            {
                await _userMiddleService.DeleteAsync(Q.Where(nameof(Entity.UserMiddle.UserMiddle.MiddleType), 20).Where(nameof(Entity.UserMiddle.UserMiddle.DataSourceId), request.Id));
                foreach (var item in request.CcUserMiddles)
                {
                    item.DataSourceId = request.Id;
                    item.MiddleType = 20;
                }
                await _userMiddleService.AddUserMiddleAsync(request.CcUserMiddles);
                var users = await _userMiddleService.FindUsersAsync(request.CcUserMiddles, request.UserId);
                request.NoticeCcUserIds = users.Select(n => n.Id).ToList();
                request.NoticeCcUserIds.Remove(request.UserId);
            }
            if (request.NoticeAddresseeUserIds.Count > 0)
            {
                //删除接收人
                await _noticeAddresseeRepository.DeleteAsync(request.Id);
                //删除middle
                await _middleRepository.DeleteAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), request.Id).Where(nameof(Entity.Middle.Middle.FolderType), 1));
                if (request.NoticeType == NoticeTypeConst.Send)
                {
                    var userEntity = await _userRepository.GetAsync(request.UserId);
                    //创建人
                    var noticeAddresseeEntity = new NoticeAddressee
                    {
                        NoticeId = request.Id,
                        UserId = request.UserId,
                        UserName = userEntity.Name,
                        IsAdmin = true,
                        NoticeAddresseeType = request.NoticeType,
                        IsTop = false
                    };
                    var noticeAddresseeId = await _noticeAddresseeRepository.InsertAsync(noticeAddresseeEntity);
                    //添加文件
                    var middleInsertTypes = new MiddleInsertTypeRequest
                    {
                        FolderId = 0,
                        MiddleId = request.Id,
                        FolderType = 1,
                        UserId = request.UserId,
                        MiddleSonId = noticeAddresseeId,
                        NoticeAddresseeType = request.NoticeType,
                        AttributeValue = 1,
                        IsAdmin = true
                    };
                    await _middleService.InsertAsync(middleInsertTypes);
                }
                //收件人
                foreach (var noticeAddresseeUserId in request.NoticeAddresseeUserIds)
                {
                    var user = await _userRepository.GetAsync(noticeAddresseeUserId);
                    if (user.Id == request.UserId)
                        continue;
                    var noticeAddressee = new NoticeAddressee
                    {
                        NoticeId = request.Id,
                        UserId = noticeAddresseeUserId,
                        UserName = user.Name,
                        NoticeAddresseeType = request.NoticeType
                    };
                    var noticeAddresseeId = await _noticeAddresseeRepository.InsertAsync(noticeAddressee);
                    if (request.NoticeType == NoticeTypeConst.Send)
                    {
                        //添加文件
                        var middleInsertType = new MiddleInsertTypeRequest
                        {
                            FolderId = 0,
                            MiddleId = request.Id,
                            FolderType = 1,
                            UserId = noticeAddresseeUserId,
                            MiddleSonId = noticeAddresseeId,
                            AttributeValue = 1
                        };
                        await _middleService.InsertAsync(middleInsertType);
                    }
                }
            }
            if (request.NoticeCcUserIds.Count > 0)
            {
                //删除抄送人
                await _noticeCcRepository.DeleteAsync(request.Id);
                //创建
                //抄送
                foreach (var noticeCcUserId in request.NoticeCcUserIds)
                {
                    var user = await _userRepository.GetAsync(noticeCcUserId);
                    var noticeCc = new NoticeCc
                    {
                        UserId = noticeCcUserId,
                        NoticeId = request.Id,
                        UserName = user.Name,
                        NoticeCcType = request.NoticeType
                    };
                    await _noticeCcRepository.InsertAsync(noticeCc);
                }
            }
            return true;
        }
        /// <summary>
        /// 根据已读未读查询通知数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IEnumerable<NoticeReadListResult>> NoticeReadListAsync(NoticeReadListRequest request)
        {
            var noticeReadListResults = await _noticeAddresseeRepository.GetNoticeAddresseeByUserIdIdAsync(request);
            return noticeReadListResults;
        }

        /// <summary>
        /// 获取通知列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PagedList<NoticeListPageResult>> GetNoticeListPageAsync(NoticePageSearchRequest request)
        {
            var result = await _noticeRepository.GetNoticeListPageAsync(request);
            foreach (var item in result.Items)
            {
                // var userMiddles = await _userMiddleService.FindUserMiddlesAsync(10, item.MiddleId);
                // item.EnjoyUser = StringUtils.ObjectCollectionToString(userMiddles.Select(n => n.SourceName).ToList(), "、");
                //分析title
                if (string.IsNullOrWhiteSpace(item.Title))
                {
                    var data = JsonConvert.DeserializeObject<List<ContentJsonData>>(item.Content);
                    if (data.Count > 0)
                    {
                        var first = data.First();
                        if (first.TypeValue == OldTextEditorTypeConst.Text.GetHashCode() && !string.IsNullOrWhiteSpace(first.Text))
                            item.Title = first.Text;
                        else
                        {
                            foreach (var contentJsonData in data)
                            {
                                //是否是文本
                                if (contentJsonData.TypeValue == OldTextEditorTypeConst.Text.GetHashCode())
                                    continue;
                                else if (contentJsonData.TypeValue == OldTextEditorTypeConst.Image.GetHashCode())
                                {
                                    item.Title = "[图片]";
                                    break;
                                }
                                else if (contentJsonData.TypeValue == OldTextEditorTypeConst.File.GetHashCode())
                                {
                                    item.Title = "[附件]";
                                    break;
                                }
                                else
                                {
                                    item.Title = "[附件]";
                                    break;
                                }
                            }
                            // //图片 文件类型
                            // var typeList = new List<int> { OldTextEditorTypeConst.Image.GetHashCode(), OldTextEditorTypeConst.File.GetHashCode() };
                            // if (data.Any(n => (n.TypeValue == OldTextEditorTypeConst.Image.GetHashCode() && n.TypeValue == OldTextEditorTypeConst.File.GetHashCode())))
                            //     item.Title = "[图片][附件]";
                            // else
                            // {
                            //     if (data.Any(n => n.TypeValue == OldTextEditorTypeConst.Image.GetHashCode()))
                            //         item.Title = "[图片]";
                            //     else if (data.Any(n => n.TypeValue == OldTextEditorTypeConst.File.GetHashCode()))
                            //         item.Title = "[附件]";
                            //     else
                            //     {
                            //         if (data.Any(n => !typeList.Contains(n.TypeValue)))
                            //             item.Title = "[附件]";
                            //     }
                            // }
                        }
                    }
                }
                if (item.IsDelete == true)
                    item.NoticeStatus = 0;
                else if (item.NoticeAddresseeType == NoticeTypeConst.Draft)
                    item.NoticeStatus = 2;
                else
                    item.NoticeStatus = 1;
            }

            return result;
        }
        /// <summary>
        /// 撤销通知
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> RecallAsync(int id)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    //删除middle
                    await _middleRepository.DeleteAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), id).Where(nameof(Entity.Middle.Middle.FolderType), 1).Where(nameof(Entity.Middle.Middle.IsAdmin), false));
                    //修改为草稿箱
                    await _middleRepository.UpdateAsync(Q.Where(nameof(Entity.Middle.Middle.MiddleId), id).Where(nameof(Entity.Middle.Middle.FolderType), 1).Where(nameof(Entity.Middle.Middle.IsAdmin), true).Set(nameof(Entity.Middle.Middle.NoticeAddresseeType), 2));
                    //修改
                    await _noticeRepository.UpdateAsync(Q.Where(nameof(Entity.Notice.Id), id).Set(nameof(Entity.Notice.NoticeType), NoticeTypeConst.Draft.GetHashCode()));
                    transactionScope.Complete();
                }
            }
            catch (System.Exception ex)
            {
                throw new BusinessException(ex.Message);
            }
            return true;
        }
    }
}
