using System;
using System.Data;
using MySqlConnector;

namespace DBObj
{
    public class MyDB : IDisposable
    {

        private readonly string connectionString = Utils.Env.GetDBConnection();
        private MySqlConnection conn;
        private DataTable table = new DataTable();
        private int cursor = 0;

        public MyDB()
        {
            conn = new MySqlConnection(connectionString);
            conn.Open();
            //Console.WriteLine("MyDB 連線成功！");
        }

        public void Dispose()
        {
            if (conn != null)
            {
                conn.Dispose(); // 包含 Close + 資源釋放
                conn = null;
                //Console.WriteLine("MyDB 連線已釋放！");
            }
        }

        // SELECT 方法
        public bool open(string query, MySqlParameter[] parameters, bool showError = true)
        {
            table.Clear();
            cursor = 0;
            try
            {
                using (var cmd = new MySqlCommand(query, conn))
                {
                    if (parameters != null)
                    {
                        cmd.Parameters.AddRange(parameters);
                    }
                    using (var adapter = new MySqlDataAdapter(cmd))
                    {
                        adapter.Fill(table);
                    }
                }
            }
            catch (Exception ex)
            {
                if (showError)
                    Console.WriteLine($"DB Error: {ex.Message}");
                return false;
            }
            return true;
        }
        public T Field<T>(string name)
        {
            if (cursor < 0 || cursor >= table.Rows.Count || !table.Columns.Contains(name))
                return default;

            object value = table.Rows[cursor][name];
            if (value == DBNull.Value)
                return default;

            return (T)Convert.ChangeType(value, typeof(T));
        }
        public List<T> ToList<T>() where T : new()
        {
            var list = new List<T>();

            foreach (DataRow row in table.Rows)
            {
                T obj = new T();
                foreach (DataColumn col in table.Columns)
                {
                    var prop = typeof(T).GetProperty(col.ColumnName,
                        System.Reflection.BindingFlags.Public |
                        System.Reflection.BindingFlags.Instance |
                        System.Reflection.BindingFlags.IgnoreCase);

                    if (prop != null && prop.CanWrite)
                    {
                        object value = row[col];
                        if (value == DBNull.Value)
                        {
                            value = null;
                        }
                        try
                        {
                            if (value != null && prop.PropertyType != value.GetType())
                            {
                                value = Convert.ChangeType(value, prop.PropertyType);
                            }
                            prop.SetValue(obj, value);
                        }
                        catch
                        {
                            // 可以視情況加入錯誤處理
                        }
                    }
                }
                list.Add(obj);
            }

            return list;
        }
        public Dictionary<string, object> CurrentRowAsDictionary()
        {
            if (cursor < 0 || cursor >= table.Rows.Count)
                return null;

            var dict = new Dictionary<string, object>();
            foreach (DataColumn col in table.Columns)
            {
                dict[col.ColumnName] = table.Rows[cursor][col];
            }
            return dict;
        }
        public void moveNext()
        {
            cursor++;
        }
        public void movePrevious()
        {
            cursor--;
        }
        public void move(int index)
        {
            cursor = index;
        }
        public void moveFirst()
        {
            cursor = 0;
        }
        public void moveEnd()
        {
            cursor = table.Rows.Count - 1;
        }
        public bool bof()
        {
            return (cursor < 0) || (table.Rows.Count == 0);
        }
        public bool eof()
        {
            return cursor > table.Rows.Count - 1;
        }
        public bool Read()
        {
            if (eof()) return false;
            moveNext();
            return !eof();
        }
        public int recordCount()
        {
            return table.Rows.Count;
        }
        public bool found()
        {
            return table.Rows.Count > 0;
        }
        public void clear()
        {
            table.Clear();
        }


        // INSERT / UPDATE / DELETE 方法
        public int ExecuteNonQuery(string query, MySqlParameter[] parameters)
        {
            using (var cmd = new MySqlCommand(query, conn))
            {
                if (parameters != null)
                {
                    cmd.Parameters.AddRange(parameters);
                }
                return cmd.ExecuteNonQuery();
            }
        }
        public long LastInsertId()
        {
            using (var cmd = new MySqlCommand("SELECT LAST_INSERT_ID()", conn))
            {
                return Convert.ToInt64(cmd.ExecuteScalar());
            }
        }
    }
}
