using System.Data;
using System.IO;
using System.Reflection;
using log4net;
using log4net.Repository.Hierarchy;
using Microsoft.Data.Sqlite;

namespace SparkClient.Model.Helper;
/// <summary>
/// SqLite工具类
/// </summary>
public class DataBaseHelper
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(MainWindow));
    //连接、查询、查询、关闭

    public static void InitDataBase()
    {
        string databasePath = Path.Combine(Common.BasePath, Common.DataBaseTempFileName);
        Logger logger;
        if (File.Exists(databasePath))
            return;
        else
            File.Create(databasePath).Close();
        var connection = new SqliteConnection(new SqliteConnectionStringBuilder("data source=" + databasePath)
        {
            Mode = SqliteOpenMode.ReadWriteCreate,
            Password = Common.DatabasePwd
        }.ToString());
        connection.Open();
        using (var command = new SqliteCommand($"ATTACH DATABASE '{Common.DataBaseFileName}' AS {Common.DataBaseName} KEY '{Common.DatabasePwd}';" +
                                               $"SELECT sqlcipher_export('{Common.DataBaseName}');" +
                                               $"DETACH DATABASE {Common.DataBaseName};", connection))
        {
            command.ExecuteNonQuery();
        }
        connection.Close();
       
    }
    
    static readonly string password = Common.DatabasePwd;
    static readonly string dbPath = Common.DataBaseFileName;
    static SqliteConnection? connection;
    static SqliteTransaction? sqliteTransaction;

    public static void CreateConnection()
    {
        connection = new SqliteConnection(new SqliteConnectionStringBuilder("data source=" + DataBaseHelper.dbPath)
        {
            Mode = SqliteOpenMode.ReadWriteCreate,
            Password = password
        }.ToString());
        if (connection.State != ConnectionState.Open) { 
            connection.Open();
            using (var command = connection.CreateCommand())
            {
                command.CommandText = "PRAGMA key = '" + password + "';";
                command.CommandText += "PRAGMA case_sensitive_like = 1;";
                command.ExecuteNonQuery();
            }
        }
    }

    public static void CloseConnection()
    {
        if (connection != null)
        {
            connection.Close();
        }
    }
    public static void BeginTransaction()
    {
        if (connection != null)
        {
            sqliteTransaction = connection.BeginTransaction();
        }
    }
    public static void commit()
    {
        if (sqliteTransaction != null)
        {
            sqliteTransaction.Commit();
            sqliteTransaction.Dispose();
            sqliteTransaction = null;
        }
    }
    public static void rollback()
    {
        if (sqliteTransaction != null)
        {
            sqliteTransaction.Rollback();
            sqliteTransaction.Dispose();
            sqliteTransaction = null;
        }
    }

    public static int ExecuteNonQuery(string sql, SqliteParameter[] sqlParameters = null)
    {
        int resultCount = -1;
        try
        {
            SqliteCommand cmd = new SqliteCommand();
            cmd.Connection = connection;
            cmd.CommandText = sql;
            if (sqliteTransaction != null)
            {
                cmd.Transaction = sqliteTransaction;
            }
            if (sqlParameters != null)
            {
                cmd.Parameters.AddRange(sqlParameters);
            }
            resultCount = cmd.ExecuteNonQuery();
            cmd.Parameters.Clear();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
       
        return resultCount;
    }

    //查询全部
    public static DataTable ExecuteQuery(String sql, SqliteParameter[] sqlParameters = null)
    {
        DataTable table = new DataTable();
        try
        {
            SqliteCommand cmd = new SqliteCommand();
            cmd.Connection = connection;
            cmd.CommandText = sql;
            if(sqliteTransaction != null)
            {
                cmd.Transaction = sqliteTransaction;
            }
            if (sqlParameters != null)
            {
                cmd.Parameters.AddRange(sqlParameters);
            }
            SqliteDataReader reader = cmd.ExecuteReader();
            cmd.Parameters.Clear();
            table.Load(reader);
            return table;
        }
        catch (Exception ex)
        {
            Logger.Error($"全局异常捕获:{ex.Message}", ex);
            System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ApplicationError")}{ex.Message}");
        }
        return null;
    }

    public static List<T> ExecuteQuery<T>(String sql, SqliteParameter[] sqlParameters = null) where T : new()
    {
        List<T> table = new List<T>(); ;
        try
        {
            SqliteCommand cmd = new SqliteCommand();
            cmd.Connection = connection;
            cmd.CommandText = sql;
            if (sqliteTransaction != null)
            {
                cmd.Transaction = sqliteTransaction;
            }
            if (sqlParameters != null)
            {
                cmd.Parameters.AddRange(sqlParameters);
            }
            SqliteDataReader reader = cmd.ExecuteReader();
            // 获取实体类的属性信息
            PropertyInfo[] properties = typeof(T).GetProperties();
            while (reader.Read())
            {
                T item = new T();

                for (int i = 0; i < reader.FieldCount; i++)
                {
                    // 获取列名
                    string columnName = reader.GetName(i);

                    // 查找与列名匹配的属性(不区分大小写)
                    PropertyInfo property = properties.FirstOrDefault(p => p.Name.Equals(columnName, StringComparison.OrdinalIgnoreCase));

                    if (property != null && reader[i] != DBNull.Value)
                    {
                        // 使用反射将列值赋给属性
                        // 这里需要处理不同类型的列值,这里只处理了基本类型
                        if (property.PropertyType == typeof(int?) || property.PropertyType == typeof(int))
                            property.SetValue(item, reader.GetInt32(i));
                        else if (property.PropertyType == typeof(string))
                            property.SetValue(item, reader.GetString(i));
                        else if (property.PropertyType == typeof(decimal?) || property.PropertyType == typeof(decimal))
                            property.SetValue(item, reader.GetDecimal(i));
                    }
                }
                table.Add(item);
            }
            return table;
        }
        catch (Exception ex)
        {
            Logger.Error($"全局异常捕获:{ex.Message}", ex);
            System.Windows.MessageBox.Show($"{MultilingualHelper.getString("ApplicationError")}{ex.Message}");
        }
        return null;
    }
}