
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using System.Net.Http;
using System.Media;
using System.Text.RegularExpressions;
using System.IO;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Globalization;
using System.Data;
using Newtonsoft.Json;
using System.IO.Ports;
using static AVS.LiteDbClass;
using System.Drawing;
using static AVS.DailyLog;
using RJCP.IO.Ports;
using System.Threading;
using System.Diagnostics.Contracts;
using static AVS.MODELLog;
using Microsoft.Management.Infrastructure;
using Newtonsoft.Json.Linq;
using MaterialSkin.Controls;
using System.ComponentModel;
using System.Linq;
using System.Diagnostics;
using System.Reflection;
using System.Management;
using System.Runtime.InteropServices;

namespace AVS
{
    public partial class MainForm : MaterialForm
    {

        // Define the necessary P/Invoke signatures
        const uint DIGCF_PRESENT = 0x00000002;
        const uint DIGCF_ALLCLASSES = 0x00000004;
        const uint DIF_DISABLE = 0x00000012;
        const uint DIF_ENABLE = 0x00000011;

        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr SetupDiGetClassDevs(IntPtr classGuid, string enumerator, IntPtr hwndParent, uint flags);

        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiEnumDeviceInfo(IntPtr deviceInfoSet, uint memberIndex, ref SP_DEVINFO_DATA deviceInfoData);

