using Dapper;
using DapperExtensions;
using MWS.Data.InterFace;
using MWS.Library;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;

namespace MWS.Data.Manager
{
    /// <summary>
    /// dapper 帮助类
    /// </summary>
    public class DapperHelper<T> : IDapperHelper, IDisposable
    {
        private readonly Database Connection = null;

        public DapperHelper(DatabaseType databaseType = DatabaseType.MySql)
        {
            Connection = ConnectionFactory.CreateConnection(databaseType);
        }
        public Database GetConnection()
        {
            return Connection;
        }
        public IDbTransaction TranStart()
        {
            if (Connection.Connection.State == ConnectionState.Closed)
            {
                Connection.Connection.Open();
            }

            return Connection.Connection.BeginTransaction();
        }
        public void TranRollBack(IDbTransaction tran)
        {
            tran.Rollback();
            if (Connection.Connection.State == ConnectionState.Open)
            {
                tran.Connection.Close();
            }
        }
        public void TranCommit(IDbTransaction tran)
        {
            tran.Commit();
            if (Connection.Connection.State == ConnectionState.Open)
            {
                tran.Connection.Close();
            }
        }

        public bool Delete<T>(T obj, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {
            return Connection.Delete(obj, tran, commandTimeout);
        }
        public bool Delete<T>(dynamic primaryId, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {
            var entity = Get<T>(primaryId);
            var obj = entity as T;
            return Connection.Delete<T>(obj, tran, commandTimeout);
        }
        public bool Delete<T>(IEnumerable<T> list, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {

            return Connection.Delete(list, tran, commandTimeout);
        }
        public void Dispose()
        {
            if (Connection != null)
            {
                Connection.Dispose();
            }
        }
        public T Get<T>(dynamic id, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {
            return Connection.Get<T>(id, tran, commandTimeout);
        }

        public IEnumerable<T> GetAll<T>(object predicate = null, IList<ISort> sort = null, IDbTransaction tran = null, int? commandTimeout = null, bool buffered = true) where T : class
        {
            return Connection.GetList<T>(predicate, sort, tran, commandTimeout, buffered);
        }
        public IEnumerable<T> GetPage<T>(object predicate, IList<ISort> sort, int page, int pagesize, out int totalCount, IDbTransaction tran = null, int? commandTimeout = null, bool buffered = true) where T : class
        {
            totalCount = Connection.Count<T>(predicate, commandTimeout);
            return Connection.GetPage<T>(predicate, sort, page - 1, pagesize, tran, commandTimeout, buffered);
        }
        public dynamic Insert<T>(T obj, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {
            return Connection.Insert(obj, tran, commandTimeout);
        }

        public void Insert<T>(IEnumerable<T> list, IDbTransaction tran = null, int? commandTimeout = null) where T : class
        {
            Connection.Insert(list, tran, commandTimeout);
        }
        public bool Update<T>(T obj, IDbTransaction tran = null, int? commandTimeout = null, bool ignoreAllKeyProperties = true) where T : class
        {
            return Connection.Update(obj, tran, commandTimeout, ignoreAllKeyProperties);
        }

        public bool Update<T>(IEnumerable<T> list, IDbTransaction tran = null, int? commandTimeout = null, bool ignoreAllKeyProperties = true) where T : class
        {
            return Connection.Update(list, tran, commandTimeout, ignoreAllKeyProperties);
        }
        public List<T> Query<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        {
            return Connection.Connection.Query<T>(sql, param, transaction, buffered, commandTimeout, commandType).AsList();
        }
        public SqlMapper.GridReader QueryMultiple(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        {
            return Connection.Connection.QueryMultiple(sql, param, transaction, commandTimeout, commandType);
        }
        //public int Execute<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        //{
        //    return Connection.Connection.Execute(sql, param, transaction, commandTimeout, commandType);

        //}
        public int Execute<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        {
            try
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                var result = Connection.Connection.Execute(sql, param, transaction, 120, commandType);
                stopwatch.Stop();
                Console.WriteLine(stopwatch.ElapsedMilliseconds);
                return result;
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog("错误日志：" + ex.Message);
                LogHelper.WriteLog("保存sql：" + sql);
                return 0;
            }
           
        }

        public object ExecuteScalar<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return Connection.Connection.ExecuteScalar(sql, param, transaction, commandTimeout, commandType);
        }
    }
}
