using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using AutoMapper;
using Dapper;
using Datory;
using GxPress.Common.AppOptions;
using GxPress.Common.Tools;
using GxPress.Entity.WaitHandle;
using GxPress.Repository.Interface.WaitHandle;
using GxPress.Request.App.WaitHandle;
using GxPress.Result.App.WaitHandle;
using Microsoft.Extensions.Options;
using SqlKata;

namespace GxPress.Repository.Implement.WaitHandle
{
    public class WaitHandleRepository : IWaitHandleRepository
    {
        private readonly Repository<Entity.WaitHandle.WaitHandle> _repository;
        private readonly IMapper _mapper;
        private readonly string _connectionString;
        private readonly string _databaseTypeStr;
        public WaitHandleRepository(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<Entity.WaitHandle.WaitHandle>(database);
            _mapper = mapper;
        }

        public IDatabase Database => _repository.Database;
        public string TableName => _repository.TableName;
        public List<TableColumn> TableColumns => _repository.TableColumns;
        public async Task<int> InsertAsync(Entity.WaitHandle.WaitHandle waitHandle)
        {
            return await _repository.InsertAsync(waitHandle);
        }

        public async Task<bool> UpdateAsync(Entity.WaitHandle.WaitHandle waitHandle)
        {
            return await _repository.UpdateAsync(waitHandle);
        }

        public async Task<bool> UpdateAsync(Query query)
        {
            return await _repository.UpdateAsync(query) > 0;
        }

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

        public async Task<bool> DeleteAsync(Query query)
        {
            return await _repository.DeleteAsync(query) > 0;
        }

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

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

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

        public async Task<int> CountAsync(Query query)
        {
            return await _repository.CountAsync(query);
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<WaitHandleListResult> GetAllAsync(ListWaitHandleRequest request)
        {
            var @dateTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
            var waitHandlesSql =
                $@"
                    SELECT 
                        a.*,(SELECT 
                                    COUNT(1)
                                FROM
                                    tede_wait_handle
                                WHERE
                                    DATE_ADD(AlarmTime,
                                        INTERVAL -Minute MINUTE)< NOW() and Id=a.Id and IsFinish=0) IsFinish, b.Title
                    FROM
                        tede_wait_handle a
                            LEFT JOIN
                        tede_wait_handle_label b ON a.LabelId = b.Id
                    WHERE
                        a.UserId = {request.UserId}
                             and a.IsFinish=0";
            var finishWaitHandlesSql =
                $@"SELECT 
                        a.*, b.Title
                    FROM
                        tede_wait_handle a
                            LEFT JOIN
                        tede_wait_handle_label b ON a.LabelId = b.Id
                    WHERE
                        a.UserId = {request.UserId}
                           and a.IsFinish=1";
            var result = new WaitHandleListResult();
            if (request.SearchType == 1)
            {
                waitHandlesSql += " order by a.IsFinish desc";
                finishWaitHandlesSql += " order by a.IsFinish desc";
            }
            else if (request.SearchType == 2)
            {
                waitHandlesSql += " order by a.AlarmTime asc";
                finishWaitHandlesSql += " order by a.IsFinish desc";
            }
            else if (request.SearchType == 3)
            {
                waitHandlesSql += " order by a.LabelId desc";
                finishWaitHandlesSql += " order by a.IsFinish desc";
            }
            else if (request.SearchType == 4)
            {
                waitHandlesSql += " order by a.Level desc";
                finishWaitHandlesSql += " order by a.IsFinish desc";
            }
            else
            {
                waitHandlesSql += " order by a.AlarmTime asc";
                finishWaitHandlesSql += " order by a.AlarmTime desc";
            }

            var databaseType = _databaseTypeStr.ToEnum(DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var waitHandles =
                await connection
                    .QueryAsync<WaitHandleResult, WaitHandleLabel, WaitHandleResult>(waitHandlesSql,
                        (waitHandleResult, waitHandleLabel) =>
                        {
                            waitHandleResult.LabelName = waitHandleLabel != null ? waitHandleLabel.Title : "";
                            return waitHandleResult;
                        }, splitOn: "Title");
            result.WaitHandles = waitHandles;
            var finishWaitHandles =
               await connection
                    .QueryAsync<WaitHandleResult, WaitHandleLabel, WaitHandleResult>(finishWaitHandlesSql,
                        (waitHandleResult, waitHandleLabel) =>
                        {
                            waitHandleResult.LabelName = waitHandleLabel != null ? waitHandleLabel.Title : "未设置";
                            return waitHandleResult;
                        }, splitOn: "Title");
            result.FinishWaitHandles = finishWaitHandles;
            return result;
        }
        public async Task<int> GetUFinishAsync(int userId)
        {
            string sql = $"SELECT count(1) FROM tede_wait_handle WHERE DATE_ADD(AlarmTime,INTERVAL -Minute MINUTE) < NOW() and UserId={userId} and IsFinish=0";
            var databaseType = _databaseTypeStr.ToEnum(DatabaseType.MySql);
            var database = new Database(databaseType, _connectionString);
            var connection = database.GetConnection();
            var count =
                await connection.ExecuteScalarAsync<int>(sql);
            return count;
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Entity.WaitHandle.WaitHandle> GetWaitAsync(int id)
        {
            var waitHandle = await _repository.GetAsync(id);
            if (!string.IsNullOrEmpty(waitHandle.AlarmTime))
            {
                var AlarmTime = DateTime.Parse(waitHandle.AlarmTime);
                var alarmTime = AlarmTime.AddMinutes(-waitHandle.Minute);
                //设置
                if (alarmTime <= System.DateTime.Now)
                {
                    waitHandle.IsFinish = true;
                    await _repository.UpdateAsync(waitHandle);
                }
            }
            return waitHandle;
        }
    }
}