using System.Collections.Generic;
using System.Threading.Tasks;
using Datory;
using GxPress.Common.AppOptions;
using GxPress.Common.Tools;
using GxPress.Entity.WorkMeeting;
using GxPress.Repository.Interface.WorkMeeting;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using System;
using System.Linq;
using GxPress.Request.App.WorkMeeting;
using Dapper;

namespace GxPress.Repository.Implement.WorkMeeting
{
    public class MeetingRepository : IMeetingRepository
    {
        private readonly Repository<Meeting> _repository;
        private readonly IMeetingOrderRepository _meetingOrderRepository;
        private readonly Repository<Entity.WorkMeeting.MeetingSummaryTodo> meetingSummaryTodoRepository;
        private readonly string _connectionString;
        private readonly string _databaseTypeStr;


        public MeetingRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IDistributedCache cache, IMeetingOrderRepository meetingOrderRepository)
        {
            _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<Meeting>(database, cache);
            meetingSummaryTodoRepository = new Repository<Entity.WorkMeeting.MeetingSummaryTodo>(database);
            _meetingOrderRepository = meetingOrderRepository;
        }

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

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

        public async Task<bool> UpdateAsync(Meeting item)
        {
            return await _repository.UpdateAsync(item);
        }

        public async Task<IEnumerable<Meeting>> GetCurrentListAsync(int userId, string keyword)
        {
            var query = new SqlKata.Query();
            var meetingSummaryTodos = await meetingSummaryTodoRepository.GetAllAsync(Q.Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.UserId), userId).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.TypeId), 1));
            query.Where(q => q.WhereIn(nameof(Meeting.Id), meetingSummaryTodos.Select(n => n.MeetingSummaryId)));
            query.Where(nameof(Meeting.EndDateTime), ">", DateTime.Now)
             .OrderByDesc(nameof(Meeting.CreatedDate));
            if (!string.IsNullOrEmpty(keyword))
            {
                query.Where(q => q
                    .WhereLike(nameof(Meeting.Name), $"%{keyword}%")
                    .OrWhereLike(nameof(Meeting.Description), $"%{keyword}%")
                );
            }
            return await _repository.GetAllAsync(query);
        }

        public async Task<IEnumerable<Meeting>> GetHistoryListAsync(int userId, string keyword, int page = 1, int perPage = 10)
        {
            var sql = $@"select * from tede_meeting where Id in( select MeetingSummaryId from  tede_meeting_summary_todo  where TypeId=1 and UserId={userId}) and EndDateTime<'{DateTime.Now}'";
            if (!string.IsNullOrWhiteSpace(keyword))
                sql += $" and (Name like '%{keyword}%' or Description like '%{keyword}%')";
            sql += $" limit {(page - 1) * perPage},{perPage}";
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection
                .QueryAsync<Meeting>(sql);
            return items;
        }

        public async Task<Meeting> GetAsync(int meetingId)
        {
            return await _repository.GetAsync(meetingId);
        }

        public async Task<bool> DeleteAsync(int meetingId)
        {
            await _meetingOrderRepository.DeleteByMeetingIdAsync(meetingId);
            //删除关联用户
            await meetingSummaryTodoRepository.DeleteAsync(Q.Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.TypeId), 1).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.MeetingSummaryId), meetingId));
            return await _repository.DeleteAsync(meetingId);
        }

        public async Task DeleteByRoomIdAsync(int roomId)
        {
            await _repository.DeleteAsync(Q.Where(nameof(Meeting.RoomId), roomId));
        }
        /// <summary>
        /// 获取会议人员
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<IEnumerable<MeetingUserResult>> GetUserByMeeting(MeetingUsersRequest request)
        {
            string sql = $"select * from ccpph.tede_user where Id in(select UserId from ccpph.tede_meeting_summary_todo where TypeId=1 and MeetingSummaryId={request.MeetingId})";
            if (!string.IsNullOrWhiteSpace(request.KeyWord))
            {
                sql += $" AND (Name like '%{request.KeyWord}%' or Phone like '%{request.KeyWord}%')";
            }

            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var items = await connection
                .QueryAsync<MeetingUserResult>(sql);
            foreach (var item in items)
                item.AvatarUrl = StringUtils.AddDomainMin(item.AvatarUrl);
            return items;
        }
    }
}