using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Text;
using Dapper;
using System.IO;
using Microsoft.Extensions.Configuration;
using AutoTurnOver.Utility;
using System.Data;
using AutoTurnOver.Models.Base;
using AutoTurnOver.DB.Base;
using System.Threading.Tasks;

namespace AutoTurnOver.DB
{
    public class connectionHelper
    {
        public static string _connStr = null;

        public static MyMySqlConnection _connection
        {
            get
            {
                return new MyMySqlConnection();
            }
        }

        public static string connStr
        {
            get
            {
                if (!string.IsNullOrWhiteSpace(_connStr))
                {
                    return _connStr;
                }
                else
                {
                    _connStr = ConfigHelper.ConnectionString("Default");
                    return _connStr;
                }
            }
        }
    }

    public class MyMySqlConnection : IDisposable
    {
        void IDisposable.Dispose()
        {
            _connection.Dispose();
        }


        public static MySqlConnection _connection
        {
            get
            {
               return new MySqlConnection(ConfigHelper.ConnectionString("Default"));
            }
        }
        public static MySqlConnection _connection_read_only
        {
            get
            {
                return new MySqlConnection(ConfigHelper.ConnectionString("ReadOnly"));

            }
        }

        public void Open()
        {
            _connection.Open();
        }
        public void Close()
        {
            _connection.Close();
        }
        public int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection.Execute(sql, param, transaction, commandTimeout, commandType);
        }
        public int Update<TEntity>(TEntity entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return _connection.Update(entityToUpdate, transaction, commandTimeout);
        }

        public int Delete<T>(T entityToDelete, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return _connection.Delete<T>(entityToDelete, transaction, commandTimeout);
        }
        
        public int Delete<T>(object id, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return _connection.Delete<T>(id, transaction, commandTimeout);
        }
        public int? Insert<TEntity>(TEntity entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null)
        {
            return _connection.Insert(entityToInsert, transaction, commandTimeout);
        }
        public IEnumerable<T> Query<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.Query<T>(sql, param, transaction, buffered, commandTimeout, commandType);
        }
        public T QuerySingleOrDefault<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QuerySingleOrDefault<T>(sql, param, transaction, commandTimeout, commandType);
        }
       
        public dynamic QueryFirstOrDefault(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QuerySingleOrDefault(sql, param, transaction, commandTimeout, commandType);
        }
        public T QueryFirstOrDefault<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QueryFirstOrDefault<T>(sql, param, transaction, commandTimeout, commandType);
        }  
        public Task<T> QueryFirstOrDefaultAsync<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QueryFirstOrDefaultAsync<T>(sql, param, transaction, commandTimeout, commandType);
        }
        public T ExecuteScalar<T>( string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection.ExecuteScalar<T>(sql, param, transaction, commandTimeout, commandType);
        }
        public T QueryFirst<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QueryFirst<T>(sql, param, transaction, commandTimeout, commandType);
        }
        public Task<IEnumerable<T>> QueryAsync<T>(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
        {
            return _connection_read_only.QueryAsync<T>(sql, param, transaction, commandTimeout, commandType);
        }

        public MySqlTransaction BeginTransaction()
        {
            return _connection.BeginTransaction();
        }

        public Page<T> Page<T>(string sql, page_search_dto search_data, object param = null, int? commandTimeout = null, bool isCount = true)
        {
            return _connection_read_only.Page<T>(sql, search_data, param, commandTimeout, isCount);
        }

        public IEnumerable<T> Page<T>(int offset, int limit, string strsql, ref int total, object param = null)
        {
            return _connection_read_only.Page<T>(offset, limit, strsql, ref total, param);
        }


    }
}
