using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using GxPress.Common.AppOptions;
using GxPress.Common.Exceptions;
using GxPress.Common.Tools;
using GxPress.Entity;
using GxPress.Repository.Interface;
using GxPress.Request.GroupChatUser;
using GxPress.Result.GroupChatUser;
using Microsoft.Extensions.Options;
using Datory;
using GroupChatUser = GxPress.Entity.GroupChatUser;
using Dapper;

namespace GxPress.Repository.Implement
{
    public class GroupChatUserRepository : IGroupChatUserRepository
    {
        private readonly Repository<GroupChatUser> _repository;
        private readonly Repository<GroupChat> _groupChatRepository;
        private readonly Repository<User> _userRepository;
        private readonly Repository<OftenContact> _oftenContactRepository;
        private readonly IMapper _mapper;
        private readonly Repository<Entity.Middle.Middle> _middleRepository;
        private readonly string _connectionString;
        private readonly string _databaseTypeStr;
        public GroupChatUserRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IMapper mapper)
        {
            _databaseTypeStr = dbOptionsAccessor.CurrentValue.DatabaseType;
            _connectionString = dbOptionsAccessor.CurrentValue.ConnectionString;
            var databaseType = StringUtils.ToEnum<DatabaseType>(dbOptionsAccessor.CurrentValue.DatabaseType, DatabaseType.MySql);
            var database = new Database(databaseType, dbOptionsAccessor.CurrentValue.ConnectionString);
            _repository = new Repository<GroupChatUser>(database);
            _groupChatRepository = new Repository<GroupChat>(database);
            _userRepository = new Repository<User>(database);
            _oftenContactRepository = new Repository<OftenContact>(database);
            _middleRepository = new Repository<Entity.Middle.Middle>(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(GroupChatUserInRequest request)
        {
            var user = await _userRepository.GetAsync(request.UserId);
            if (user == null)
                throw new BusinessException("用户不存在");
            var groupChat = await _groupChatRepository.GetAsync(request.GroupChatId);
            if (groupChat == null)
                throw new BusinessException("群不存在");
            //查询用户是否存在
            var groupChatUser = await _repository.GetAsync(Q
                .Where(nameof(GroupChatUser.GroupChatId), request.GroupChatId)
                .Where(nameof(GroupChatUser.UserId), request.UserId));
            if (groupChatUser == null)
                throw new BusinessException("用户已经添加过了");
            var groupChatUserEntity = new GroupChatUser
            {
                GroupChatId = request.GroupChatId,
                UserId = request.UserId,
                ImId = request.GroupChartImId
            };
            //添加用户

            var oftenContact = new OftenContact
            {
                ChatType = 2,
                ContactUserId = request.GroupChartImId,
                IndividualGroupId = 0,
                UserId = request.UserId
            };
            await _oftenContactRepository.InsertAsync(oftenContact);

            return await _repository.InsertAsync(groupChatUserEntity) > 0;
        }

        /// <summary>
        /// 添加多个
        /// </summary>
        /// <param name="groupChatUsers"></param>
        /// <returns></returns>
        public async Task<bool> InsertAsync(List<GroupChatUser> groupChatUsers)
        {
            if (groupChatUsers.Count == 0 || groupChatUsers == null)
                return false;
            string sql = $@"INSERT INTO `ccpph`.`tede_group_chat_user`(`Guid`,`CreatedDate`,`LastModifiedDate`,`GroupChatId`,`UserId`,`IsDisturb`,`IsTop`,`ImId`,`IsAdmin`,`GroupChatImId`)VALUES";
            var guId = Guid.NewGuid().ToString();
            var nowTime = System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            foreach (var item in groupChatUsers)
            {
                var IsDisturb = item.IsDisturb ? 1 : 0;
                var IsTop = item.IsTop ? 1 : 0;
                var IsAdmin = item.IsAdmin ? 1 : 0;
                sql += $@"('{guId}','{nowTime}','{nowTime}','{item.GroupChatId}',{item.UserId}, {IsDisturb},{IsTop},'{item.ImId}',{IsAdmin},'{item.GroupChatImId}'),";
            }
            sql = sql.Remove(sql.Length - 1, 1);
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            return await connection.ExecuteAsync(sql) > 0;
        }


        /// <summary>
        /// 修改数据
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> UpdateAsync(GroupChatUserUpRequest request)
        {
            throw new NotImplementedException();
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteAsync(int id)
        {
            return await _repository.DeleteAsync(id);
        }


        /// <summary>
        /// 根据群ID获取群用户
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IEnumerable<GroupChatUserByGroupChatIdResult>> GetGroupChatUserByGroupChatIdAsync(GroupChatUserSearchRequest request)
        {
            var sql = $"SELECT a.*,b.Name,b.AvatarUrl FROM ccpph.tede_group_chat_user a inner join ccpph.tede_user b on a.UserId=b.Id  where a.GroupChatImId='{request.GroupChatImId}'";
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection
                .QueryAsync<GroupChatUserByGroupChatIdResult, User, GroupChatUserByGroupChatIdResult>(sql,
                    (groupChatUserByGroupChatIdResult, user) =>
                    {
                        groupChatUserByGroupChatIdResult.UserName = user.Name;
                        groupChatUserByGroupChatIdResult.AvatarUrl = user != null ? StringUtils.AddDomainMin(user.AvatarUrl) : "";
                        return groupChatUserByGroupChatIdResult;
                    },
                    splitOn: "Name");
            return items;
        }
        /// <summary>
        /// 是否免打扰
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> UpIsDisturbAsync(GroupChatUserIsDisturbRequest request)
        {
            //获取群
            var groupChat = await _groupChatRepository.GetAsync(request.GroupChatId);
            if (groupChat == null)
                throw new BusinessException("群已经解散");
            var groupChatUser = await _repository.GetAsync(Q.Where(nameof(GroupChatUser.GroupChatId), request.GroupChatId).Where(nameof(GroupChatUser.UserId), request.UserId));
            if (groupChatUser == null)
                throw new BusinessException("用户不在群里面");
            groupChatUser.IsDisturb = !groupChatUser.IsDisturb;
            return await _repository.UpdateAsync(groupChatUser);
        }

        /// <summary>
        /// 是否置顶
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> UpIsTopAsync(GroupChatUserIsTopRequest request)
        {
            //获取群
            var groupChat = await _groupChatRepository.GetAsync(request.GroupChatId);
            if (groupChat == null)
                throw new BusinessException("群已经解散");
            var oftenContact = await _oftenContactRepository.GetAsync(Q.Where(nameof(Entity.OftenContact.UserId), request.UserId).Where(nameof(Entity.OftenContact.ContactUserId), groupChat.GroupChatImId));
            if (oftenContact == null)
                return false;
            return await _middleRepository.UpdateAsync(Q.Set(nameof(Entity.Middle.Middle.IsTop), request.IsTop).Where(nameof(Entity.Middle.Middle.UserId), request.UserId).Where(nameof(Entity.Middle.Middle.MiddleId), oftenContact.Id).Where(nameof(Entity.Middle.Middle.FolderType), 10)) > 0;
        }
        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<GroupChatUser> FindGroupChatUserByIdAsync(int id)
        {
            return await _repository.GetAsync(id);
        }

        /// <summary>
        /// 根据群IMID获取用户
        /// </summary>
        /// <param name="imId"></param>
        /// <returns></returns>
        public async Task<IEnumerable<GroupChatUser>> FindGroupChatUserByImId(string imId)
        {
            var groupChat = await _groupChatRepository.GetAsync(Q.Where(nameof(GroupChat.GroupChatImId), imId));
            return await _repository.GetAllAsync(Q.Where(nameof(GroupChatUser.GroupChatId), groupChat.Id).Where(nameof(GroupChatUser.IsAdmin), false));
        }

        /// <summary>
        /// 是否免打扰
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<bool> IsDisturbAsync(GroupChatUserIsDisturbRequest request)
        {
            //获取群
            var groupChat = await _groupChatRepository.GetAsync(request.GroupChatId);
            if (groupChat == null)
                throw new BusinessException("群已经解散");
            var groupChatUser = await _repository.GetAsync(Q.Where(nameof(GroupChatUser.GroupChatId), request.GroupChatId).Where(nameof(GroupChatUser.UserId), request.UserId));
            if (groupChatUser == null)
                return false;
            return groupChatUser.IsDisturb;
        }

        public async Task<IEnumerable<GroupChatUser>> GetAllAsync(SqlKata.Query query)
        {
            return await _repository.GetAllAsync(query);
        }

        public async Task<int> InsertAsync(GroupChatUser groupChatUser)
        {
            return await _repository.InsertAsync(groupChatUser);
        }
    }
}