        [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetupDiCallClassInstaller(uint InstallFunction, IntPtr deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData);

        [DllImport("setupapi.dll")]
        static extern bool SetupDiDestroyDeviceInfoList(IntPtr deviceInfoSet);

        [StructLayout(LayoutKind.Sequential)]
        public class SP_DEVINFO_DATA
        {
            public uint cbSize;
            public Guid ClassGuid;
            public uint DevInst;
            public IntPtr Reserved;
        }

        private readonly SemaphoreSlim _operationLock = new SemaphoreSlim(1, 1);
        string Softwareversion;

        string SVNversion;
        static string part1;
        static string part2;
        private Label userTextBox;
        string fnsku = "";
        public static MainForm mainForm;

        private LiteDbClass liteDbClass;

        static ConnectionClass ConnectionClass = new ConnectionClass();
        static MaterialSkinClass MaterialSkinClass = new MaterialSkinClass();
        MySqlConnection connectionString = null;
        DailyLog log = new DailyLog();
        MODELLog Moellog = new MODELLog();
        SKULog SKULog = new SKULog();
        DailyLog LogData = new DailyLog();
        Updater Updater = new Updater();

        public static string filePath = "C:\\Users\\Public\\Documents\\AVS\\credentials.txt";
        public static string filePathPressed = "button.txt";


        private string SERVER_URL;
        private string SERVER_URL_CONTAINER;
        private string SERVER_URL_MOEDEL_NO;

        private Form LoginForm;

        private Form CartonForm;
        private int count = 0;
        private int boxcount = 0;

        private int selectedRowIndex = -1;
        //  private string barcodePattern = @"^X[\w\d\s]+$"; // barcode pattern
        private string barcodePattern = @"^[A-Za-z0-9][\w\d\s]*$";
        private string desktopIp;
        private DataTable FinalexcelDataTable;
        private int exceclRowCount = 0;

        public string modelNO;
        private string userID = "0";
        int int_item_per_box;
        int int_item_count;
        public bool global_cb_carton = false;
        static string portname = null;

        double PreviousWeight = 0;

        private SerialPortStream _serialPort;

        private System.Threading.Timer _timer;



        WeightTolerance WeightTolerance = new WeightTolerance();
        //[STAThread]

        public SoundPlayer soundPlayer = new SoundPlayer();

        private System.Timers.Timer backgroundTimer;
        private MySqlConnectivity dbHelper;
        public MainForm(string userId, bool cb_carton)
        {
            this.AutoScaleMode = AutoScaleMode.Dpi;

            liteDbClass = new LiteDbClass(this);
            userID = userId;
            InitializeComponent();
            this.AutoScroll = true;
            MaterialSkinClass.ApplySkin(this);

            // this.WindowState = FormWindowState.Maximized;

            connectionString = new MySqlConnection(ConnectionClass.connectionString);


            MinimizeBox = false;
            MaximizeBox = false;
            desktopIp = GetSystemIp().ToString();
            SERVER_URL = ConnectionClass.SERVER_URL.ToString();

            SERVER_URL_CONTAINER = ConnectionClass.SERVER_URL_CONTAINER.ToString();
            SERVER_URL_MOEDEL_NO = ConnectionClass.SERVER_URL_MOEDEL_NO.ToString();

            liteDbClass.CheckAndCreateDb();


            List<MODELLog.TableColumn> column = MODELLogTable.GetColumns();
            liteDbClass.CreateMODELlogTable("MODELLogs", column);
            if (cb_carton == true)
            {
                global_cb_carton = true;
               
                dataGridView.DataSource = liteDbClass.showModelData();


                int total = dataGridView.Rows.Count;
                lbl_total.Text = "Total : "+total.ToString();

            }
            else
            {
                List<SKULog.TableColumn> columns = AVS.SKULog.SKULogTable.GetColumns();
                liteDbClass.CreateSKUlogTable("SKUlogs", columns);
                List<DailyLog.TableColumn> Tablecolumns = DailyLogTable.GetColumns();
                liteDbClass.CreateDailylogTable("DailyLogs", Tablecolumns);
                dataGridView.DataSource = liteDbClass.showData();


                List<WeightTolerance.TableColumn> WeightToleranceColumns = AVS.WeightTolerance.WeightToleranceTable.GetColumns();
                liteDbClass.CreateToleranceTable("Weight_Tolerance", WeightToleranceColumns); 


            }

            fillMarketPlaces();
            // set the default column width for all columns
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
            //dataGridView.CellClick += dataGridView_CellClick;


            showToolTips();
            dbHelper = new MySqlConnectivity(); 
            StartBackgroundTask();
        }
        public void showToolTips()
        {
            System.Windows.Forms.ToolTip ToolTip1 = new System.Windows.Forms.ToolTip();
            ToolTip1.SetToolTip(this.btn_close, "Close");

            System.Windows.Forms.ToolTip ToolTip2 = new System.Windows.Forms.ToolTip();
            ToolTip1.SetToolTip(this.btn_logout, "Logout");

            System.Windows.Forms.ToolTip ToolTip3 = new System.Windows.Forms.ToolTip();
            ToolTip1.SetToolTip(this.btn_minimize, "Minimize");

            System.Windows.Forms.ToolTip ToolTip4 = new System.Windows.Forms.ToolTip();
            ToolTip1.SetToolTip(this.pb_blue, "Machine signals");
            System.Windows.Forms.ToolTip ToolTip5 = new System.Windows.Forms.ToolTip();
            ToolTip1.SetToolTip(this.pb_red, "Machine signals");
        }
        public void fillMarketPlaces()
        {
            MarketplaceService service = new MarketplaceService();
            List<Marketplace> marketplaces = service.GetMarketplaces();

            cb_marketplace.DisplayMember = "Name";
            cb_marketplace.ValueMember = "Id";
            cb_marketplace.DataSource = marketplaces;

        }


        private void txt_barcode_KeyPress(object sender, KeyPressEventArgs e)
        {

            if (e.KeyChar == (char)13)
            {
                this.Enabled = false;

                if (lbl_hold_weight.Text == "0" || (Convert.ToDouble(lbl_hold_weight.Text) < 0.121))
                {
                    txt_barcode.Text = "";
                    this.Enabled = true;
                    //MessageBox.Show("Please provide weight !");
                    AutoClosingMessageBox.Show("Please provide weight !", "Weight Msg", 1000);
                    return;
                }


                string barcode = txt_barcode.Text.Trim().ToUpper();

                if (string.IsNullOrEmpty(barcode))
                {
                    e.Handled = true; // Prevent the system sound
                    txt_barcode.Text = "";
                    this.Enabled = true;
                    MessageBox.Show("Please provide FNSKU !");
                    return;
                }


                if (global_cb_carton == false)
                {

                    if (string.IsNullOrEmpty(lbl_fnsku.Text))
                    {
                        e.Handled = true; // Prevent the system sound
                        txt_barcode.Text = "";
                        this.Enabled = true;
                        MessageBox.Show("Please select SKU !");
                        return;
                    }
                    
                }

                //FOR ONLY CARTON ----------------------------------------------

                if (global_cb_carton == true)
                {
                    if (cb_marketplace.SelectedIndex == 0)
                    {
                        this.Enabled = true;
                        MessageBox.Show("Please select market place");
                        return;
                    }
                    lbl_ScanDateTime.Text = "Scan time - " + DateTime.Now.ToString();

                    var barcodeParts = barcode.Split(';');

                    if (barcodeParts.Length == 2)
                    {
                        // Example usage of parts:
                        part1 = barcodeParts[0]; // "UT0369"
                        part2 = barcodeParts[1]; // "241106052682"

                        // You can use these parts as needed. For example:
                        _ = VerifyBarcodeCarton(part1, "CONT", "", cb_marketplace.Text);

                       
                    }
                    else
                    {

                        MessageBox.Show("Incorrect model no");
                        this.Enabled = true;
                        return;
                    }

                }

                //FOR UINT AND CARTON
                else
                {

                    lbl_ScanDateTime.Text = "Scan time - " + DateTime.Now.ToString();

                    if (Regex.IsMatch(barcode, barcodePattern, RegexOptions.IgnoreCase))
                    {

                        if (barcode != LabelFnsku)
                        {
                            HandleMismatchedValues(barcode);
                            //MessageBox.Show("Invalid FNSKU !");
                        }

                        else
                        {
                            if (userTextBox.Text.Contains("SITE05") || userTextBox.Text.Contains("SITE06"))
                            {
                                // Check for weight tolerance (+-5 %)
                                double lowerLimit = 0;
                                double upperLimit = 0;

                                if (double.TryParse(txt_weight_tol.Text, out double tolWeight) &&
                                    double.TryParse(lbl_hold_weight.Text, out double actualWeight))
                                {
                                    //For pillow Site05  (+-3 %)

                                    if (userTextBox.Text.Contains("SITE05"))
                                    {
                                        lowerLimit = tolWeight * 0.97;
                                        upperLimit = tolWeight * 1.03;
                                    }
                                    else
                                    {
                                        lowerLimit = tolWeight * 0.95;
                                        upperLimit = tolWeight * 1.05;

                                    }

                                    if (actualWeight < lowerLimit || actualWeight > upperLimit)
                                    {
                                        PlayAlertSound();
                                        OpenLoginForm(false, "Weight Tolerance");
                                        txt_barcode.Text = "";
                                        this.Enabled = true;

                                    }
                                    else
                                    {
                                        VerifyBarcodeOffline(txt_barcode.Text.Trim());
                                    }
                                }
                                else
                                {
                                    // Optional: handle invalid input
                                    MessageBox.Show("Invalid weight tolerance.");
                                    this.Enabled = true;
                                }
                            }

                            //For Site02 without tolerance
                            else
                            {
                                VerifyBarcodeOffline(txt_barcode.Text.Trim());
                            }
                        }
                    }
                    else
                    {
                        e.Handled = true; // Prevent the system sound
                        MessageBox.Show("Invalid FNSKU");
                        Resetvalues();
                        this.Enabled = true;
                    }

                }

            }
            else
            {

            }

        }
        public void VerifyBarcodeOffline(string barcode)
        {
            lbl_error.Visible = false;
           if (Convert.ToDouble(lbl_hold_weight.Text) > 0.121)
            {

                count++;
                lbl_counter.Text = "Item count : " + count;
                lbl_detail.Text = SKULog.Title;
                lbl_fnsku.Text = SKULog.FNSKU;
                lbl_sku.Text = SKULog.SKU;
                lbl_netWeight.Text = "Net weight : " + SKULog.NetWeightKg;

                ScanTimeText = System.DateTime.Now;
                lbl_ScanDateTime.Text = "Scan time: " + ScanTimeText.ToString("yyyy-MMM-dd hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
                lbl_color.Text = SKULog.Colour;
                lbl_size.Text = SKULog.Size;
                string formattedDate = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                DailyLog Dailylog = new DailyLog()
                {
                    FNSKU = txt_barcode.Text.ToString().ToUpper(),
                    SYS_IP = desktopIp,
                    RECORD_DATE = Convert.ToDateTime(formattedDate),
                    LIVE_WEIGHT = Convert.ToDecimal(lbl_hold_weight.Text),
                    WRONG_FNSKU = "0",
                    IS_FNSKU_WRONG = false,
                    IS_WEIGHT_WRONG = false,
                    USER_ID = userID,
                    MODEL_NO = SKULog.ModelNo,
                    NET_WEIGHT = Convert.ToDecimal(SKULog.NetWeightKg),
                    MARKET_PLACE = SKULog.MARKET_PLACE,
                    PC_NAME = userTextBox.Text.ToString().ToUpper()

                };
                liteDbClass.InsertRecord("DailyLogs", Dailylog, "FNSKU", null);



                int_item_per_box = ExtractValue(lbl_item_box.Text);
                int_item_count = ExtractValue(lbl_counter.Text);
                if (int_item_count != int_item_per_box && int_item_count % int_item_per_box != 0)
                {

                }
                else
                {
                    if (int_item_count > 0)
                    {

                      if (Convert.ToDouble(lbl_hold_weight.Text) > 0.121)
                        {
                            boxcount++;
                            lbl_boxCount.Text = "Box count : " + boxcount.ToString();
                            int id = liteDbClass.GetLastRecord();
                            OpenCartonForm(id, Dailylog);

                        }
                    }
                }
                lbl_hold_weight.Text = "0";
            }

            txt_barcode.Text = "";
            this.Enabled = true;
            txt_barcode.Focus();

        }

        void HandleMismatchedValues(string barcode)
        {
            this.Enabled = true;

            InsertDailyLog(barcode, true, false);
            PlayAlertSound();
            OpenLoginForm(false,null);
            txt_barcode.Text = "";


        }


        int ExtractValue(string input)
        {
            Match match = Regex.Match(input, @"\d+");
            // Check if a match was found and parse the integer
            if (match.Success)
            {

                return int.Parse(match.Value);
            }
            return 0;
        }

        void PlayAlertSound()
        {
            string soundFilePath = @"C:\Users\Public\Documents\AVS\alert-alaram.wav";
            soundPlayer.SoundLocation = soundFilePath;
            soundPlayer.PlayLooping();
        }
        void InsertDailyLog(string barcode, bool isFnskuWrong, bool isWeightWrong)
        {
            string formattedDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            DailyLog dailyLog = new DailyLog()
            {
                FNSKU = lbl_fnsku.Text,
                SYS_IP = desktopIp,
                RECORD_DATE = Convert.ToDateTime(formattedDate),
                LIVE_WEIGHT = Convert.ToDecimal(lbl_hold_weight.Text),
                WRONG_FNSKU = barcode,
                IS_FNSKU_WRONG = isFnskuWrong,
                IS_WEIGHT_WRONG = isWeightWrong,
                USER_ID = userID,
                MODEL_NO = SKULog.ModelNo,
                NET_WEIGHT = Convert.ToDecimal(SKULog.NetWeightKg),
                PC_NAME = userTextBox.Text.ToString().ToUpper(),
                MARKET_PLACE = SKULog.MARKET_PLACE

            };
            liteDbClass.InsertRecord("DailyLogs", dailyLog, "SKU", null);

        }


        public IPAddress GetSystemIp()
        {
            string hostName = Dns.GetHostName();
            IPAddress[] ipAddresses = Dns.GetHostAddresses(hostName);

            foreach (IPAddress ipAddress in ipAddresses)
            {
                if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
                {
                    lb_sysIp.Text = ipAddress.ToString();

                    return ipAddress;
                }

            }
            return null;
        }

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

            string cleanedScanDate = lbl_ScanDateTime.Text.Replace("Scan time:", "").Trim();
            DateTime inputDate = DateTime.ParseExact(cleanedScanDate, "yyyy-MMM-dd hh:mm tt", CultureInfo.InvariantCulture);

            // Format the date in MySQL datetime format
            string mysqlFormattedDate = inputDate.ToString("yyyy-MM-dd HH:mm:ss");
            // Create a dictionary to hold your data
            Dictionary<string, string> data = new Dictionary<string, string>
              {

                  { "user_id", "0" },
                  { "fnsku", lbl_fnsku.Text },
                  { "scan_date", mysqlFormattedDate },
                  { "desktop_ip", desktopIp+"-"+ userTextBox.Text.ToString().ToUpper() }
                  // You can add more key-value pairs as needed
              };



            // Serialize the data to JSON
            string jsonData = JsonConvert.SerializeObject(data);

            // 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();
                // Process the response as needed
            }
            else
            {
                // Handle an error response
                // You can access response.StatusCode and response.ReasonPhrase for details
            }
        }
        public async Task VerifyBarcodeCarton(string barcode, string type, string command, string marketPlace)
        {
            try
            {
                if (global_cb_carton == true)
                {
                    lbl_error.Visible = false;
                    using (HttpClient client = new HttpClient())
                    {
                        client.Timeout = TimeSpan.FromMinutes(5);
                        string parameter = $"{barcode}&marketplace={marketPlace}";

                        var response = await client.GetAsync($"{SERVER_URL_MOEDEL_NO}{parameter}");
                        string responseString = await response.Content.ReadAsStringAsync();

                        if (responseString.Equals("Invalid MODEL NO") || responseString.Contains("error 69"))
                        {
                            HandleInvalidFNSKU(command);
                        }
                        else
                        {
                            if (response.IsSuccessStatusCode)
                            {
                                HandleValidFNSKU(responseString, command);
                            }
                            else
                            {
                                MessageBox.Show("Invalid response");
                            }
                        }

                        txt_barcode.Text = "";

                        this.Enabled = true;
                        txt_barcode.Focus();

                    }
                }

            }
            catch (Exception ex)
            {
                this.Enabled = true;

                if (ex.Message.Contains("Unexpected character encountered"))
                {
                    lbl_error.Text = "Unexpected character encountered!";
                    lbl_error.Visible = true;
                }

                else
                {
                    lbl_error.Text = "INTERNET/COSMOS not working!";
                    lbl_error.Visible = true;
                }
            }


        }

