using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GWSocketClient.model;
using GWSocketClient.util;
using Newtonsoft.Json;

namespace GWSocketClient.db
{
    public class AccessDbLoader
    {
        private static AccessDbLoader INSTANCE = null;

        private DataTable dataTable = new DataTable();
        private OleDbDataAdapter dataAdapter;


        public const string IP_HIS = "ip_his";
        public const string SEND_HIS = "send_his";
        public const string CCID_HIS = "ccid_his";
        public const string ADDR_HIS = "addr_his";

        //        private List<WvBean> wvBeans = new List<WvBean>();
        private Dictionary<string, string> ID_INFO = new Dictionary<string, string>();

        public static AccessDbLoader getInstance(string dbssPath = "")
        {
            return INSTANCE ?? (INSTANCE = new AccessDbLoader(dbssPath));
        }

        public DataTable getDataTable()
        {
            return dataTable;
        }


        public OleDbDataAdapter getDataAdapter()
        {
            return dataAdapter;
        }

        public Dictionary<string, string> getUserIdInfo()
        {
            return ID_INFO;
        }

        /* public string getWebViewJson()
         {
             return JsonConvert.SerializeObject(wvBeans);
         }*/

        private AccessDbLoader(string dbPath = "")
        {
            if (dbPath.Equals(""))
            {
                dbPath = Application.StartupPath + "/dbfile/ID_INFO.accdb;";
            }
            openConnection(dbPath);
            reloadAccessDb();
        }

        private static string strConnection = "Provider = Microsoft.ACE.OLEDB.12.0;Data Source = ";


        private OleDbConnection objConnection = null;

        private void openConnection(string dbPath)
        {
            strConnection += dbPath;
            objConnection = new OleDbConnection(strConnection);
            objConnection.Open();
        }

        public void closeConnection()
        {
            objConnection.Close();
        }

        public AccessDbLoader reloadAccessDb(string sql = @"select * from fw")
        {
            Console.WriteLine(sql);
            try
            {
//                OleDbCommand sqlcmd = new OleDbCommand(@"select * from fw", objConnection);
                OleDbCommand sqlcmd = new OleDbCommand(sql, objConnection);

                dataAdapter = new OleDbDataAdapter(sqlcmd);
                dataTable.Clear();
                ID_INFO.Clear();
//                wvBeans.Clear();
                dataAdapter.Fill(dataTable);

                fillData(sqlcmd);
            }
            catch (OleDbException oe)
            {
                MessageBox.Show(oe.Message);
            }

            catch (Exception exception)
            {
                MyMessageBox.ShowMessageBox(exception.Message);
            }

            return this;
        }

        public AccessDbLoader findDataByType(int mType, string query)
        {
            /*
            ID - 10进制
           ID - 16进制
           名字 - IDInfo
           描述 - Desp
           */
            string sql = "select * from fw ";

            switch (mType)
            {
                case 0:
                    sql += " where my_index = " + query;
                    break;
                case 1:
                    sql += " where MY_ID = '" + query + "'";
                    break;
                case 2:
                    sql += " where idInfo like '%" + query + "%'";
                    break;
                case 3:
                    sql += " where desp like '%" + query + "%'";
                    break;
                default:
                    return reloadAccessDb();
            }
            return reloadAccessDb(sql);
        }

        private void fillData(OleDbCommand sqlcmd)
        {
            using (OleDbDataReader reader = sqlcmd.ExecuteReader())
            {
                while (reader.Read()) //这个read调用很重要！不写的话运行时将提示找不到数据  
                {
                    WvBean wb = new WvBean();
                    int id = 0;
                    int index = 0;
                    string myId = "";
                    string idInfo = "";
                    string len = "";
                    string mode = "";
                    string desp = "";
                    string defalutValue = "";
                    string userValue = "";
                    string remark = "";
                    /*try
                    {*/
                    id = reader.GetInt32(0);
                    index = reader.GetInt32(1);
                    myId = reader.GetString(2);
                    idInfo = calcNull(reader.GetString(3));
                    len = calcNull(reader.GetString(4));
                    mode = calcNull(reader.GetString(5));
                    desp = calcNull(reader.GetString(6));
                    defalutValue = calcNull(reader.GetString(7));
                    userValue = calcNull(reader.GetString(8));
                    remark = calcNull(reader.GetString(9));
                    /* }
                     catch (Exception exception)
                     {
                     }*/

                    wb.id = id;
                    wb.index = index;
                    wb.myId = myId;
                    wb.idInfo = idInfo;
                    wb.len = len;
                    wb.mode = mode;
                    wb.desp = desp;
                    wb.defalutValue = defalutValue;
                    wb.userValue = userValue;
                    wb.remark = remark;

                    ID_INFO.Add(myId, userValue);

                    //                        wvBeans.Add(wb);
                }
            }
        }


