using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AVS
{
    class LiteDbClass
    {
        public string SERVER_URL = "https://cosmos.utopiadeals.com/cosmos/webhook/article-verification-log";
        //public string SERVER_URL = "https://cosmos-jobs.utopiadeals.com/cosmos/webhook/article-verification-log";

        //public string SERVER_URL = "http://192.168.91.54:8080/cosmos/webhook/article-verification-log";
        public string SERVER_URL_CARTON = "https://cosmos.utopiadeals.com/cosmos/rest/carton-verification-logs";

        private MainForm _mainForm;

        // Constructor that accepts MainForm instance
        public LiteDbClass(MainForm mainForm)
        {
            _mainForm = mainForm;
        }

        // Specify the folder path for the SQLite database file
        static string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonDocuments), "AVS");
        // Specify the path for the SQLite database file within the folder
        static string dbFileName = "AVS.db";
        static string dbPath = Path.Combine(folderPath, dbFileName);
        private static string connectionString = $"Data Source={dbPath};Version=3;";
        SQLiteConnection connection = new SQLiteConnection(connectionString);
        public SQLiteConnection OpenConnection()
        {
            try
            {
                // Open the SQLite connection

                connection.Open();
                Console.WriteLine("SQLite connection opened successfully");
                return connection;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error opening SQLite connection: {ex.Message}");
                return null;
            }
        }

        public void CloseConnection()
        {
            try
            {
                // Close the SQLite connection
                connection?.Close();
                Console.WriteLine("SQLite connection closed successfully");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error closing SQLite connection: {ex.Message}");
            }
        }
        public bool InsertOrUpdateWeightTolerance(string FNSKU, string market_place, double weight_tolerance, string avs_name)
        {
            try
            {
                OpenConnection();

                string query = @"INSERT OR REPLACE INTO weight_tolerance 
                         (FNSKU, MARKET_PLACE, WEIGHT_TOLERANCE, WEIGHT_TOLERANCE_DATETIME)
                         VALUES (@fnsku, @market_place, @weight_tolerance, @datetime)";

                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    cmd.Parameters.AddWithValue("@fnsku", FNSKU);
                    cmd.Parameters.AddWithValue("@market_place", market_place);
                    cmd.Parameters.AddWithValue("@weight_tolerance", weight_tolerance);
                    cmd.Parameters.AddWithValue("@datetime", DateTime.Now);


                    cmd.ExecuteNonQuery();
                }

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"InsertOrUpdate Error: {ex.Message}");
                return false;
            }
            finally
            {
                CloseConnection();
            }
        }
        public void UpdateSKURecord(string tableName, string oldSKU, string newSKU)
        {
            try
            {

                //if (!RecordExists(tableName,newSKU,null))
                //{
                OpenConnection();

                // Create the SQL command for update
                string updateCommand = $"UPDATE {tableName} SET SKU = @NewSKU WHERE SKU = @OldSKU";

                using (SQLiteCommand cmd = new SQLiteCommand(updateCommand, connection))
                {
                    // Set the parameters for the old and new SKUs
                    cmd.Parameters.AddWithValue("@OldSKU", oldSKU);
                    cmd.Parameters.AddWithValue("@NewSKU", newSKU);

                    // Execute the command
                    cmd.ExecuteNonQuery();
                }

                CloseConnection();

                Console.WriteLine("SKU updated successfully");
                //   }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error updating SKU: {ex.Message}");
            }
            finally
            {
                CloseConnection();
            }
        }
        public double GetWeightTolerance(string fnsku, string marketPlace)
        {
            double weightTolerance = 0;

            try
            {
                OpenConnection();

                string query = @"
            SELECT weight_tolerance 
            FROM weight_tolerance
            WHERE FNSKU = @fnsku AND MARKET_PLACE = @market_place";

                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    cmd.Parameters.AddWithValue("@fnsku", fnsku);
                    cmd.Parameters.AddWithValue("@market_place", marketPlace);

                    var result = cmd.ExecuteScalar();

                    if (result != null && result != DBNull.Value)
                    {
                        weightTolerance = Convert.ToDouble(result);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error fetching weight tolerance: {ex.Message}");
            }
            finally
            {
                CloseConnection();
            }

            return weightTolerance;
        }
        public void InsertRecord<T>(string tableName, T record, string property, string property2)
        {
            try
            {
                string PropValue1 = "";
                string PropValue2 = "";

                PropertyInfo[] properties = typeof(T).GetProperties();
                foreach (PropertyInfo prop in properties)
                {
                    if (prop.Name == property)
                    {
                        PropValue1 = prop.GetValue(record).ToString();
                    }
                    if (prop.Name == property2)
                    {
                        PropValue2 = prop.GetValue(record).ToString();
                    }
                }
                if (tableName == "DailyLogs")
                {
                    OpenConnection();
                    // Create the SQL command for insertion


                    // Generate column names and parameter names dynamically
                    string columnNames = string.Join(", ", properties.Select(prop => prop.Name));
                    string parameterNames = string.Join(", ", properties.Select(prop => $"@{prop.Name}"));

                    string insertCommand = $"INSERT INTO {tableName} ({columnNames}) VALUES ({parameterNames})";

                    using (SQLiteCommand cmd = new SQLiteCommand(insertCommand, connection))
                    {
                        // Set the parameters based on the record properties
                        foreach (PropertyInfo prop in properties)
                        {
                            cmd.Parameters.AddWithValue($"@{prop.Name}", prop.GetValue(record));
                        }

                        // Execute the command
                        cmd.ExecuteNonQuery();
                    }

                    CloseConnection();

                    Console.WriteLine("Record inserted successfully");
                }
                else
                {
                    if (!RecordExists(tableName, (property, PropValue1), (property2, PropValue2)))
                    {
                        OpenConnection();
                        // Create the SQL command for insertion


                        // Generate column names and parameter names dynamically
                        string columnNames = string.Join(", ", properties.Select(prop => prop.Name));
                        string parameterNames = string.Join(", ", properties.Select(prop => $"@{prop.Name}"));

                        string insertCommand = $"INSERT INTO {tableName} ({columnNames}) VALUES ({parameterNames})";

                        using (SQLiteCommand cmd = new SQLiteCommand(insertCommand, connection))
                        {
                            // Set the parameters based on the record properties
                            foreach (PropertyInfo prop in properties)
                            {
                                cmd.Parameters.AddWithValue($"@{prop.Name}", prop.GetValue(record));
                            }

                            // Execute the command
                            cmd.ExecuteNonQuery();
                        }

                        CloseConnection();

                        Console.WriteLine("Record inserted successfully");
                    }
                }

            }

            catch (Exception ex)
            {
                Console.WriteLine($"Error inserting record: {ex.Message}");
            }
            finally
            {
                CloseConnection();
            }
        }
        private bool RecordExists(string tableName, params (string PropertyName, object PropertyValue)[] properties)
        {
            try
            {
                string whereClause = null;
                // Parameter Validation
                if (string.IsNullOrEmpty(tableName) || properties == null || properties.Length == 0)
                {
                    throw new ArgumentNullException("tableName, record, or properties", "Table name, record, and at least one property must be provided.");
                }

                try
                {
                    OpenConnection();

                    // Generate the WHERE clause based on the provided properties

                    if (properties[1].PropertyName != null)
                    {
                        whereClause = string.Join(" AND ", properties
                            .Where(p => p.PropertyName != null)
                            .Select(p => $"{p.PropertyName} = @{p.PropertyName}"));

                    }
                    else
                    {
                        whereClause = string.Join("", properties
                            .Where(p => p.PropertyName != null)
                            .Select(p => $"{p.PropertyName} = @{p.PropertyName}"));
                    }

                    // Check if the combination of properties exists in the table

                    string query = $"SELECT COUNT(*) FROM {tableName} WHERE {whereClause}";

                    using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                    {
                        foreach (var property in properties)
                        {
                            if (property.PropertyName != null)
                            {
                                cmd.Parameters.Add(new SQLiteParameter($"@{property.PropertyName}", property.PropertyValue));
                            }
                        }

                        int count = Convert.ToInt32(cmd.ExecuteScalar());
                        return count > 0;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error checking existence: {ex.Message}");
                    throw; // Rethrow the exception or return false, depending on your design
                }
                finally
                {
                    CloseConnection();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"General error in SKUExists method: {ex.Message}");
                return false;
            }
        }

        public bool CheckSkuRunning(string sku, string tableName)
        {
            try
            {
                OpenConnection();

                // Check if SKU exists in the table
                string query = $"SELECT COUNT(*) FROM {tableName} WHERE FNSKU = @FNSKU ";
                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    cmd.Parameters.AddWithValue("@FNSKU", sku);
                    int count = Convert.ToInt32(cmd.ExecuteScalar());
                    return count > 0;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error checking SKU existence: {ex.Message}");
                return false;
            }
            finally
            {
                CloseConnection();
            }
        }


        public bool checkCarton(string model_no, string QR)
        {
            try
            {
                OpenConnection();

                // Check if SKU exists in the table 
                string query = $"SELECT * FROM MODELLogs WHERE QR = @QR and MODEL_NO = @MODEL_NO";
                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    cmd.Parameters.AddWithValue("@MODEL_NO", model_no);
                    cmd.Parameters.AddWithValue("@QR", QR);
                    int count = Convert.ToInt32(cmd.ExecuteScalar());
                    return count > 0;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error checking SKU existence: {ex.Message}");
                return false;
            }
            finally
            {
                CloseConnection();
            }
        }

        public int GetLastRecord()
        {
            try
            {
                OpenConnection();

                // Query to get the last id from the DailyLogs table
                string query = "SELECT id FROM DailyLogs ORDER BY id DESC LIMIT 1;";
                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    // Execute the query and convert the result to an integer
                    int lastId = Convert.ToInt32(cmd.ExecuteScalar());
                    return lastId;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error retrieving the last record id: {ex.Message}");
                return -1; // Return a sentinel value to indicate failure
            }
            finally
            {
                CloseConnection();
            }
        }

        public bool UpdateCartonValue(string cartonValue, int lastId)
        {
            try
            {
                // Get the last record ID using the existing GetLastRecord method

                OpenConnection();

                // Query to update the carton_value for the last record
                string query = "UPDATE DailyLogs SET WRONG_CARTON = @cartonValue WHERE id = @id;";
                using (SQLiteCommand cmd = new SQLiteCommand(query, connection))
                {
                    // Add parameters to the query
                    cmd.Parameters.AddWithValue("@cartonValue", cartonValue);
                    cmd.Parameters.AddWithValue("@id", lastId);

                    // Execute the update query
                    int rowsAffected = cmd.ExecuteNonQuery();

                    return rowsAffected > 0; // Return true if the update was successful
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error updating carton value: {ex.Message}");
                return false;
            }
            finally
            {
                CloseConnection();
            }
        }

        public List<SKULog> showData()
        {
            List<SKULog> LogList = new List<SKULog>();
            try
            {
                OpenConnection();

                string query = "SELECT * FROM SKUlogs";
                using (SQLiteCommand command = new SQLiteCommand(query, connection))
                {
                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {

                        while (reader.Read())
                        {
                            SKULog sKULog = new SKULog
                            {
                                SKU = reader["SKU"] != DBNull.Value ? reader["SKU"].ToString() : string.Empty,
                                FNSKU = reader["FNSKU"] != DBNull.Value ? reader["FNSKU"].ToString() : string.Empty,
                                SYS_IP = reader["SYS_IP"] != DBNull.Value ? reader["SYS_IP"].ToString() : string.Empty,
                                Title = reader["Title"] != DBNull.Value ? reader["Title"].ToString() : string.Empty,
                                NetWeightKg = reader["NetWeightKg"] != DBNull.Value ? Convert.ToDouble(reader["NetWeightKg"]) : 0.0,
                                Colour = reader["Colour"] != DBNull.Value ? reader["Colour"].ToString() : string.Empty,
                                ModelNo = reader["ModelNo"] != DBNull.Value ? reader["ModelNo"].ToString() : string.Empty,
                                Size = reader["Size"] != DBNull.Value ? reader["Size"].ToString() : string.Empty,
                                RECORD_DATE = reader["RECORD_DATE"] != DBNull.Value ? Convert.ToDateTime(reader["RECORD_DATE"]) : DateTime.MinValue,
                                USER_ID = reader["USER_ID"] != DBNull.Value ? reader["USER_ID"].ToString() : string.Empty,
                                ItemsPerBox = reader["ItemsPerBox"] != DBNull.Value ? Convert.ToInt32(reader["ItemsPerBox"]) : 0,
                                MARKET_PLACE = reader["MARKET_PLACE"] != DBNull.Value ? reader["MARKET_PLACE"].ToString() : "NA"
                            };

                            LogList.Add(sKULog);

                        }


                    }
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                CloseConnection();
            }
            return LogList;
        }



        public void DeleteRow(string FNSKU, string market_place)
        {
            // Open the connection
            OpenConnection();

            // Define the SQL query with a parameter
            string query = "DELETE FROM SKUlogs WHERE FNSKU = @fnsku AND(MARKET_PLACE = @MARKET_PLACE OR MARKET_PLACE IS NULL)";

            // Use a using block to ensure resources are properly disposed
            using (SQLiteCommand cmd = new SQLiteCommand(query, connection)) // Replace 'sqliteConnection' with your actual SQLiteConnection object
            {
                // Add the parameter to avoid SQL injection
                cmd.Parameters.AddWithValue("@fnsku", FNSKU);
                cmd.Parameters.AddWithValue("@MARKET_PLACE", market_place);
                // Execute the query
                cmd.ExecuteNonQuery();
            }

            // Close the connection
            CloseConnection();
        }
        public List<MODELLog> showModelData()
        {
            List<MODELLog> LogList = new List<MODELLog>();
            try
            {
                OpenConnection();

                string query = "SELECT MODEL_NO,QR,LIVE_WEIGHT,SYS_IP,RECORD_DATE,USER_ID , PC_NAME , MARKET_PLACE FROM MODELLogs order by RECORD_DATE desc ";
                using (SQLiteCommand command = new SQLiteCommand(query, connection))
                {
                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {

                        while (reader.Read())
                        {
                            MODELLog log = new MODELLog
                            {
                                //CONTAINER_NO = reader["CONTAINER_NO"].ToString(),
                                MODEL_NO = reader["MODEL_NO"].ToString(),
                                QR = reader["QR"].ToString(),
                                LIVE_WEIGHT = Convert.ToDecimal(reader["LIVE_WEIGHT"].ToString()),
                                SYS_IP = reader["SYS_IP"].ToString(),
                                RECORD_DATE = Convert.ToDateTime(reader["RECORD_DATE"]),
                                USER_ID = reader["USER_ID"].ToString(),
                                PC_NAME = reader["PC_NAME"].ToString(),
                                MARKET_PLACE = reader["MARKET_PLACE"].ToString(),

                            };

                            LogList.Add(log);

                        }


                    }
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                CloseConnection();
            }
            return LogList;
        }

        public int FillCounts(string fnsku, string market_place)
        {
            int totalCount = 0;
            try
            {
                OpenConnection();

                string query;

                if (market_place == "NA")
                {
                    query = @"SELECT COUNT(FNSKU) AS Total_item
              FROM DailyLogs
              WHERE is_weight_wrong = 0
              AND is_fnsku_wrong = 0
              AND FNSKU = @FNSKU
              AND LIVE_WEIGHT > 0.121
              AND (MARKET_PLACE IS NULL OR MARKET_PLACE LIKE 'NA')";
                }
                else
                {
                    query = @"SELECT COUNT(FNSKU) AS Total_item
              FROM DailyLogs
              WHERE is_weight_wrong = 0
              AND is_fnsku_wrong = 0
              AND FNSKU = @FNSKU
              AND LIVE_WEIGHT > 0.121
              AND MARKET_PLACE = @MARKET_PLACE";
                }
                using (SQLiteCommand command = new SQLiteCommand(query, connection))
                {
                    // Add FNSKU parameter
                    command.Parameters.AddWithValue("@FNSKU", fnsku);
                    command.Parameters.AddWithValue("@MARKET_PLACE", market_place);



                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {

                        while (reader.Read())
                        {
                            totalCount = reader.GetInt32(0);
                        }

                    }
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                CloseConnection();
            }
            return totalCount;

        }

        public int FillCarton(string modelNo)
        {
            int totalCount = 0;
            try
            {
                OpenConnection();

                string query = "SELECT COUNT(MODEL_NO) AS Total_item FROM MODELLogs WHERE MODEL_NO = @MODEL_NO and LIVE_WEIGHT >  0.121";
                using (SQLiteCommand command = new SQLiteCommand(query, connection))
                {
                    // Add FNSKU parameter
                    command.Parameters.AddWithValue("@MODEL_NO", modelNo);


                    using (SQLiteDataReader reader = command.ExecuteReader())
                    {

                        while (reader.Read())
                        {
                            totalCount = reader.GetInt32(0);
                        }

                    }
                }
            }
            catch (Exception ex)
            {

            }
            finally
            {
                CloseConnection();
            }
            return totalCount;
        }

        public void CheckAndCreateDb()
        {
            try
            {
                // Create the folder if it doesn't exist
                Directory.CreateDirectory(folderPath);

                // Set the connection string with the dynamic path
                connectionString = $"Data Source={dbPath};Version=3;";

                // Check if the database file exists
                bool isDatabaseExists = File.Exists(dbPath);

                // If the database file doesn't exist, create it
                if (!isDatabaseExists)
                {
                    SQLiteConnection.CreateFile(dbPath);
                    Console.WriteLine("SQLite database created successfully");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error creating database: {ex.Message}");
            }

        }
        public void CreateSKUlogTable(string tableName, List<AVS.SKULog.TableColumn> columns)
        {
            try
            {
                OpenConnection();

                // Check if table exists
                string tableExistsQuery = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
                bool tableExists = false;

                using (SQLiteCommand checkTableCmd = new SQLiteCommand(tableExistsQuery, connection))
                {
                    using (SQLiteDataReader reader = checkTableCmd.ExecuteReader())
                    {
                        tableExists = reader.HasRows;
                    }
                }

                if (!tableExists)
                {
                    // Create table if it does not exist
                    string createTableCommand = $"CREATE TABLE {tableName} ({AVS.SKULog.GetColumnsDefinition(columns)})";

                    using (SQLiteCommand cmd = new SQLiteCommand(createTableCommand, connection))
                    {
                        cmd.ExecuteNonQuery();
                    }

                    Console.WriteLine($"Table '{tableName}' created.");
                }
                else
                {
                    // Check for each column's existence and add it if it doesn't exist
                    foreach (var column in columns)
                    {
                        string columnExistsQuery = $"PRAGMA table_info({tableName})";
                        bool columnExists = false;

                        using (SQLiteCommand checkColumnCmd = new SQLiteCommand(columnExistsQuery, connection))
                        {
                            using (SQLiteDataReader reader = checkColumnCmd.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    if (reader["name"].ToString() == column.Name)
                                    {
                                        columnExists = true;
                                        break;
                                    }
                                }
                            }
                        }

                        if (!columnExists)
                        {
                            string addColumnCommand = $"ALTER TABLE {tableName} ADD COLUMN {column.Name} {column.DataType}";

                            using (SQLiteCommand addColumnCmd = new SQLiteCommand(addColumnCommand, connection))
                            {
                                addColumnCmd.ExecuteNonQuery();
                            }

                            Console.WriteLine($"Column '{column.Name}' added to table '{tableName}'.");
                        }
                    }
                }

                CloseConnection();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error creating or modifying table: {ex.Message}");
                CloseConnection();
            }
            finally
            {
                CloseConnection();
            }
        }

        public void CreateMODELlogTable(string tableName, List<AVS.MODELLog.TableColumn> columns)
        {
            try
            {
                OpenConnection();

                // Check if table exists
                string tableExistsQuery = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
                bool tableExists = false;

                using (SQLiteCommand checkTableCmd = new SQLiteCommand(tableExistsQuery, connection))
                {
                    using (SQLiteDataReader reader = checkTableCmd.ExecuteReader())
                    {
                        tableExists = reader.HasRows;
                    }
                }

                if (!tableExists)
                {
                    // Create table if it does not exist
                    string createTableCommand = $"CREATE TABLE {tableName} ({AVS.MODELLog.GetColumnsDefinition(columns)})";

                    using (SQLiteCommand cmd = new SQLiteCommand(createTableCommand, connection))
                    {
                        cmd.ExecuteNonQuery();
                    }

                    Console.WriteLine($"Table '{tableName}' created.");
                }
                else
                {
                    // Check for each column's existence and add it if it doesn't exist
                    foreach (var column in columns)
                    {
                        string columnExistsQuery = $"PRAGMA table_info({tableName})";
                        bool columnExists = false;

                        using (SQLiteCommand checkColumnCmd = new SQLiteCommand(columnExistsQuery, connection))
                        {
                            using (SQLiteDataReader reader = checkColumnCmd.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    if (reader["name"].ToString() == column.Name)
                                    {
                                        columnExists = true;
                                        break;
                                    }
                                }
                            }
                        }

                        if (!columnExists)
                        {
                            string addColumnCommand = $"ALTER TABLE {tableName} ADD COLUMN {column.Name} {column.DataType}";

                            using (SQLiteCommand addColumnCmd = new SQLiteCommand(addColumnCommand, connection))
                            {
                                addColumnCmd.ExecuteNonQuery();
                            }

                            Console.WriteLine($"Column '{column.Name}' added to table '{tableName}'.");
                        }
                    }
                }

                CloseConnection();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error creating or modifying table: {ex.Message}");
                CloseConnection();
            }
            finally
            {
                CloseConnection();
            }
        }

        public void CreateDailylogTable(string tableName, List<AVS.DailyLog.TableColumn> columns)
        {
            try
            {
                OpenConnection();

                // Check if table exists
                string tableExistsQuery = $"SELECT name FROM sqlite_master WHERE type='table' AND name='{tableName}'";
                bool tableExists = false;

                using (SQLiteCommand checkTableCmd = new SQLiteCommand(tableExistsQuery, connection))
                {
                    using (SQLiteDataReader reader = checkTableCmd.ExecuteReader())
                    {
                        tableExists = reader.HasRows;
                    }
                }

                if (!tableExists)
                {
                    // Create table if it does not exist
                    string createTableCommand = $"CREATE TABLE {tableName} ({AVS.DailyLog.GetColumnsDefinition(columns)})";

                    using (SQLiteCommand cmd = new SQLiteCommand(createTableCommand, connection))
                    {
                        cmd.ExecuteNonQuery();
                    }

                    Console.WriteLine($"Table '{tableName}' created.");
                }
                else
                {
                    // Check for each column's existence and add it if it doesn't exist
                    foreach (var column in columns)
                    {
                        string columnExistsQuery = $"PRAGMA table_info({tableName})";
                        bool columnExists = false;

                        using (SQLiteCommand checkColumnCmd = new SQLiteCommand(columnExistsQuery, connection))
                        {
                            using (SQLiteDataReader reader = checkColumnCmd.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    if (reader["name"].ToString() == column.Name)
                                    {
                                        columnExists = true;
                                        break;
                                    }
                                }
                            }
                        }

                        if (!columnExists)
                        {
                            string addColumnCommand = $"ALTER TABLE {tableName} ADD COLUMN {column.Name} {column.DataType}";

                            using (SQLiteCommand addColumnCmd = new SQLiteCommand(addColumnCommand, connection))
                            {
                                addColumnCmd.ExecuteNonQuery();
                            }

                            Console.WriteLine($"Column '{column.Name}' added to table '{tableName}'.");
                        }
                    }
                }

                CloseConnection();
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error creating or modifying table: {ex.Message}");
                CloseConnection();
            }
            finally
            {
                CloseConnection();
            }
        }

        public void CreateToleranceTable(string tableName, List<AVS.WeightTolerance.TableColumn> columns)
        {
            if (columns == null || columns.Count == 0)
            {
                Console.WriteLine("No columns provided to create the table.");
                return;
            }

            try
            {
                OpenConnection();

                // Check if table exists
                string tableExistsQuery = $"SELECT name FROM sqlite_master WHERE type='table' AND name=@tableName";
                bool tableExists = false;

                using (SQLiteCommand checkTableCmd = new SQLiteCommand(tableExistsQuery, connection))
                {
                    checkTableCmd.Parameters.AddWithValue("@tableName", tableName);

                    using (SQLiteDataReader reader = checkTableCmd.ExecuteReader())
                    {
                        tableExists = reader.HasRows;
                    }
                }

                if (!tableExists)
                {
                    // Build columns definition
                    string columnsDefinition = AVS.WeightTolerance.GetColumnsDefinition(columns);

                    // 🆕 ADD UNIQUE CONSTRAINT to table definition
                    columnsDefinition += ", UNIQUE(FNSKU, MARKET_PLACE)";

                    string createTableCommand = $"CREATE TABLE \"{tableName}\" ({columnsDefinition})";

                    using (SQLiteCommand cmd = new SQLiteCommand(createTableCommand, connection))
                    {
                        cmd.ExecuteNonQuery();
                    }

                    Console.WriteLine($"Table '{tableName}' created with UNIQUE constraint on (FNSKU, MARKET_PLACE).");
                }
                else
                {
                    // Get existing columns once
                    List<string> existingColumns = new List<string>();

                    string columnListQuery = $"PRAGMA table_info(\"{tableName}\")";
                    using (SQLiteCommand getColumnsCmd = new SQLiteCommand(columnListQuery, connection))
                    {
                        using (SQLiteDataReader reader = getColumnsCmd.ExecuteReader())
                        {
                            while (reader.Read())
                            {
                                existingColumns.Add(reader["name"].ToString());
                            }
                        }
                    }

                    // Now check and add missing columns
                    foreach (var column in columns)
                    {
                        if (!existingColumns.Contains(column.Name))
                        {
                            string addColumnCommand = $"ALTER TABLE \"{tableName}\" ADD COLUMN {column.Name} {column.DataType}";

                            using (SQLiteCommand addColumnCmd = new SQLiteCommand(addColumnCommand, connection))
                            {
                                addColumnCmd.ExecuteNonQuery();
                            }

                            Console.WriteLine($"Column '{column.Name}' added to table '{tableName}'.");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error creating or modifying table: {ex.Message}");
            }
            finally
            {
                CloseConnection();
            }
        }


        public async Task<List<MODELLog>> GetAllLogsFromDatabaseAsyncCarton()
        {
            List<MODELLog> logs = new List<MODELLog>();

            try
            {
                using (var command = new SQLiteCommand("SELECT * FROM MODELLogs", connection))
                {
                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            var log = new MODELLog
                            {
                                QR = reader["QR"] is DBNull ? null : reader["QR"].ToString(),
                                RECORD_DATE = reader["RECORD_DATE"] is DBNull ? DateTime.MinValue : DateTime.Parse(reader["RECORD_DATE"].ToString()),
                                SYS_IP = reader["SYS_IP"] is DBNull ? null : reader["SYS_IP"].ToString(),
                                USER_ID = reader["USER_ID"] is DBNull ? null : reader["USER_ID"].ToString(),
                                LIVE_WEIGHT = reader["LIVE_WEIGHT"] is DBNull ? 0 : Convert.ToDecimal(reader["LIVE_WEIGHT"].ToString()),
                                MODEL_NO = reader["MODEL_NO"] is DBNull ? "0" : reader["MODEL_NO"].ToString(),
                                PC_NAME = reader["PC_NAME"] is DBNull ? "PC NAME NOT FOUND" : reader["PC_NAME"].ToString(),
                                MARKET_PLACE = reader["MARKET_PLACE"] is DBNull ? "NA" : reader["MARKET_PLACE"].ToString(),


                            };

                            logs.Add(log);
                        }
                    }
                }

                return logs;
            }
            catch (Exception ex)
            {
                // Handle exceptions, log them, or rethrow if needed.
                Console.WriteLine($"Error in GetAllLogsFromDatabaseAsync: {ex.Message}");
                throw;
            }
        }
        public async Task<List<DailyLog>> GetAllLogsFromDatabaseAsync()
        {
            List<DailyLog> logs = new List<DailyLog>();

            try
            {
                using (var command = new SQLiteCommand("SELECT * FROM DailyLogs", connection))
                {
                    using (var reader = await command.ExecuteReaderAsync())
                    {
                        while (await reader.ReadAsync())
                        {
                            var log = new DailyLog
                            {
                                FNSKU = reader["FNSKU"] is DBNull ? null : reader["FNSKU"].ToString(),
                                RECORD_DATE = reader["RECORD_DATE"] is DBNull ? DateTime.MinValue : DateTime.Parse(reader["RECORD_DATE"].ToString()),
                                SYS_IP = reader["SYS_IP"] is DBNull ? null : reader["SYS_IP"].ToString(),
                                USER_ID = reader["USER_ID"] is DBNull ? null : reader["USER_ID"].ToString(),
                                LIVE_WEIGHT = reader["LIVE_WEIGHT"] is DBNull ? 0 : Convert.ToDecimal(reader["LIVE_WEIGHT"].ToString()),
                                WRONG_FNSKU = reader["WRONG_FNSKU"] is DBNull ? null : reader["WRONG_FNSKU"].ToString(),
                                IS_WEIGHT_WRONG = reader["IS_WEIGHT_WRONG"] is DBNull ? false : Convert.ToBoolean(reader["IS_WEIGHT_WRONG"]),
                                IS_FNSKU_WRONG = reader["IS_FNSKU_WRONG"] is DBNull ? false : Convert.ToBoolean(reader["IS_FNSKU_WRONG"]),
                                NET_WEIGHT = reader["NET_WEIGHT"] is DBNull ? 0 : Convert.ToDecimal(reader["NET_WEIGHT"].ToString()),
                                MODEL_NO = reader["MODEL_NO"] is DBNull ? "0" : reader["MODEL_NO"].ToString(),
                                WRONG_CARTON = reader["WRONG_CARTON"] is DBNull ? null : reader["WRONG_CARTON"].ToString(),
                                MARKET_PLACE = reader["MARKET_PLACE"] != DBNull.Value ? reader["MARKET_PLACE"].ToString() : "NA",
                                PC_NAME = reader["PC_NAME"] is DBNull ? null : reader["PC_NAME"].ToString(),
                            };

                            logs.Add(log);
                        }
                    }
                }

                return logs;
            }
            catch (Exception ex)
            {
                // Handle exceptions, log them, or rethrow if needed.
                Console.WriteLine($"Error in GetAllLogsFromDatabaseAsync: {ex.Message}");
                throw;
            }
        }
        public string ConvertLogsToJson(List<DailyLog> logs)
        {
            var jsonLogs = logs.Select(log => new
            {
                log.FNSKU,
                log.RECORD_DATE,
                log.SYS_IP,
                log.USER_ID,
                log.LIVE_WEIGHT,
                log.WRONG_FNSKU,
                log.IS_WEIGHT_WRONG,
                log.IS_FNSKU_WRONG,
                log.NET_WEIGHT,
                log.MODEL_NO,
                log.WRONG_CARTON,
                log.MARKET_PLACE,
                log.PC_NAME
            });

            return Newtonsoft.Json.JsonConvert.SerializeObject(jsonLogs, Newtonsoft.Json.Formatting.Indented);
        }
        public string ConvertLogsToJsonCarton(List<MODELLog> logs)
        {
            var jsonLogs = logs.Select(log => new
            {
                log.MODEL_NO,
                log.QR,
                log.RECORD_DATE,
                log.SYS_IP,
                log.USER_ID,
                log.LIVE_WEIGHT,
                log.PC_NAME,
                log.MARKET_PLACE

            });

            return Newtonsoft.Json.JsonConvert.SerializeObject(jsonLogs, Newtonsoft.Json.Formatting.Indented);
        }


        public void DeleteAllLogsFromDatabase()
        {

            OpenConnection();
            using (var transaction = connection.BeginTransaction())
            {
                try
                {
                    using (var command = new SQLiteCommand("DELETE FROM DailyLogs", connection))
                    {
                        command.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    CloseConnection();
                    // Handle the exception, e.g., log it or throw a custom exception
                    Console.WriteLine($"Error deleting logs: {ex.Message}");
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    CloseConnection();
                }
            }
        }
        public void DeleteAllLogsFromDatabaseCarton()
        {

            OpenConnection();
            using (var transaction = connection.BeginTransaction())
            {
                try
                {
                    using (var command = new SQLiteCommand("DELETE FROM MODELLogs", connection))
                    {
                        command.ExecuteNonQuery();
                    }

                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    CloseConnection();
                    // Handle the exception, e.g., log it or throw a custom exception
                    Console.WriteLine($"Error deleting logs: {ex.Message}");
                    transaction.Rollback();
                    throw;
                }
                finally
                {
                    CloseConnection();
                }
            }
        }


        public async void postDataAsync()
        {
            HttpClient client = new HttpClient();
            client.Timeout = TimeSpan.FromMinutes(5);

            OpenConnection();

            try
            {
                List<DailyLog> logs = await GetAllLogsFromDatabaseAsync();

                if (logs.Count > 0)
                {
                    CloseConnection();
                    string jsonData = ConvertLogsToJson(logs);

                    // Create a StringContent object with JSON data
                    var content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                    // Send a POST request with the data
                    var response = await client.PostAsync(SERVER_URL, content);

                    if (response.IsSuccessStatusCode)
                    {
                        // Handle a successful response
                        string responseString = await response.Content.ReadAsStringAsync();
                        DeleteAllLogsFromDatabase();


                        MessageBox.Show("DATA POSTED SUCCESSFULLY ! ");
                        _mainForm.btn_post_data.Enabled = true;
                    }
                    else
                    {
                        MessageBox.Show("ERROR POSTING DATA ! ");
                        _mainForm.btn_post_data.Enabled = true;
                    }
                }
                else
                {
                    MessageBox.Show("NO DATA FOUND ! ");
                    _mainForm.btn_post_data.Enabled = true;
                }
            }
            catch (HttpRequestException ex)
            {
                // Handle exception indicating server is down or unreachable
                MessageBox.Show($"Error: {ex.Message}");

            }
        }

        public async void postDataAsyncCarton()
        {
            HttpClient client = new HttpClient();
            client.Timeout = TimeSpan.FromMinutes(5);

            OpenConnection();

            try
            {
                List<MODELLog> logs = await GetAllLogsFromDatabaseAsyncCarton();

                if (logs.Count > 0)
                {
                    CloseConnection();
                    string jsonData = ConvertLogsToJsonCarton(logs);

                    // Create a StringContent object with JSON data
                    var content = new StringContent(jsonData, Encoding.UTF8, "application/json");

                    // Send a POST request with the data
                    var response = await client.PostAsync(SERVER_URL_CARTON, content);

                    if (response.IsSuccessStatusCode)
                    {
                        // Handle a successful response
                        string responseString = await response.Content.ReadAsStringAsync();
                        DeleteAllLogsFromDatabaseCarton();


                       // MessageBox.Show("DATA POSTED SUCCESSFULLY ! ");
                        _mainForm.btn_post_data.Enabled = true;
                    }
                    else
                    {
                       // MessageBox.Show("ERROR POSTING DATA ! " + response.StatusCode);

                        _mainForm.btn_post_data.Enabled = true;
                    }
                }
                else
                {
                    //MessageBox.Show("NO DATA FOUND ! ");
                    _mainForm.btn_post_data.Enabled = true;
                }
            }
            catch (HttpRequestException ex)
            {
                // Handle exception indicating server is down or unreachable
                MessageBox.Show($"Error: {ex.Message}");

            }
        }
    }
}