using Models;
using MySql.Data.MySqlClient;
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 Service
{
    public class InitDB
    {
        public static string ConnectionString;
        public static void initDB(bool dropTable=false)
        {
            ConnectionConfig connectionConfig = new ConnectionConfig() {
                ConnectionString = ConnectionString,
                DbType = DbType.MySql,
                IsAutoCloseConnection = true
            };
            //创建数据库对象
            using (SqlSugarClient db = new SqlSugarClient(connectionConfig))
            {
                db.Aop.OnLogExecuting = (sql, pars) =>
                {
                    Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响 
                };

                //create db
                db.DbMaintenance.CreateDatabase();
                //db.DbMaintenance.TruncateTable<Order>();//删除记录
                //===建表
                if (dropTable && db.DbMaintenance.IsAnyTable("Classes", false)) db.DbMaintenance.DropTable("Classes");
                if (dropTable && db.DbMaintenance.IsAnyTable("Right", false)) db.DbMaintenance.DropTable("Right");
                if (dropTable && db.DbMaintenance.IsAnyTable("Role", false)) db.DbMaintenance.DropTable("Role");
                if (dropTable && db.DbMaintenance.IsAnyTable("RoleRightMap", false)) db.DbMaintenance.DropTable("RoleRightMap");
                if (dropTable && db.DbMaintenance.IsAnyTable("User", false)) db.DbMaintenance.DropTable("Users");
                if (dropTable && db.DbMaintenance.IsAnyTable("Step", false)) db.DbMaintenance.DropTable("Steps");
                if (dropTable && db.DbMaintenance.IsAnyTable("StepProcess", false)) db.DbMaintenance.DropTable("StepProcess");
                if (dropTable && db.DbMaintenance.IsAnyTable("Product", false)) db.DbMaintenance.DropTable("Product");
                if (dropTable && db.DbMaintenance.IsAnyTable("Attachment", false)) db.DbMaintenance.DropTable("Attachment");
                if (dropTable && db.DbMaintenance.IsAnyTable("BatchHistory", false)) db.DbMaintenance.DropTable("BatchHistory");
                if (dropTable && db.DbMaintenance.IsAnyTable("QualifiedCriterion", false)) db.DbMaintenance.DropTable("QualifiedCriterion");
                if (dropTable && db.DbMaintenance.IsAnyTable("ProductReviseProcess", false)) db.DbMaintenance.DropTable("ProductReviseProcess");//????ProductReviseProcessList
                if (dropTable && db.DbMaintenance.IsAnyTable("ProductAssistProcess", false)) db.DbMaintenance.DropTable("ProductAssistProcess");
                if (dropTable && db.DbMaintenance.IsAnyTable("Order", false)) db.DbMaintenance.DropTable("Order");
                if (dropTable && db.DbMaintenance.IsAnyTable("OrderHistory", false)) db.DbMaintenance.DropTable("OrderHistory");
                if (dropTable && db.DbMaintenance.IsAnyTable("SizeTagData", false)) db.DbMaintenance.DropTable("SizeTagData");
                if (dropTable && db.DbMaintenance.IsAnyTable("DefectInfo", false)) db.DbMaintenance.DropTable("DefectInfo");

                //===添加与更新表
                db.CodeFirst.InitTables<Models.Classes>();
                db.CodeFirst.InitTables<Models.Right>();
                db.CodeFirst.InitTables<Models.Role>();
                db.CodeFirst.InitTables<Models.RoleRightMap>();
                db.CodeFirst.InitTables<Models.User>();
                db.CodeFirst.InitTables<Models.Step>();
                db.CodeFirst.InitTables<Models.StepProcess>();
                db.CodeFirst.InitTables<Models.Product>();
                db.CodeFirst.InitTables<Models.Attachment>();
                db.CodeFirst.InitTables<Models.BatchHistory>();
                db.CodeFirst.InitTables<Models.QualifiedCriterion>();
                db.CodeFirst.InitTables<Models.ProductProcess>();
                db.CodeFirst.InitTables<Models.ProductReviseProcess>();
                db.CodeFirst.InitTables<Models.ProductAssistProcess>();
                db.CodeFirst.InitTables<Models.Order>();
                db.CodeFirst.InitTables<Models.OrderHistory>();
                db.CodeFirst.InitTables<Models.SizeTagData>();
                db.CodeFirst.InitTables<Models.DefectInfo>();

                //更新新列数据 
                //db.Ado.ExecuteCommand("update Step set Tag=0 where Tag is null"); 
                //try
                //{
                //    db.Ado.ExecuteCommand("ALTER TABLE Product DROP COLUMN HoleCountId");
                //}
                //catch { }
                //try { 
                //    db.Ado.ExecuteCommand("ALTER TABLE Product DROP COLUMN HoleCount");
                //}
                //catch { }
                //===初始数据 注意*********会清空这些表数据
                //User
                db.DbMaintenance.TruncateTable<User>();
                db.DbMaintenance.TruncateTable<Role>();
                if (db.Queryable<Models.User>().Count() < 1)
                {
                    //db.Insertable(new Models.User() { Code = "admin", Name = "管理员", RoleId = id }).ExecuteCommand();
                    db.InsertNav(new Models.User()
                    {
                        Code = "admin",
                        Name = "管理员",
                        Password = GetMD5(""),
                        RoleInfo = new Models.Role() { Code = "admin", Name = "管理员", ModifyUserCode = "admin", CreateUserCode = "admin" },//多表添加
                        CreateUserCode = "admin",
                        ModifyUserCode = "admin",
                    }).Include(x => x.RoleInfo)
                    .ExecuteCommand();
                }
                //===权限  
                db.DbMaintenance.TruncateTable<RoleRightMap>();
                db.DbMaintenance.TruncateTable<Right>();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "Step").Count() < 1) db.Insertable(new Models.Right("Step", "流程管理")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "Product").Count() < 1) db.Insertable(new Models.Right("Product", "产品管理")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "Debug").Count() < 1) db.Insertable(new Models.Right("Debug", "设备调试")).ExecuteCommand();

                if (db.Queryable<Models.Right>().Where(m => m.Code == "Order").Count() < 1) db.Insertable(new Models.Right("Order", "报表查询")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "Statistics").Count() < 1) db.Insertable(new Models.Right("Statistics", "统计分析")).ExecuteCommand();

                if (db.Queryable<Models.Right>().Where(m => m.Code == "Role").Count() < 1) db.Insertable(new Models.Right("Role", "角色管理")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "User").Count() < 1) db.Insertable(new Models.Right("User", "用户管理")).ExecuteCommand();
                //if (db.Queryable<Models.Right>().Where(m => m.Code == "Right").Count() < 1) db.Insertable(new Models.Right("Right", "权限管理")).ExecuteCommand();

                if (db.Queryable<Models.Right>().Where(m => m.Code == "HeightBase").Count() < 1) db.Insertable(new Models.Right("HeightBase", "高度Base校正")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "SysSetting").Count() < 1) db.Insertable(new Models.Right("SysSetting", "系统设置")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "CmdSetting").Count() < 1) db.Insertable(new Models.Right("CmdSetting", "指令设置")).ExecuteCommand();
                if (db.Queryable<Models.Right>().Where(m => m.Code == "PTSetting").Count() < 1) db.Insertable(new Models.Right("PTSetting", "点位设置")).ExecuteCommand();

                //==触发器
                string rootPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                string sqlPath = rootPath + "\\SqlPath\\";
                if (Directory.Exists(sqlPath))
                {
                    int count;
                    string triggerName = "trigger_order_update";
                    if (File.Exists(sqlPath + triggerName+".sql"))
                    {
                        count = db.Ado.GetInt($"SELECT count(*) FROM information_schema.TRIGGERS where TRIGGER_NAME = '{triggerName}'");
                        if (count > 0)
                            db.Ado.ExecuteCommand($"drop trigger {triggerName}");
                        db.Ado.ExecuteCommand(File.ReadAllText(sqlPath + triggerName + ".sql"));
                    }
                }

                //==清理垃圾数据
                db.Ado.ExecuteCommand($"delete from `Order` where ProductId not in (select id from product)");
            }
        }
        /// <summary>
        /// 备份DB (还原：mysql -uroot -p < d:\dbName.sql)
        /// </summary>
        /// <param name="result"></param>
        public static void BackupDataBase(string outFilePath)
        {
            using (var conn = new MySqlConnection(ConnectionString))
            {
                using (var cmd = new MySqlCommand())
                {
                    using (MySqlBackup mb = new MySqlBackup(cmd))
                    {
                        // 设置数据库连接
                        cmd.Connection = conn;
                        cmd.Connection.Open();
                        // 导出数据库到文件
                        mb.ExportToFile(outFilePath);
                        conn.Close();
                    }
                }
            }
        } 
        private static string GetMD5(string str)
        {
            byte[] data = Encoding.UTF8.GetBytes(str);
            data = new System.Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(data);

            string ret = "";
            for (int i = 0; i < data.Length; i++)
            {
                ret += data[i].ToString("x1").PadLeft(2, '0');//ToString("x1"):转换为16进制
            }
            return ret.ToUpper();
        }
    }
}