        public int insert2Db(WvBean wb)
        {
            try
            {
                string sql =
                    "INSERT INTO fw(my_index,MY_ID,idInfo,len,mode,desp,default_value,user_value,remark) VALUES(";
                sql += wb.index + ",";
                sql += "'" + wb.myId + "',";
                sql += "'" + wb.idInfo + "',";
                sql += "'" + wb.len + "',";
                sql += "'" + wb.mode + "',";
                sql += "'" + wb.desp + "',";
                sql += "'" + wb.defalutValue + "',";
                sql += "'" + wb.userValue + "',";
                sql += "'" + wb.remark + "')";
//                Console.WriteLine(sql);
                OleDbCommand inst = new OleDbCommand(sql, objConnection);

                return inst.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            Console.WriteLine(wb.ToString());
            return -1;
        }

        public int delete4Db(int id)
        {
            string sql = "delete from fw where ID=" + id;
            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }

        public int update2Db(WvBean wb)
        {
            /*string sql = "update fw set index=" + wb.index + ", MY_ID='" + wb.myId + "',idInfo='" + wb.idInfo +
                         "',len='" + wb.len +
                         "',mode='" +
                         wb.mode + "',desp='" + wb.desp + "',default_value='" + wb.defalutValue + "',user_value='" +
                         wb.userValue + "',remark='" + wb.remark + "' where ID=" + wb.id;*/

            string sql = "update fw set my_index=" + wb.index + ",MY_ID=\"" + wb.myId + "\",idInfo=\"" + wb.idInfo +
                         "\",len=\"" + wb.len +
                         "\",mode=\"" +
                         wb.mode + "\",desp=\"" + wb.desp + "\",default_value=\"" + wb.defalutValue +
                         "\",user_value=\"" +
                         wb.userValue + "\",remark=\"" + wb.remark + "\" where ID=" + wb.id;

            Console.WriteLine(sql);
            OleDbCommand inst = new OleDbCommand(sql, objConnection);

            return inst.ExecuteNonQuery();
        }

        public int resetUserData()
        {
            string sql = "update fw set user_value=default_value";
            Console.WriteLine(sql);
            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }


        public int setReceiveData(string id, string value)
        {
            int idInt = Utils.hexToTen(id);
            string sql = "update fw set user_value=\"" + (value.Trim()) + "\" where my_index=" + idInt;
            Console.WriteLine(sql);
            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }

        public int deleteAllData(string tableName = "fw")
        {
            string sql = "delete from " + tableName;
            Console.WriteLine(sql);
            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }


        private string calcNull(string ojb)
        {
            if (ojb.Trim().Equals("") || ojb == null)
            {
                return "";
            }
            return ojb;
        }


        public int getHistoryCount(string tableName)
        {
            string sql = "select COUNT(*),MIN(ID) from " + tableName;

            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            int count = 0;
            int minId = 0;
            using (OleDbDataReader reader = inst.ExecuteReader())
            {
                if (reader != null)
                {
                    reader.Read();
                    try
                    {
                        count = reader.GetInt32(0);
                        minId = reader.GetInt32(1);
                    }
                    catch (Exception e)
                    {
                        // 当数据库中没有记录的时候,MIN ID 就会出错.
                    }
                }
            }
            if (count > 30)
            {
                sql = "delete from " + tableName + "  where ID=" + minId;
                inst = new OleDbCommand(sql, objConnection);
                inst.ExecuteNonQuery();
            }
            return count;
        }


        public int checkHistoryExits(string tableName, string his)
        {
            his = his.Trim().ToUpper();
            string sql = "select COUNT(*) from " + tableName + " ";

            switch (tableName)
            {
                case IP_HIS:
                    sql += "where ip ='" + his + "'";
                    break;
                case SEND_HIS:
                    sql += "where s_data ='" + his + "'";
                    break;
                case CCID_HIS:
                    sql += "where CCID ='" + his + "'";
                    break;
                case ADDR_HIS:
                    sql += "where addr ='" + his + "'";
                    break;
                default:
                    break;
            }

            Console.WriteLine("检查是否存在SQL=" + sql);

            int count;
            using (OleDbCommand inst = new OleDbCommand(sql, objConnection))
            {
                count = 0;
                using (OleDbDataReader reader = inst.ExecuteReader())
                {
                    if (reader != null)
                    {
                        reader.Read();
                        count = reader.GetInt32(0);
                    }
                }
            }
            return count;
        }

        public int addToHistory(string tableName, string his)
        {
            his = his.ToUpper();
            Console.WriteLine(tableName + "; " + his);

            int exits = checkHistoryExits(tableName, his);
            if (exits != 0)
                return -1;

            int rowCount = getHistoryCount(tableName);
            OleDbCommand inst = null;

            string sql = "INSERT INTO " + tableName + "(";
            if (tableName.Equals(IP_HIS))
            {
                sql += "ip) VALUES('" + his + "')";
                Console.WriteLine(sql);
            }
            else if (tableName.Equals(SEND_HIS))
            {
                sql += "s_data) VALUES('" + his + "')";
                Console.WriteLine(sql);
            }
            else if (tableName.Equals(CCID_HIS))
            {
                sql += "CCID) VALUES('" + his + "')";
                Console.WriteLine(sql);
            }
            else if (tableName.Equals(ADDR_HIS))
            {
                sql += "addr) VALUES('" + his + "')";
                Console.WriteLine(sql);
            }
            inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }


        public int deleteByID(string tablename, int id)
        {
            string sql = "delete from " + tablename + "  where ID=" + id;
            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            return inst.ExecuteNonQuery();
        }

        public List<HisBean> getInputHistory(string tname)
        {
            string sql = "select * from " + tname;

            OleDbCommand inst = new OleDbCommand(sql, objConnection);
            List<HisBean> hsiList = new List<HisBean>();

            using (OleDbDataReader reader = inst.ExecuteReader())
            {
                while (reader.Read())
                {
                    HisBean hb = new HisBean();
                    hb.ID = reader.GetInt32(0);
                    hb.data = reader.GetString(1);
                    hsiList.Add(hb);
                }
            }
            return hsiList;
        }
    }
}