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 SqlKata;
using System.Linq;
using GxPress.Request.App.WorkMeeting;
using Dapper;

namespace GxPress.Repository.Implement.WorkMeeting
{
    public class MeetingSummaryRepository : IMeetingSummaryRepository
    {
        private readonly Repository<MeetingSummary> _repository;
        private readonly Repository<Entity.WorkMeeting.MeetingSummaryTodo> meetingSummaryTodoRepository;
        private readonly string _connectionString;
        private readonly string _databaseTypeStr;
        public MeetingSummaryRepository(IOptionsMonitor<DatabaseOptions> dbOptionsAccessor, IDistributedCache cache)
        {
            _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<MeetingSummary>(database, cache);
            meetingSummaryTodoRepository = new Repository<Entity.WorkMeeting.MeetingSummaryTodo>(database);
        }

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

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

        public async Task UpdateAsync(MeetingSummary item)
        {
            await _repository.UpdateAsync(item);
        }

        public async Task<IEnumerable<MeetingSummary>> GetListAsync(string keyword, int userId, int typeId, int meetingId, int page = 1, int perPage = 10)
        {
            // var query = Q.Where(nameof(MeetingSummary.UserId), userId);
            //if (!string.IsNullOrEmpty(keyword))
            //{
            //    query.Where(q => q
            //        .WhereLike(nameof(MeetingSummary.Title), $"%{keyword}%")
            //        .OrWhereLike(nameof(MeetingSummary.Content), $"%{keyword}%")
            //    );
            //}
            var query = new SqlKata.Query();
            if (typeId == 1)
            {
                var meetingSummaryTodos = await meetingSummaryTodoRepository.GetAllAsync(Q.Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.UserId), userId).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.IsAdmin), true).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.TypeId), 2));
                query.Where(q => q.WhereIn(nameof(MeetingSummary.Id), meetingSummaryTodos.Select(n => n.MeetingSummaryId)));
            }
            else if (typeId == 2)
            {
                var meetingSummaryTodos = await meetingSummaryTodoRepository.GetAllAsync(Q.Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.UserId), userId).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.IsAdmin), false).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.TypeId), 2));
                query.Where(q => q.WhereIn(nameof(MeetingSummary.Id), meetingSummaryTodos.Select(n => n.MeetingSummaryId)));
            }
            else if (meetingId > 0)
            {
                query.Where(q => q.Where(nameof(MeetingSummary.MeetingId), meetingId));
            }
            else
            {
                var meetingSummaryTodos = (await meetingSummaryTodoRepository.GetAllAsync(Q.Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.UserId), userId).Where(nameof(Entity.WorkMeeting.MeetingSummaryTodo.TypeId), 2))).ToList();
                query.Where(q => q.WhereIn(nameof(MeetingSummary.Id), meetingSummaryTodos.Select(n => n.MeetingSummaryId)));
            }
            if (!string.IsNullOrEmpty(keyword))
            {
                query.Where(q => q
                    .WhereLike(nameof(MeetingSummary.Title), $"%{keyword}%")
                    .OrWhereLike(nameof(MeetingSummary.Content), $"%{keyword}%")
                );
            }
            // return await _repository.GetAllAsync(query);
            return await _repository.GetAllAsync(query.OrderByDesc(nameof(MeetingSummary.Id)));
        }
        /// <summary>
        /// 会议列表
        /// </summary>
        /// <param name="keyword"></param>
        /// <param name="userId"></param>
        /// <param name="typeId"></param>
        /// <param name="meetingId"></param>
        /// <param name="page"></param>
        /// <param name="perPage"></param>
        /// <returns></returns>
        public async Task<IEnumerable<MeetingSummaryResult>> GetListMeetingSummaryResultAsync(string keyword, int userId, int typeId, int meetingId, int page = 1, int perPage = 10)
        {
            var sql = $@"SELECT 
                                a.*,(select Address from ccpph.tede_meeting_location where Id=e.Id) as Address,(select Name from ccpph.tede_meeting where Id=a.MeetingId) as MeetingName,(select Name from ccpph.tede_user where Id=a.UserId) as UserName
                            FROM
                                ccpph.tede_meeting_summary a
                                    INNER JOIN
                                ccpph.tede_meeting_summary_todo b ON a.Id = b.MeetingSummaryId
                                    INNER JOIN
                                ccpph.tede_meeting c ON a.MeetingId = c.Id
                                    INNER JOIN
                                ccpph.tede_meeting_room d ON c.RoomId = d.Id
                                    INNER JOIN
                                ccpph.tede_meeting_location e ON d.LocationId = e.Id
                            WHERE
                                b.UserId = {userId}";
            if (typeId == 1)
                sql += $" AND b.IsAdmin =1 and a.UserId={userId}";
            if (typeId == 2)
                sql += $" AND b.IsAdmin =0 and a.UserId<>{userId}";
            if (meetingId > 0)
                sql += $@" AND a.MeetingId ={meetingId}";
            if (!string.IsNullOrWhiteSpace(keyword))
                sql += $@" AND a.Title LIKE '%{keyword}%'";
            sql += $@" order by a.CreatedDate desc limit {(page - 1) * perPage},{perPage}";
            var databaseType = StringUtils.ToEnum<DatabaseType>(_databaseTypeStr, DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var result =
                await connection
                    .QueryAsync<MeetingSummaryResult>(sql);
            return result;
        }

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

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

        public async Task DeleteByRoomIdAsync(int roomId)
        {
            await _repository.DeleteAsync(Q.Where(nameof(MeetingSummary.RoomId), roomId));
        }

        public async Task<MeetingSummary> GetAsync(Query query)
        {
            return await _repository.GetAsync(query);
        }
    }
}