        public async Task GetSku(string barcode, string type)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    SKULog = new SKULog();
                    client.Timeout = TimeSpan.FromMinutes(5);
                    string parameter = $"{barcode}&type={type}";
                    if (cb_marketplace.SelectedIndex > 0)
                    {
                        string selectedMarketplace = cb_marketplace.Text; // Get the selected item text
                        parameter = $"{parameter}&marketplace={selectedMarketplace}";
                    }
                    var response = await client.GetAsync($"{SERVER_URL}{parameter}");
                    string responseString = await response.Content.ReadAsStringAsync();

                    if (responseString.Equals("Invalid FNSKU") || responseString.Equals("Invalid 'DATA'"))
                    {
                        MessageBox.Show("Invalid FNSKU / market place!");

                    }
                    else
                    {
                        string formattedDate = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        Dictionary<string, string> data = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);
                        txt_sku.Text = data["sku"].ToString();



                        if (!string.IsNullOrEmpty(txt_sku.Text))
                            SKULog.SKU = txt_sku.Text.ToString().ToUpper();

                        SKULog.SYS_IP = desktopIp; // Assuming desktopIp is never null



                        if (!string.IsNullOrEmpty(formattedDate))
                            SKULog.RECORD_DATE = Convert.ToDateTime(formattedDate);

                        SKULog.USER_ID = userID; // Assuming userID is never null

                        if (data.ContainsKey("itemPerBox") && data["itemPerBox"] != null)
                            SKULog.ItemsPerBox = Convert.ToInt16(data["itemPerBox"]);

                        if (data.ContainsKey("fnsku") && data["fnsku"] != null)
                            SKULog.FNSKU = data["fnsku"].ToString();

                        if (data.ContainsKey("title") && data["title"] != null)
                            SKULog.Title = data["title"].ToString();

                        if (data.ContainsKey("netWeightKg") && data["netWeightKg"] != null)
                            SKULog.NetWeightKg = Convert.ToDouble(data["netWeightKg"].ToString());

                        if (data.ContainsKey("colour") && data["colour"] != null)
                            SKULog.Colour = data["colour"].ToString();

                        if (data.ContainsKey("size") && data["size"] != null)
                            SKULog.Size = data["size"].ToString();

