using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Transactions;
using AutoMapper;
using GxPress.Common.AppOptions;
using GxPress.Common.Exceptions;
using GxPress.Common.Tools;
using GxPress.Entity;
using GxPress.Repository.Interface;
using GxPress.Request.App.ChatRecord;
using GxPress.Result.App.ChatRecord;
using Microsoft.Extensions.Options;
using Datory;
using GxPress.Common.Page;

namespace GxPress.Repository.Implement
{
    public class ChatRecordRepository:IChatRecordRepository
    {
        private readonly Repository<ChatRecord> _repository;
        private readonly Repository<User> _userRepository;
        private readonly Repository<GroupChat> _groupChatRepository;
        private readonly Repository<GroupChatUser> _groupChartUseRepository;
        private readonly Repository<OftenContact> _oftenContactRepository;
        private readonly Repository<FileLibrary> _fileLibraryRepository;
        private readonly IMapper _mapper;

        public ChatRecordRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IMapper mapper)
        {
            var databaseType = StringUtils.ToEnum<DatabaseType>(dbOptionsAccessor.CurrentValue.DatabaseType, DatabaseType.MySql);
            var database = new Database(databaseType, dbOptionsAccessor.CurrentValue.ConnectionString);
            _repository = new Repository<ChatRecord>(database);
            _userRepository=new Repository<User>(database);
            _groupChatRepository=new Repository<GroupChat>(database);
            _groupChartUseRepository=new Repository<GroupChatUser>(database);
            _oftenContactRepository=new Repository<OftenContact>(database);
            _fileLibraryRepository=new Repository<FileLibrary>(database);
            _mapper = mapper;
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;

        /// <summary>
        /// 插入聊天信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(ChatRecordInRequest request)
        {
            try
            {
                using (TransactionScope transactionScope = new TransactionScope())
                {
                    var chatRecord = new ChatRecord
                    {
                        ChatType = request.ChatType,
                        Content = request.Content,
                        MsgType = request.MsgType,
                        ReceiveUserId = request.ReceiveUserId,
                        SendUserId = request.SendUserId
                    };
                    //修改界面显示
                    if (request.ChatType == 1)
                    {
                        await _oftenContactRepository.UpdateAsync(Q.Set(nameof(OftenContact.IsDelete), false)
                            .Where(nameof(OftenContact.UserId), request.SendUserId));
                        await _oftenContactRepository.UpdateAsync(Q.Set(nameof(OftenContact.IsDelete), false)
                            .Where(nameof(OftenContact.UserId), int.Parse(request.ReceiveUserId)));
                    }
                    else
                    {
                        await _oftenContactRepository.UpdateAsync(Q.Set(nameof(OftenContact.IsDelete), false)
                            .Where(nameof(OftenContact.ContactUserId), request.ReceiveUserId).Where(nameof(OftenContact.IsDelete),true));
                    }
                    await _repository.InsertAsync(chatRecord);
                    transactionScope.Complete();
                }
            }
            catch (Exception e)
            {
                throw new BusinessException(e.Message);
            }

            return true;
        }

        /// <summary>
        /// 搜索聊天记录
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<PagedList<ChatRecordSearchHistoryResult>> SearchChatRecordHistoryAsync(
            ChatRecordSearchHistoryRequest request)
        {
            var query = Q.NewQuery();
            if (!string.IsNullOrEmpty(request.KeyWord))
            {
                var key = $"%{request.KeyWord}%";
                query.WhereLike(nameof(ChatRecord.Content), key);
                query.Where(nameof(ChatRecord.MsgType), 1);
            }

            if (request.MsgType > 0)
            {
                query.Where(nameof(ChatRecord.MsgType), request.MsgType);
            }

            if (!string.IsNullOrEmpty(request.ReceiveUserId))
            {
                query.OrWhere(nameof(ChatRecord.ReceiveUserId), request.ReceiveUserId);
                query.OrWhere(nameof(ChatRecord.SendUserId), request.ReceiveUserId);
            }

            if (DateTime.TryParse(request.BeginTime, out var beginDateTime))
            {
                if (DateTime.TryParse(request.EndTime, out var endDateTime))
                {
                    if (endDateTime > beginDateTime)
                    {
                        query.WhereDate(nameof(ChatRecord.CreatedDate), ">=", beginDateTime);
                        query.WhereDate(nameof(ChatRecord.CreatedDate), "<=", endDateTime);
                    }
                }
            }

            var result = new PagedList<ChatRecordSearchHistoryResult> {Total = await _repository.CountAsync(query)};
            var chatRecords = await _repository.GetAllAsync(query.OrderByDesc(nameof(ChatRecord.CreatedDate)).ForPage(request.Page,request.PerPage));
            var list=new List<ChatRecordSearchHistoryResult>();
            foreach (var chatRecord in chatRecords)
            {
                var chatRecordSearchHistory = new ChatRecordSearchHistoryResult
                {
                    ChatType = chatRecord.ChatType,
                    MsgType = chatRecord.MsgType,
                    Content = chatRecord.Content,
                    FileUrl = chatRecord.FileUrl,
                    ReceiveUserId = chatRecord.ReceiveUserId
                };
                if (chatRecord.MsgType > 1)
                {
                    if (!string.IsNullOrEmpty(chatRecord.Content))
                    {
                        var fileLibrary = await _fileLibraryRepository.GetAsync(int.Parse(chatRecord.Content));
                        chatRecordSearchHistory.FileUrl = StringUtils.AddDomain(fileLibrary.FileUrl);
                    }
                }
                //查询用户或者群
                if (chatRecord.ChatType == 1)
                {
                    var user =await _userRepository.GetAsync(chatRecord.ReceiveUserId);
                    if (user != null)
                    {
                        chatRecordSearchHistory.Name = user.Name;
                        chatRecordSearchHistory.AvatarUrl = StringUtils.AddDomain(user.AvatarUrl);
                    }
                }
                if (chatRecord.ChatType == 2)
                {
                    var groupChat = await _groupChatRepository.GetAsync(chatRecord.ReceiveUserId);
                    if (groupChat != null)
                    {
                        chatRecordSearchHistory.Name = groupChat.Name;
                        chatRecordSearchHistory.AvatarUrl = StringUtils.AddDomain(groupChat.AvatarUrl);
                    }
                }

                chatRecordSearchHistory.CreatedDate = chatRecord.CreatedDate;
                list.Add(chatRecordSearchHistory);
            }
            result.Items = list;
            return result;
        }


        public async Task<IEnumerable<ChatRecord>> GetAllAsync()
        {
            return await _repository.GetAllAsync();
        }
    }
}
