using BPA.Helper;
using BPA.Model;
using BPA.Model.Table;
using BPA.SingleDevice.Interface;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace BPA.SingleDevice.Helper
{
    public class SqlHelper : ISqlHelper
    {
        private volatile static SqlHelper _Instance;
        public static ISqlHelper GetInstance => _Instance ?? (_Instance = new SqlHelper());
        private SqlHelper() { }

        static string path
        {
            get
            {
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory);
                return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AccessFile\\DB\\SingleDevice.db");
            }
        }

        public DbType TempDbType { get; set; } = DbType.Sqlite;
        public string ConnectionStr { get; set; } = $"Data Source={path}";
        public SqlSugarScope Db { get; set; }

        public OperateResult Init(DbType dt = DbType.Sqlite, string connectStr = "")
        {
            try
            {
                TempDbType = dt;
                if (!string.IsNullOrEmpty(connectStr)) ConnectionStr = connectStr;
                if (Db == null)
                    Db = new SqlSugarScope(new ConnectionConfig()
                    {
                        ConnectionString = ConnectionStr,
                        DbType = TempDbType,
                        IsAutoCloseConnection = true,//设置自动关闭连接
                    });

                string spnaName = "BPA.Model.Table";//实体类的命名空间
                Type[] ass = Assembly.LoadFrom(AppContext.BaseDirectory + "BPA.Model.dll").GetTypes().Where(p => p.Namespace == spnaName).ToArray();

                if (TempDbType == DbType.Sqlite && File.Exists(path)) return new OperateResult(true);

                //创建数据库
                Db.DbMaintenance.CreateDatabase();

                //创建数据表
                Db.CodeFirst.SetStringDefaultLength(200).InitTables(ass);

                return new OperateResult(true);
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }

        public async Task<OperateResult> AddAsync<T>(T data) where T : class, new()
        {
            try
            {
                if (Db == null) return new OperateResult("DB 实例为空");
                var res = await Db.Insertable(data).ExecuteCommandAsync() > 0;
                return new OperateResult(res);
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }

        public async Task<OperateResult> AddAsync<T>(List<T> data) where T : class, new()
        {
            try
            {
                if (Db == null) return new OperateResult("DB 实例为空");
                var res = await Db.Insertable(data).ExecuteCommandAsync() > 0;
                return new OperateResult(res);
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }

        public async Task<OperateResult> UpdateAsync<T>(T data) where T : SqlBase, new()
        {
            try
            {
                if (Db == null) return new OperateResult("DB 实例为空");
                var res = await Db.Updateable(data).ExecuteCommandAsync() > 0;
                return new OperateResult(res);
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }

        public async Task<OperateResult> DeleteAsync<T>(string id) where T : SqlBase, new()
        {
            try
            {
                if (Db == null) return new OperateResult("DB 实例为空");
                var removeList = await Db.Queryable<T>().Where(p => p.Id == id).ToListAsync();
                if (removeList != null)
                {
                    var res = await Db.Deleteable(removeList).ExecuteCommandHasChangeAsync();
                    return new OperateResult(res);
                }
                else
                {
                    return new OperateResult("未找到需要移除的信息");
                }
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }

        public async Task<OperateResult<List<T>>> GetListAsync<T>()
        {
            OperateResult<List<T>> result = new OperateResult<List<T>>();
            try
            {
                if (Db == null) return new OperateResult<List<T>>("DB 实例为空");
                result.Content = await Db.Queryable<T>().ToListAsync();
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                result.SetMsg(ex.ToString());
            }
            return result;
        }

        public async Task<OperateResult<List<RecipeRawMaterTB>>> GetRawMaterIds(string RecipeId)
        {
            OperateResult<List<RecipeRawMaterTB>> result = new OperateResult<List<RecipeRawMaterTB>>();
            try
            {
                if (Db == null) return new OperateResult<List<RecipeRawMaterTB>>("DB 实例为空");
                var res = await Db.Queryable<RecipeRawMaterTB>().Where(p => p.RecipeId == RecipeId).ToListAsync();
                if (res != null)
                {
                    result.Content = res;
                    result.IsSuccess = true;
                }
                else { result.SetMsg("查询数据为空"); }
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                result.SetMsg(ex.ToString());
            }
            return result;
        }

        public async Task<OperateResult> DeleteRawMaterAsync(string id)
        {
            try
            {
                if (Db == null) return new OperateResult("DB 实例为空");
                var removeList = await Db.Queryable<RecipeRawMaterTB>().Where(p => p.RecipeId == id).ToListAsync();
                if (removeList != null)
                {
                    var res = await Db.Deleteable(removeList).ExecuteCommandHasChangeAsync();
                    return new OperateResult(res);
                }
                else
                {
                    return new OperateResult("未找到需要移除的信息");
                }
            }
            catch (Exception ex)
            {
                MessageLog.GetInstance.Show(ex.ToString());
                return new OperateResult(ex.ToString());
            }
        }
    }
}