                        if (data.ContainsKey("modelNo") && data["modelNo"] != null)
                            SKULog.ModelNo = data["modelNo"].ToString();
                        if (cb_marketplace.SelectedIndex > 0)
                        {
                            SKULog.MARKET_PLACE = cb_marketplace.Text;
                        }
                        else
                        {
                            SKULog.MARKET_PLACE = "NA";
                        }
                        // Now you can insert the record
                        liteDbClass.InsertRecord("SKUlogs", SKULog, "SKU", "MARKET_PLACE");
                        dataGridView.DataSource = liteDbClass.showData();


                    }
                    txt_sku.Text = "";
                }
            }
            catch (Exception ex)
            {

            }
        }

        public class ContainerItem
        {
            public string property1 { get; set; }
            public string property2 { get; set; }
            // Add other properties as needed
        }


        public async Task GetContainerDetail(string barcode)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMinutes(5);
                    string parameter = $"{barcode}";

                    var response = await client.GetAsync($"{SERVER_URL_MOEDEL_NO}{parameter}");
                    string responseString = await response.Content.ReadAsStringAsync();

                    if (!response.IsSuccessStatusCode)
                    {
                        MessageBox.Show("Invalid Container # ");

                    }
                    else
                    {
                        Dictionary<string, string> data = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);

                        // Extract values directly from the dictionary
                        string sku = data.ContainsKey("sku") ? data["sku"] : "";
                        string size = data.ContainsKey("size") ? data["size"] : "";
                        string color = data.ContainsKey("color") ? data["color"] : "";
                        string model = data.ContainsKey("model") ? data["model"] : "";
                        int unitPerBox = data.ContainsKey("unitPerBox") ? int.Parse(data["unitPerBox"]) : 0;
                        string name = data.ContainsKey("name") ? data["name"] : "";
                        string shipFrom = data.ContainsKey("shipFrom") ? data["shipFrom"] : "";
                        string shipTo = data.ContainsKey("shipTo") ? data["shipTo"] : "";

                        // Log creation
                        string formattedDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                        MODELLog log = new MODELLog()
                        {
                            //CONTAINER_NO = barcode,
                            MODEL_NO = model,
                            SYS_IP = $"{desktopIp}",
                            RECORD_DATE = DateTime.Parse(formattedDate),
                            USER_ID = userID,

                        };


                        liteDbClass.InsertRecord("MODELLogs", log, "CONTAINER_NO", "MODEL_NO");


                    }
                }

                txt_sku.Text = "";
                dataGridView.DataSource = liteDbClass.showModelData();
            }
            catch (Exception ex)
            {

            }
        }


        private void HandleInvalidFNSKU(string command)
        {
            if (command == "forSKU")
            {
                // Handle 'forSKU' command
            }
            else
            {
                PlayAlertSound();
                OpenLoginForm(false,null);
            }
        }

        private void HandleValidFNSKU(string responseString, string command)
        {
            if (command == "forSKU")
            {
                ProcessForSKUResponse(responseString);
            }
            else
            {
                ProcessDefaultResponse(responseString);
            }
        }
        private void ProcessForSKUResponse(string responseString)
        {
            Dictionary<string, string> data = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);
            lbl_fnsku.Text = data["fnsku"].ToString();
            lbl_item_box.Text = "Item per box : " + data["itemPerBox"].ToString();
            lbl_counter.Text = "Item count : " + liteDbClass.FillCounts(lbl_fnsku.Text, SKULog.MARKET_PLACE).ToString();

            if (Int16.TryParse(Regex.Match(lbl_counter.Text, @"\d+").Value, out Int16 countt) &&
                Int16.TryParse(Regex.Match(lbl_item_box.Text, @"\d+").Value, out Int16 itemPerBox))
            {
                int boxCountt = countt / itemPerBox;

                lbl_boxCount.Text = "Box count : " + boxCountt;
                lbl_counter.Text = "Item count : " + countt;
                count = countt;
                boxcount = boxCountt;

            }
        }

        private void ProcessDefaultResponse(string responseString)
        {

            if (global_cb_carton == true)
            {

                //Check record already exist

                if (liteDbClass.checkCarton(part1, part2) == true)
                {
                    PlayAlertSound();
                    OpenLoginForm(true,null);

                }
                else
                {

                    ScanTimeText = System.DateTime.Now;
                    lbl_ScanDateTime.Text = "Scan time: " + ScanTimeText.ToString("yyyy-MMM-dd hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
                    Dictionary<string, string> data = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);


                    count = liteDbClass.FillCarton(data["model"].ToString());
                    count++;

                    lbl_boxCount.Text = "Carton count : " + count;
                    if (data["name"] != null)
                        lbl_detail.Text = data["name"].ToString();

                    if (data["sku"] != null)
                        lbl_sku.Text = data["sku"].ToString();

                    if (data["color"] != null)
                        lbl_color.Text = data["color"].ToString();

                    if (data["size"] != null)
                        lbl_size.Text = data["size"].ToString();

                    if (data["model"] != null)
                        lbl_fnsku.Text = data["model"].ToString();

                    if (data["shipTo"] != null)
                        lbl_ship_to.Text = data["shipTo"].ToString();

                    if (data["shipFrom"] != null)
                        lbl_ship_from.Text = data["shipFrom"].ToString();


                    string formattedDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    MODELLog log = new MODELLog()
                    {
                        //CONTAINER_NO = barcode,
                        QR = part2,
                        MODEL_NO = data["model"].ToString(),
                        SYS_IP = $"{desktopIp}",
                        RECORD_DATE = DateTime.Parse(formattedDate),
                        USER_ID = userID,
                        LIVE_WEIGHT = Convert.ToDecimal(lbl_hold_weight.Text),
                        PC_NAME = userTextBox.Text.ToString().ToUpper(),
                        MARKET_PLACE = cb_marketplace.Text

                    };


                    liteDbClass.InsertRecord("MODELLogs", log, "CONTAINER_NO", "MODEL_NO");
                    dataGridView.DataSource = liteDbClass.showModelData();
                }
            }
            else
            {
                if (Convert.ToDouble(lbl_hold_weight.Text) > 0.121)
                {

                    Dictionary<string, string> data = JsonConvert.DeserializeObject<Dictionary<string, string>>(responseString);
                    count++;
                    lbl_counter.Text = "Item count : " + count;
                    lbl_detail.Text = data["title"].ToString();

                    lbl_fnsku.Text = data["fnsku"].ToString();
                    lbl_sku.Text = data["sku"].ToString();
                    lbl_netWeight.Text = "Net weight : " + data["netWeightKg"].ToString();

                    ScanTimeText = System.DateTime.Now;
                    lbl_ScanDateTime.Text = "Scan time: " + ScanTimeText.ToString("yyyy-MMM-dd hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
                    lbl_color.Text = data["colour"].ToString();
                    lbl_size.Text = data["size"].ToString();
                    string formattedDate = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    DailyLog Dailylog = new DailyLog()
                    {
                        FNSKU = txt_barcode.Text.ToString().ToUpper(),
                        SYS_IP = desktopIp,
                        RECORD_DATE = Convert.ToDateTime(formattedDate),
                        LIVE_WEIGHT = Convert.ToDecimal(lbl_hold_weight.Text),
                        WRONG_FNSKU = "0",
                        IS_FNSKU_WRONG = false,
                        IS_WEIGHT_WRONG = false,
                        USER_ID = userID,
                        MODEL_NO = data["modelNo"].ToString(),
                        NET_WEIGHT = Convert.ToDecimal(data["netWeightKg"].ToString()),
                        PC_NAME = userTextBox.Text.ToString().ToUpper()
                    };
                    liteDbClass.InsertRecord("DailyLogs", Dailylog, "FNSKU", null);



                    int_item_per_box = ExtractValue(lbl_item_box.Text);
                    int_item_count = ExtractValue(lbl_counter.Text);
                    if (int_item_count != int_item_per_box && int_item_count % int_item_per_box != 0)
                    {

                    }
                    else
                    {
                        if (int_item_count > 0)
                        {
                            //lbl_hold_weight.Text = "0.110";
                            if (Convert.ToDouble(lbl_hold_weight.Text) > 0.121)
                            {

                                boxcount++;
                                lbl_boxCount.Text = "Box count : " + boxcount.ToString();
                            }
                        }
                    }
                    lbl_hold_weight.Text = "0";
                }
            }
        }
        private void OpenLoginForm(bool val,string value)
        {

            this.Hide(); // Hide the MainForm
            LoginForm = new LoginForm(this, val, value);
            LoginForm.Show();
        }
        private void OpenCartonForm(int id , DailyLog dailyLog)
        {
            CartonForm cartonForm = new CartonForm(SKULog.ModelNo.Trim(), id, dailyLog, SKULog);

            // Disable the maximize and minimize buttons
            cartonForm.MaximizeBox = false;
            cartonForm.MinimizeBox = false;

            // Set the form border style to FixedDialog to remove the resizable border
            cartonForm.FormBorderStyle = FormBorderStyle.FixedDialog;

            cartonForm.ShowDialog();
        }
        public void Resetvalues()
        {
            lbl_sku.Text = "Sku : ";
            lbl_detail.Text = "Title : ";
            lbl_ScanDateTime.Text = "Scan time : ";
            lbl_netWeight.Text = "Net weight : ";
            txt_barcode.Text = "";
            lbl_size.Text = "Size : ";
            lbl_color.Text = "Color : ";

        }
        public void ShowControls()
        {
            lbl_sku.Visible = true;
            lbl_ScanDateTime.Visible = true;
            lbl_detail.Visible = true;

            lbl_netWeight.Visible = true;
        }

        public void CartonControls()
        {
            lbl_counter.Visible = false;

            txt_sku.Hint = "Scan QR #";
            // btn_upload.Visible = true;
            lbl_netWeight.Visible = false;
            lbl_item_box.Text = "Unit per carton : 0";
            lbl_boxCount.Text = "Carton count : 0";

            txt_sku.Visible = false;
            txt_search.Visible = false;
            lbl_item_box.Visible = false;
            btn_delete.Visible = false;

            //lbl_boxCount.Location = new Point(1610, 90);
            //lbl_item_box.Location = new Point(1580, 120);

            btn_upload.Location = new Point(336, 81);
            btn_update.Location = new Point(431, 81);
            lblBarcode.Text = "Model #";
            txt_barcode.MaxLength = 50;
            panel3.Visible = true;
            lbl_total.Visible = true;

        }

        private bool ReadCredentials()
        {
            // Initialize variables to store the values

            try
            {
                // Check if the file exists
                if (File.Exists(filePathPressed))
                {
                    using (StreamReader sr = new StreamReader(filePathPressed))
                    {
                        // Read the lines from the file
                        string[] lines = sr.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

                        // Check if there are enough lines (username and password)
                        if (lines.Length == 1)
                        {
                            DateTime dt = Convert.ToDateTime(lines[0]);
                            if (dt.ToShortDateString() == DateTime.Now.ToShortDateString())
                            {
                                btn_post_data.Enabled = false;
                            }
                            else
                            {
                                btn_post_data.Enabled = true;
                            }

                            // Successfully read the credentials
                            return true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Handle any exceptions that occur during file reading
                MessageBox.Show($"An error occurred while reading the file: {ex.Message}");
            }
            return false;
        }

        public void CheckAVSuser()
        {

            // Define the root directory and the file name
            string rootPath = @"C:\Users\Public\Documents\AVS\";  // Root path of the application

            string fileName = "user.txt";  // Text file to store the site ID
            string filePath = Path.Combine(rootPath, fileName);  // Full file path

            // Check if the file exists
            if (File.Exists(filePath))
            {
                // Read the content of the file (site ID)
                string user = File.ReadAllText(filePath);

                // Display the site ID in the TextBox
                userTextBox.Text = user;
                if (userTextBox.Text.Contains("SITE05") || userTextBox.Text.Contains("SITE06"))
                {
                    btn_save_tol.Visible = true;
                    lbl_weightTolerance.Visible = true;
                    txt_weight_tol.Visible = true;

                }
                else
                {
                    btn_save_tol.Visible = false;
                    lbl_weightTolerance.Visible = false;
                    txt_weight_tol.Visible = false;
                }

            }
            else
            {
                // Create the file and write "Site ID not available" if it doesn't exist
                string defaultText = "PC NAME NOT FOUND";
                File.WriteAllText(filePath, defaultText);

                // Display the default message in the TextBox
                userTextBox.Text = defaultText;
            }
        }

        private void MainForm_Load(object sender, EventArgs e)
        {

            lbl_username.Text = userID;
            //ReadCredentials();

            if (global_cb_carton == true)
            {
                CartonControls();

            }
            else
            {
                lbl_counter.Visible = true;
                lbl_item_box.Visible = true;
                lbl_boxCount.Visible = true;
                lbl_total.Visible = false;
            }

            //timer_weighing.Interval = 1000;
            //timer_weighing.Start();
            //timer_weighing_Tick(null, null);
            StartReading();
            CheckAVSuser();
            // fillMarketPlaces();
            Softwareversion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            lbl_ver.Text = "Version-" + Softwareversion;

        }
        static string GetPortDescription(string portName)
        {
            string query = $"SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%({portName})%'";
            CimSession cimSession = CimSession.Create(null);

            // Run the query
            IEnumerable<CimInstance> queryResults = cimSession.QueryInstances("root/cimv2", "WQL", query);

            foreach (CimInstance queryObj in queryResults)
            {
                return queryObj.CimInstanceProperties["Caption"].Value.ToString();
            }

            return "Description not available";
        }




        private void btn_close_Click(object sender, EventArgs e)
        {
            Application.Exit();

        }




        private void CheckAndInsertSKU()
        {
            try
            {
                if (txt_sku.Text.Length > 0)
                {
                    string formattedDate = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    _ = GetSku(txt_sku.Text.ToUpper().ToString(), "FNSKU");
                    this.Enabled = true;
                }
                else
                {
                    MessageBox.Show("Please provide SKU");
                }


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void dataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            // Check if the clicked area is a cell (not the header or anything else)
            if (e.RowIndex >= 0)
            {
                selectedRowIndex = e.RowIndex;


                lbl_fnsku.Text = "";

                foreach (DataGridViewRow row in dataGridView.Rows)
                {
                    row.DefaultCellStyle.BackColor = SystemColors.Window;
                }

                // Change the color of the clicked row
                DataGridViewRow selectedRow = dataGridView.Rows[e.RowIndex];
                selectedRow.DefaultCellStyle.BackColor = Color.Gray; // Change the color to your preference
                if (global_cb_carton == true)
                {
                    Moellog.MODEL_NO = selectedRow.Cells["MODEL_NO"].Value.ToString();
                    lbl_fnsku.Text = Moellog.MODEL_NO;
                    //lbl_item_box.Text = "Unit per carton : " + selectedRow.Cells["UNIT_PER_BOX"].Value.ToString();
                    lbl_boxCount.Text = "Carton count : " + liteDbClass.FillCarton(Moellog.MODEL_NO).ToString();

                }
                else
                {

                    fnsku = selectedRow.Cells["FNSKU"].Value.ToString();

                    // Now you can access the data in the selected row
                    SKULog.SKU = selectedRow.Cells["SKU"].Value.ToString();
                    txt_sku.Text = SKULog.SKU;

                    lbl_item_box.Text = "Item per box: " + selectedRow.Cells["itemsPerBox"].Value.ToString();
                    SKULog.ItemsPerBox = Convert.ToInt16(selectedRow.Cells["itemsPerBox"].Value.ToString());
                    SKULog.FNSKU = lbl_fnsku.Text = selectedRow.Cells["FNSKU"].Value.ToString();
                    SKULog.ModelNo = selectedRow.Cells["ModelNo"].Value.ToString();
                    SKULog.NetWeightKg = Convert.ToDouble(selectedRow.Cells["NetWeightKg"].Value.ToString());
                    SKULog.Size = selectedRow.Cells["Size"].Value.ToString();
                    SKULog.Colour = selectedRow.Cells["Colour"].Value.ToString();
                    SKULog.Title = selectedRow.Cells["Title"].Value.ToString();
                    SKULog.MARKET_PLACE = selectedRow.Cells["MARKET_PLACE"].Value.ToString();
                    lbl_market_place.Text = SKULog.MARKET_PLACE;
                    lbl_counter.Text = "Item count : " + liteDbClass.FillCounts(lbl_fnsku.Text, lbl_market_place.Text).ToString();
                    txt_weight_tol.Text = liteDbClass.GetWeightTolerance(fnsku, SKULog.MARKET_PLACE).ToString();    
                    if (Int16.TryParse(Regex.Match(lbl_counter.Text, @"\d+").Value, out Int16 countt) &&
                        Int16.TryParse(Regex.Match(lbl_item_box.Text, @"\d+").Value, out Int16 itemPerBox))
                    {
                        int boxCountt = countt / itemPerBox;

                        lbl_boxCount.Text = "Box count : " + boxCountt;
                        lbl_counter.Text = "Item count : " + countt;
                        count = countt;
                        boxcount = boxCountt;

                    }


                }
                Resetvalues();
            }
        }



        public DateTime ScanTimeText
        {
            get { return Convert.ToDateTime(lbl_ScanDateTime.Text); }
            set { lbl_ScanDateTime.Text = value.ToString(); }
        }
        public string LabelFnsku
        {
            get { return lbl_fnsku.Text; }
            set { lbl_fnsku.Text = value; }
        }

        public string LabelItemPerBox
        {
            get { return lbl_item_box.Text; }
            set { lbl_item_box.Text = value; }
        }



     

        private void btn_update_Click(object sender, EventArgs e)
        {
            if (selectedRowIndex >= 0)
            {

                string oldSKU = SKULog.SKU;
                string newSKU = txt_sku.Text.ToString();

                if (!liteDbClass.CheckSkuRunning(lbl_fnsku.Text, "DailyLogs"))
                {
                    liteDbClass.UpdateSKURecord("SKUlogs", oldSKU, newSKU);
                    dataGridView.DataSource = liteDbClass.showData();
                }

            }
            else
            {
                MessageBox.Show("Please select a row to update.");
            }
        }



        private void btn_logout_LinkClicked(object sender, EventArgs e)
        {
            File.Delete(filePath);

            this.Close();
            LoginForm form = new LoginForm(null, false,"LOGOUT");
            form.Show();
        }

        private void txt_sku_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (txt_sku.Text.Length > 0)
            {

                if (e.KeyChar == (char)13)
                {
                    this.Enabled = false;

                    if (cb_marketplace.SelectedIndex > 0)
                    {
                        CheckAndInsertSKU();
                    }
                    else
                    {
                        this.Enabled = true;
                        MessageBox.Show("Please select market place!", "Select market place", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }

                }
            }
        }

        private void btn_minimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (panel1.BorderStyle == BorderStyle.FixedSingle)
            {
                int thickness = 3;//it's up to you
                int halfThickness = thickness / 2;
                using (Pen p = new Pen(Color.Black, thickness))
                {
                    e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
                                                              halfThickness,
                                                              panel1.ClientSize.Width - thickness,
                                                              panel1.ClientSize.Height - thickness));
                }
            }
        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {
            if (panel2.BorderStyle == BorderStyle.FixedSingle)
            {
                int thickness = 3;//it's up to you
                int halfThickness = thickness / 2;
                using (Pen p = new Pen(Color.Black, thickness))
                {
                    e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
                                                              halfThickness,
                                                              panel2.ClientSize.Width - thickness,
                                                              panel2.ClientSize.Height - thickness));
                }
            }
        }

        private void panel3_Paint(object sender, PaintEventArgs e)
        {
            if (panel3.BorderStyle == BorderStyle.FixedSingle)
            {
                int thickness = 3;//it's up to you
                int halfThickness = thickness / 2;
                using (Pen p = new Pen(Color.Black, thickness))
                {
                    e.Graphics.DrawRectangle(p, new Rectangle(halfThickness,
                                                              halfThickness,
                                                               panel3.ClientSize.Width - thickness,
                                                               panel3.ClientSize.Height - thickness));
                }
            }
        }

        private void txt_search_TextChanged(object sender, EventArgs e)
        {
            string searchValue = txt_search.Text.ToUpper();

            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;

            try
            {
                bool valueResult = false;

                foreach (DataGridViewRow row in dataGridView.Rows)
                {
                    if (row.IsNewRow) continue;

                    bool rowMatchesSearch = false;

                    for (int i = 0; i < row.Cells.Count; i++)
                    {
                        if (row.Cells[i].Value != null && row.Cells[i].Value.ToString().ToUpper().Contains(searchValue))
                        {
                            rowMatchesSearch = true;
                            break;
                        }
                    }

                    int rowIndex = row.Index;

                    if (rowMatchesSearch)
                    {
                        dataGridView.Rows[rowIndex].Selected = true;
                        valueResult = true;
                    }
                    else
                    {
                        dataGridView.Rows[rowIndex].Selected = false;
                    }
                }

                if (!valueResult)
                {
                    // Clear selection when there is no search result
                    dataGridView.ClearSelection();
                    //MessageBox.Show("Unable to find " + txt_search.Text, "Not Found");
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }



        private async Task ReadFromSerialPort()
        {
            // Get a compatible port
            string portName = GetCompatiblePort(SerialPortStream.GetPortNames());

            if (string.IsNullOrEmpty(portName))
            {
                Debug.WriteLine("USB cable not connected with PC");
                UpdateUI("USB cable not connected with PC");
                return;
            }

            try
            {
                // Initialize and open the serial port if it's not already open
                if (_serialPort == null || !_serialPort.IsOpen)
                {
                    if (_serialPort != null && _serialPort.IsOpen)
                    {
                        _serialPort.Close();
                    }

                    _serialPort = new SerialPortStream(portName, 9600);
                    _serialPort.Open();
                    Debug.WriteLine("Port opened successfully.");
                }

                // Timeout handling for reading data
                int retries = 5;
                string data = null;
                while (_serialPort.BytesToRead == 0 && retries > 0)
                {
                    await Task.Delay(100);  // Wait a short while for data to arrive
                    retries--;
                }

                // Check if data is available to read
                if (_serialPort.BytesToRead > 0)
                {
                    try
                    {
                        // Attempt to read the line
                        data = await Task.Run(() =>
                        {
                            try
                            {
                                if (global_cb_carton == true)
                                {
                                    return _serialPort.ReadExisting();
                                }
                                else
                                {
                                    return _serialPort.ReadLine();
                                }
                            }
                            catch (TimeoutException ex)
                            {
                                Debug.WriteLine($"Timeout while reading from the port: {ex.Message}");
                                return null;
                            }
                        });

                        if (!string.IsNullOrEmpty(data))
                        {

                            Debug.WriteLine($"Data received: {data}");
                            UpdateUI(data, isDataReceived: true);
                            Console.WriteLine($"Data received: {data}");

                        }
                        else
                        {
                            Debug.WriteLine("No data received.");
                            UpdateUI("No data received from the device.");
                        }
                    }
                    catch (Exception innerEx)
                    {
                        Debug.WriteLine($"Error reading data from port: {innerEx.Message}");
                    }
                }
                else
                {
                    Debug.WriteLine("Weighing machine not connected.");
                    UpdateUI("Weighing machine not connected.");
                }
            }
            catch (UnauthorizedAccessException ex)
            {
                Debug.WriteLine($"Error: COM port access denied: {ex.Message}");
            }
            catch (IOException ex)
            {
                Debug.WriteLine($"I/O error: {ex.Message}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Unexpected error: {ex.Message}");
            }
            finally
            {
                // Ensure the port is properly closed and resources are released
                if (_serialPort?.IsOpen == true)
                {
                    _serialPort.Close();
                    Debug.WriteLine("Port closed.");
                }

                _serialPort?.Dispose();
                _serialPort = null;
            }

            // Run the update process in another thread
           // _ = Task.Delay(500).ContinueWith(async _ => await RunUpdateProcessAsync());

        }

        private async Task RunUpdateProcessAsync()
        {
            await Updater.CheckVersionAsync();
        }


        public void StopReading()
        {
            _timer?.Change(Timeout.Infinite, 0);  // Stop the timer when needed
            _timer?.Dispose();
        }
        private bool _isReading = false;

        public void StartReading()
        {

            _timer = new System.Threading.Timer(async _ =>
            {
                if (_isReading)
                    return;

                _isReading = true;
                try
                {
                    await ReadFromSerialPort();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"Error in reading: {ex.Message}");
                    UpdateUI("Error encountered during reading.");
                }
                finally
                {
                    _isReading = false; // Reset the flag after reading completes
                }
            }, null, TimeSpan.Zero, TimeSpan.FromSeconds(1));
        }
        private string GetCompatiblePort(string[] availablePorts)
        {
            string compatiblePort = null;

            foreach (string portName in availablePorts)
            {
                string portDescription = GetPortDescription(portName);
                Debug.WriteLine($"Port: {portName}, Description: {portDescription}");

                // Prioritize Prolific and CH340 first
                if (portDescription.Contains("Prolific USB-to-Serial Comm Port") || portDescription.Contains("USB-SERIAL CH340"))
                {
                    compatiblePort = portName;
                    break;
                }
            }

            // If still no compatible port, check for COM1 as a fallback
            if (compatiblePort == null)
            {
                foreach (string portName in availablePorts)
                {
                    string portDescription = GetPortDescription(portName);
                    if (portDescription.Contains("Communications Port (COM1)"))
                    {
                        compatiblePort = portName;
                        break;
                    }
                }
            }

            return compatiblePort;
        }

        private void UpdateUI(string message, bool isDataReceived = false)
        {
            // Ensure the handle is created before attempting to update the UI
            if (!IsHandleCreated)
                return;

            // Use Invoke to ensure thread safety when updating UI elements
            Invoke((Action)(() =>
            {
                if (string.IsNullOrEmpty(message))
                {
                    // Handle unexpected empty message
                    pb_red.Visible = true;  // Show red indicator for disconnection
                    pb_blue.Visible = false; // Hide blue indicator
                    txt_weight.Text = "0";   // Reset weight display
                    lbl_hold_weight.Text = "0"; // Reset hold weight display
                    PreviousWeight = 0;       // Reset previous weight tracker


                }
                else
                {
                    // Check if it's a data message
                    if (isDataReceived)
                    {
                        pb_red.Visible = false;  // Hide red indicator
                        pb_blue.Visible = true;  // Show blue indicator for data received

                        // For new weighing scale
                        if (global_cb_carton == true)
                        {
                            string[] segments = message.Split('=');

                            foreach (string segment in segments)
                            {
                                // Trim unwanted characters
                                string numericPart = segment.Trim().TrimEnd('.');

                                // Try parsing as a double
                                if (!string.IsNullOrEmpty(numericPart) && double.TryParse(numericPart,
                                    NumberStyles.Any, CultureInfo.InvariantCulture, out double weight))
                                {
                                    //MessageBox.Show(weight.ToString("0.000"));

                                    // Example dynamic rule for SITE-05 (reverse the number as string)
                                    string reversedString = new string(numericPart.Reverse().ToArray());

                                    if (double.TryParse(reversedString, NumberStyles.Any, CultureInfo.InvariantCulture, out double reversedWeight))
                                    {
                                        weight = reversedWeight; // Use reversed value dynamically

                                        if (weight != PreviousWeight)
                                        {
                                            PreviousWeight = weight; // Update the previous weight
                                            txt_weight.Text = weight.ToString("0.000"); // Display the current weight
                                        }

                                        // Update hold weight if above threshold
                                        if (weight > 0.020)
                                        {
                                            lbl_hold_weight.Text = weight.ToString("0.000"); // Display the hold weight
                                        }

                                        message = "Machine connected";
                                        lbl_msg.ForeColor = Color.Green;
                                        lbl_msg.Text = message;
                                    }
                                }
                            }
                        }
                        else
                        {
                            pb_red.Visible = false;  // Hide red indicator
                            pb_blue.Visible = true;   // Show blue indicator for data received

                            // Match weight pattern in message (e.g., "123.45 kg")
                            Match match = Regex.Match(message, @"(\d+(\.\d+)?) kg");

                            if (match.Success && double.TryParse(match.Groups[1].Value, out double weight))
                            {
                                // Only update weight display if it has changed
                                if (weight != PreviousWeight)
                                {
                                    PreviousWeight = weight; // Update the previous weight
                                    txt_weight.Text = weight.ToString("0.000"); // Display the current weight
                                }

                                // Update hold weight if above threshold
                                if (weight > 0.020)
                                {
                                    lbl_hold_weight.Text = weight.ToString("0.000"); // Display the hold weight
                                }

                                message = "Machine connected";
                                lbl_msg.ForeColor = Color.Green;
                                lbl_msg.Text = message;

                            }
                        }
                    }
                    else
                    {
                        // If message is not data, handle it as a status update
                        if (message.Contains("USB cable not connected with PC") || message.Contains("Weighing machine not connected."))
                        {

                            lbl_msg.ForeColor = Color.Red;
                            pb_red.Visible = true;  // Show red indicator for no data connection
                            pb_blue.Visible = false; // Hide blue indicator
                            txt_weight.Text = "0";   // Reset weight display
                            lbl_hold_weight.Text = "0"; // Reset hold weight display
                            PreviousWeight = 0;       // Reset previous weight tracker

                            lbl_msg.Text = message;
                        }
                        else
                        {
                            // Log or display other messages accordingly
                            Console.WriteLine(message); // You can also log it in a textbox or label if needed
                        }
                    }
                }
            }));

        }

        private void HandleException(Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");

            if (IsHandleCreated)
            {
                Invoke((Action)(() =>
                {
                    pb_blue.Visible = false;
                    pb_red.Visible = true;
                    txt_weight.Text = "0";

                    btn_update.Enabled = lbl_fnsku.Text.Length > 0;
                    btn_update.BackColor = btn_update.Enabled ? System.Drawing.Color.FromArgb(0, 64, 64) : System.Drawing.SystemColors.Control;
                }));
            }
        }

        public void btn_post_data_Click(object sender, EventArgs e)
        {
            // Disable the button to prevent multiple clicks
            btn_post_data.Enabled = false;
            try
            {
                if (global_cb_carton == true)
                {
                    liteDbClass.postDataAsyncCarton();
                    count = 0;
                    lbl_boxCount.Text = "Carton count : " + count;
                }
                else
                {

                    liteDbClass.postDataAsync();
                    liteDbClass.postDataAsyncCarton();
                    count = 0;
                    lbl_counter.Text = "Item count : " + count;
                    boxcount = 0;
                    lbl_boxCount.Text = "Box count : " + boxcount.ToString();

                }
            }
            finally
            {
                // Enable the button after the operation completes
                //btn_post_data.Enabled = true;
            }
        }

        private void btn_delete_Click(object sender, EventArgs e)
        {
            if (fnsku != "")
            {
                liteDbClass.DeleteRow(fnsku, SKULog.MARKET_PLACE);
                MessageBox.Show("Row deleted");
                dataGridView.DataSource = liteDbClass.showData();
                lbl_counter.Text = "Item count : 0";
                lbl_boxCount.Text = "Box count : 0";
                lbl_item_box.Text = "Item per box : 0";

            }
            else
            {
                MessageBox.Show("First select row");
            }

        }

        private void btn_reset_port_Click(object sender, EventArgs e)
        {
            // Get the name of the first available COM port
            string portName = GetCompatiblePort(SerialPortStream.GetPortNames());

            if (string.IsNullOrEmpty(portName))
            {
                MessageBox.Show("No COM ports found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Try to get the Device Instance ID for the port
            //string deviceInstanceId = GetDeviceInstanceIdFromCOMPort(portName);
            //if (!string.IsNullOrEmpty(deviceInstanceId))
            //{
            ResetPort(portName);
            // }
            // else
            // {
            //  MessageBox.Show($"Device ID for {portName} not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //}

        }


        //private string GetDeviceInstanceIdFromCOMPort(string portName)
        //{
        //    try
        //    {
        //        // WMI query to get the device instance ID based on the COM port
        //        string query = $"SELECT * FROM Win32_SerialPort WHERE DeviceID LIKE '%{portName}%'";

        //        // Create a ManagementObjectSearcher to execute the query
        //        ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
        //        foreach (ManagementObject device in searcher.Get())
        //        {
        //            // Return the device instance ID
        //            return device["PNPDeviceID"]?.ToString();
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Debug.WriteLine($"Error retrieving Device Instance ID: {ex.Message}");
        //    }
        //    return null;
        //}

        // Method to set the device state (enable/disable) using WMI


        // Method to reset the port by disabling and enabling it
        public static void ResetPort(string portName)
        {
            string deviceInstanceId = GetDeviceInstanceIdFromCOMPort(portName);

            if (!string.IsNullOrEmpty(deviceInstanceId))
            {
                DisableDevice(deviceInstanceId);
                Thread.Sleep(3000); // Wait 3 seconds before enabling the device
                EnableDevice(deviceInstanceId);
            }
            else
            {
                Console.WriteLine("No device found for the given COM port.");
            }
        }
        // Methods to enable or disable the device
        public static void EnableDevice(string deviceInstanceId)
        {
            IntPtr deviceInfoSet = SetupDiGetClassDevs(IntPtr.Zero, deviceInstanceId, IntPtr.Zero, DIGCF_PRESENT);
            if (deviceInfoSet == IntPtr.Zero)
            {
                Console.WriteLine("Error getting device info set.");
                return;
            }

            SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
            deviceInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA));

            uint index = 0;
            while (SetupDiEnumDeviceInfo(deviceInfoSet, index, ref deviceInfoData))
            {
                Console.WriteLine($"Found device: {deviceInfoData.DevInst}");
                SetupDiCallClassInstaller(DIF_ENABLE, deviceInfoSet, ref deviceInfoData);
                Console.WriteLine("Device enabled.");
                break; // Stop after enabling the first matching device
            }
            Console.WriteLine("No matching device found.");
        }

        // Disable a device by Instance ID

        public static void DisableDevice(string deviceInstanceId)
        {


            IntPtr deviceInfoSet = SetupDiGetClassDevs(IntPtr.Zero, deviceInstanceId, IntPtr.Zero, DIGCF_PRESENT);
            if (deviceInfoSet == IntPtr.Zero)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(), "Failed to get device info set");
            }

            try
            {
                SP_DEVINFO_DATA deviceInfoData = new SP_DEVINFO_DATA();
                deviceInfoData.cbSize = (uint)Marshal.SizeOf(typeof(SP_DEVINFO_DATA));

                for (uint index = 0; SetupDiEnumDeviceInfo(deviceInfoSet, index, ref deviceInfoData); index++)
                {
                    Console.WriteLine($"Found device: {deviceInfoData.DevInst}");
                    if (!SetupDiCallClassInstaller(DIF_DISABLE, deviceInfoSet, ref deviceInfoData))
                    {
                        Console.WriteLine("Device disabled.");
                        break; // Stop after disabling the first matching device
                    }
                    else
                    {
                        Console.WriteLine("Failed to disable device.");
                    }
                }
            }
            finally
            {
                SetupDiDestroyDeviceInfoList(deviceInfoSet);
            }
        }
        public static string GetDeviceInstanceIdFromCOMPort(string portName)
        {
            try
            {
                // PowerShell query to get device instance ID based on the COM port
                string query = $"Get-PnpDevice | Where-Object {{ $_.Name -like '*{portName}*' }} | Select-Object -ExpandProperty InstanceId";

                // Capture the output of the command
                string result = ExecutePowerShellCommand(query);

                // Debugging: log the result to ensure correct InstanceId is returned
                Debug.WriteLine($"PowerShell Output for InstanceId: {result}");

                // Return the result, null if empty
                return string.IsNullOrEmpty(result) ? null : result;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error retrieving Device Instance ID: {ex.Message}");
                return null;
            }
        }

        public static string ExecutePowerShellCommand(string command)
        {
            try
            {
                // Run the PowerShell script and capture output
                var startInfo = new ProcessStartInfo
                {
                    FileName = "powershell.exe",
                    Arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{command}\"",
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                };

                using (var process = Process.Start(startInfo))
                using (var reader = process.StandardOutput)
                {
                    return reader.ReadToEnd().Trim(); // Return the output of the command
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"Error executing PowerShell command: {ex.Message}");
                return null;
            }
        }

        private void btn_refresh_Click(object sender, EventArgs e)
        {
            //if (dataGridView.SelectedRows.Count == 0)
            //{
            //    MessageBox.Show("Please select a row");
            //    return;
            //}

            var selectedRow = dataGridView.Rows[dataGridView.SelectedCells[0].RowIndex];
            var marketPlace = selectedRow.Cells["MARKET_PLACE"].Value?.ToString();

            if (string.IsNullOrWhiteSpace(marketPlace))
            {
                MessageBox.Show("Please select market place first.");
                return;
            }

            SKULog.MARKET_PLACE = marketPlace;
            lbl_market_place.Text = marketPlace;

            txt_sku.Text = SKULog.SKU;

            var cells = selectedRow.Cells;
            SKULog.FNSKU = cells["FNSKU"].Value?.ToString();
            SKULog.ModelNo = cells["ModelNo"].Value?.ToString();
            SKULog.NetWeightKg = Convert.ToDouble(cells["NetWeightKg"].Value?.ToString());
            SKULog.Size = cells["Size"].Value?.ToString();
            SKULog.Colour = cells["Colour"].Value?.ToString();
            SKULog.Title = cells["Title"].Value?.ToString();

            if (Int16.TryParse(cells["itemsPerBox"].Value?.ToString(), out Int16 itemPerBox))
            {
                SKULog.ItemsPerBox = itemPerBox;
                lbl_item_box.Text = $"Item per box: {itemPerBox}";

                var itemCount = liteDbClass.FillCounts(SKULog.FNSKU, marketPlace);
                lbl_counter.Text = $"Item count : {itemCount}";

                if (Int16.TryParse(itemCount.ToString(), out Int16 countt))
                {
                    var boxCount = countt / itemPerBox;
                    lbl_boxCount.Text = $"Box count : {boxCount}";
                    count = countt;
                    boxcount = boxCount;
                }
            }
        }

        private void btn_save_tol_Click(object sender, EventArgs e)
        {
            var selectedRow = dataGridView.Rows[dataGridView.SelectedCells[0].RowIndex];
            if(fnsku == "")
            {
                MessageBox.Show("Please select row");
                return;
            }
          
            if (txt_weight_tol.Text.Length > 0 && txt_weight_tol.Text != 0.ToString())
            {

                SKULog.FNSKU = fnsku;               
                SKULog.MARKET_PLACE = selectedRow.Cells["MARKET_PLACE"].Value?.ToString();
                double weightTolerance = Convert.ToDouble(txt_weight_tol.Text);

                bool result = liteDbClass.InsertOrUpdateWeightTolerance(fnsku, SKULog.MARKET_PLACE, weightTolerance, userTextBox.Text);

                if (result == true)
                {
                    MessageBox.Show("Weight Tolerance saved successfully.");
                }
                else
                {
                    MessageBox.Show("Weight Tolerance not saved.");
                }

            }
            else
            {
                MessageBox.Show("Please enter weight tolerance.");
            }
            txt_weight_tol.Text = "";
        }

        private void txt_weight_tol_KeyPress(object sender, KeyPressEventArgs e)
        {
            TextBox txt = sender as TextBox;

            // Allow control keys (like backspace), digits, and one dot (.)
            if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
            {
                e.Handled = true;
            }

            // Only allow one dot
            if (e.KeyChar == '.' && txt.Text.Contains("."))
            {
                e.Handled = true;
            }
        }
        private void StartBackgroundTask()
        {
            backgroundTimer = new System.Timers.Timer();
            backgroundTimer.Interval = TimeSpan.FromMinutes(30).TotalMilliseconds; // every 30 mins
            backgroundTimer.Elapsed += (sender, args) => dbHelper.UpdateClientActivity((userTextBox.Text));
            backgroundTimer.AutoReset = true;
            backgroundTimer.Start();
        }
    }
}

