using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using UWS;
using static UWS.BusinessLayer;

namespace WindowsFormsApp1
{
    public partial class WeighingForm : Form
    {
        DataAccessObject dataAccessObject = new DataAccessObject();
        string portname = "COM1";
        int baudRate = 9600;
        static string fms_no;
        ReportDocument rprt = new ReportDocument();
        DataSet1 ds = new DataSet1();
        VehicleRequestApiResponse apiResponse = new VehicleRequestApiResponse();
        static Int32 _userId;
        string dateTime;
        string itemText;
        private HttpClient _httpClient;
        private Label siteTextBox;
        private BackgroundWorker bgWorker;
        private System.Windows.Forms.Timer scanTimer;
        public WeighingForm(Int32 userId)
        {
            InitializeComponent();
            siteTextBox = txt_site; // Assign the existing TextBox control to the class-level variable
            checkSite();  // Call the method to read or create the file and update the TextBox
            _httpClient = new HttpClient();
            this.MaximizeBox = false;
            _userId = userId;
            ReadConfigFile();

        }
        public void checkSite()
        {
            // Define the root directory and the file name
            string rootPath = AppDomain.CurrentDomain.BaseDirectory;  // Root path of the application
            string fileName = "site_id.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 siteId = File.ReadAllText(filePath);

                // Display the site ID in the TextBox
                siteTextBox.Text = siteId;
            }
            else
            {
                // Create the file and write "Site ID not available" if it doesn't exist
                string defaultText = "SITE ID NOT FOUND";
                File.WriteAllText(filePath, defaultText);

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

        public void ForSite05(string data)
        {
            // Split the data into segments based on the "=" delimiter
            string[] segments = data.Split('=');

            foreach (string segment in segments)
            {
                // Trim any trailing or leading '.' and whitespace
                string numericPart = segment.Trim('.').Trim();

                // Check if the segment contains a valid numeric part
                if (!string.IsNullOrEmpty(numericPart) && long.TryParse(numericPart, out long numericValue))
                {
                    // Dynamically process the numeric value based on site or conditions
                    double processedWeight = numericValue; // Default as raw numeric value


                    // Example dynamic rule for SITE-05 (reverse the number)
                    string reversedString = new string(numericPart.Reverse().ToArray());
                    if (long.TryParse(reversedString, out long reversedValue))
                    {
                        processedWeight = reversedValue; // Use reversed value dynamically
                    }


                    // Display the dynamically processed weight
                    Console.WriteLine($"Processed Weight: {processedWeight}"); // Debug output
                    UpdateUI(Convert.ToInt32(processedWeight), "MACHINE CONNECTED", Color.Green);
                }
                else
                {
                    // Handle invalid or non-numeric data
                    UpdateUI(0, "INVALID DATA", Color.Red);
                }
            }
        }
        public void ForSite02(string data)
        {
            // Check if data length is sufficient
            if (data.Length >= 10)
            {
                string numericPart = data.Substring(1, 7);
                if (int.TryParse(numericPart, out int numericValue))
                {
                    UpdateUI(numericValue, "MACHINE CONNECTED", Color.Green);
                }
                else
                {
                    UpdateUI(0, "MACHINE CONNECTED", Color.Green); // Show "0" for invalid data
                }
            }
        }

        public async Task GetPortDataAsync()
        {
            await Task.Run(() =>
            {
                using (SerialPort serialPort = new SerialPort(portname, baudRate, Parity.None, 8, StopBits.One))
                {
                    serialPort.Handshake = Handshake.XOnXOff;
                    serialPort.ReadTimeout = 5000;

                    bool isConnected = false; // Track connection state

                    try
                    {

                        serialPort.Open();
                        isConnected = true; // Assume connected after opening

                        while (true)
                        {
                            try
                            {
                                // Check if data is available
                                if (serialPort.BytesToRead > 0)
                                {
                                    string data = serialPort.ReadExisting();
                                    Console.WriteLine($"Data received: {data}"); // Debug output


                                    if (txt_site.Text == "SITE-05")
                                    {

                                        ForSite05(data);
                                    }
                                    else
                                    {

                                        //ForSite02(data);

                                        if (txt_site.Text.Contains("A"))
                                        {
                                            ForSite05(data);
                                        }
                                        else
                                        {
                                            ForSite02(data);
                                        }
                                    }

                                }
                                else
                                {
                                    // No data received; machine may not be connected
                                    UpdateUI(0, "MACHINE NOT CONNECTED", Color.Red); // Show not connected status
                                    isConnected = false; // Set to false if no data is received
                                }

                                Thread.Sleep(500); // Delay to avoid overwhelming the system
                            }
                            catch (TimeoutException)
                            {
                                // Ignore timeouts, but assume not connected
                                UpdateUI(0, "MACHINE NOT CONNECTED", Color.Red);
                                isConnected = false; // Update connection state
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //// If an error occurs while trying to connect, we assume disconnection
                        // UpdateUI(0, "MACHINE NOT CONNECTED", Color.Red); // Show not connected status
                        serialPort.Close();
                    }
                    finally
                    {
                        if (serialPort.IsOpen)
                        {
                            serialPort.Close(); // Ensure the port is closed
                        }
                    }
                }
            });
        }

        private void UpdateUITest(string weightValue, string statusMessage, Color statusColor)
        {
            lbl_weight.BeginInvoke((MethodInvoker)delegate
            {
                lbl_weight.Text = weightValue.ToString();
                lbl_weight.ForeColor = Color.White;
                lbl_status.Text = statusMessage;
                lbl_status.ForeColor = statusColor;
                lbl_status.Visible = true;
            });
        }

        private void UpdateUI(int weightValue, string statusMessage, Color statusColor)
        {
            lbl_weight.BeginInvoke((MethodInvoker)delegate
            {
                lbl_weight.Text = weightValue.ToString();
                lbl_weight.ForeColor = Color.White;
                lbl_status.Text = statusMessage;
                lbl_status.ForeColor = statusColor;
                lbl_status.Visible = true;
            });
        }




        public void ReadConfigFile()
        {
            try
            {

                string rootPath = AppDomain.CurrentDomain.BaseDirectory;  // Root path of the application
                string fileName = "config.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 all lines from the file
                    string[] lines = File.ReadAllLines(filePath);

                    // Process each line
                    foreach (string line in lines)
                    {
                        // Split the line into key and value
                        string[] parts = line.Split('=');

                        // Check if there are two parts
                        if (parts.Length == 2)
                        {
                            // Trim spaces and assign values
                            string key = parts[0].Trim();
                            string value = parts[1].Trim();

                            // Check key and assign values accordingly
                            if (key.Equals("PortName", StringComparison.OrdinalIgnoreCase))
                            {
                                portname = value;
                                lbl_com.Text = portname;
                            }
                            else if (key.Equals("BaudRate", StringComparison.OrdinalIgnoreCase))
                            {
                                // Try parsing the value as an integer
                                if (int.TryParse(value, out int rate))
                                {
                                    baudRate = rate;
                                }
                                else
                                {
                                    Console.WriteLine($"Invalid Baud Rate: {value}");
                                }
                            }
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Config file does not exist.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error reading config file: {ex.Message}");
            }
        }
        private void WeighingForm_Load(object sender, EventArgs e)
        {

            // Start the timer
            timer1.Interval = 1000;
            timer1.Start();

            // Initialize the BackgroundWorker
            bgWorker = new BackgroundWorker();
            bgWorker.DoWork += BgWorker_DoWork;


            // Start the background work
            bgWorker.RunWorkerAsync();

        }
        private async void getTrolleyAnddl()
        {
            try
            {
                // Call the GetTrolleyApi method and await the response
                string response = await dataAccessObject.GetTrolleyApi();

                if (!string.IsNullOrEmpty(response) && !response.Contains("Error: NotFound"))
                {
                    // Deserialize the response into a list of items
                    var items = JsonConvert.DeserializeObject<List<dynamic>>(response);

                    // Add "SELECT" as the first item in the list
                    var selectItem = new { id = 0, code = "SELECT" };
                    items.Insert(0, selectItem); // Add at the 0th index of the existing items list

                    // Invoke UI updates on the main thread
                    Invoke((Action)(() =>
                    {
                        // Bind the ComboBox to the 'code' (displayed) and 'id' (value) properties
                        cb_trolley.DataSource = items
                            .Select(item => new { id = (int)item.id, code = (string)item.code }) // Ensure the mapping to `id` and `code`
                            .ToList();

                        cb_trolley.DisplayMember = "code";  // Display the 'code' value
                        cb_trolley.ValueMember = "id";      // Use the 'id' as the value

                        // Select the "SELECT" item (index 0)
                        cb_trolley.SelectedIndex = 0;
                        SetupSearchableComboBox(cb_trolley);
                    }));
                }
                else
                {
                    // Show message on the UI thread
                    Invoke((Action)(() =>
                    {
                        MessageBox.Show("Received empty trolley from the server.");
                    }));
                }

                // Load data for other ComboBoxes
                DataTable productData = dataAccessObject.GetWeightScaleData("weight_scale_product");
                DataTable transporterData = dataAccessObject.GetWeightScaleData("weight_scale_transporter");
                DataTable partyData = dataAccessObject.GetWeightScaleData("weight_scale_party");

                // Invoke UI updates for other ComboBoxes
                Invoke((Action)(() =>
                {
                    // Bind product data to comboBoxProduct
                    cb_item.DataSource = productData;
                    cb_item.DisplayMember = "product_name";  // Replace with actual column name for display
                    cb_item.ValueMember = "product_code";    // Replace with actual column name for value
                    SetupSearchableComboBox(cb_item);

                    // Bind transporter data to comboBoxTransporter
                    cb_transporter.DataSource = transporterData;
                    cb_transporter.DisplayMember = "transporter_name";  // Replace with actual column name for display
                    cb_transporter.ValueMember = "transporter_code";    // Replace with actual column name for value
                    SetupSearchableComboBox(cb_transporter);

                    // Bind party data to comboBoxParty
                    cb_location.DataSource = partyData;
                    cb_location.DisplayMember = "party_name";  // Replace with actual column name for display
                    cb_location.ValueMember = "party_code";    // Replace with actual column name for value
                    SetupSearchableComboBox(cb_location);
                    txt_vehicle_no.Enabled = true;
                }));
            }
            catch (JsonReaderException jsonEx)
            {
                MessageBox.Show($"JSON Parsing Error: {jsonEx.Message}");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error: {ex.Message}");
            }
        }
        private void BgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            // This is running on a background thread
            checkSite();
            getTrolleyAnddl();
            chk_box_CheckedChanged(null, null);
        }
        private void SetupSearchableComboBox(ComboBox comboBox)
        {
            // Enable auto-complete for the ComboBox
            comboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
            comboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
        }


        private void cb_item_Leave(object sender, EventArgs e)
        {
            string enteredValue = cb_item.Text.ToUpper();
            bool valueExists = false;

            // Check if the entered value exists in the ComboBox
            foreach (DataRowView item in cb_item.Items)
            {
                if (item["product_name"].ToString().ToUpper() == enteredValue) // Use the actual column for display
                {
                    valueExists = true;
                    break;
                }
            }

            // If the value does not exist, prompt to add it
            if (!valueExists)
            {
                var result = MessageBox.Show($"The value '{enteredValue}' is not in the list. Would you like to add it?",
                                             "Add New Value",
                                             MessageBoxButtons.YesNo,
                                             MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    dataAccessObject.AddValueToDatabase(enteredValue, "weight_scale_product", "product_name");
                    DataTable productData = dataAccessObject.GetWeightScaleData("weight_scale_product");

                    // Invoke UI updates for other ComboBoxes
                    Invoke((Action)(() =>
                    {

                        // Bind party data to comboBoxParty
                        cb_item.DataSource = productData;
                        cb_item.DisplayMember = "product_name";
                        cb_item.ValueMember = "product_code";
                        SetupSearchableComboBox(cb_item);

                    }));
                }
            }
        }


        private void timer1_Tick(object sender, EventArgs e)
        {
            lbl_date_time.Text = System.DateTime.Now.ToString();
            _ = GetPortDataAsync();
        }

        private void pb_get_Click(object sender, EventArgs e)
        {

            if (cb_1st_weight.Checked)
            {
                fillValues('1');
            }

            else if (cb_2nd_weight.Checked)
            {
                fillValues('2');
            }
            else
            {
                MessageBox.Show("Please select weight");
            }

        }



        public void fillValues(char value)
        {
            if (value == '1')
            {

                txt_1st_weight.Text = lbl_weight.Text.ToString();
                txt_1st_date.Text = DateTime.Now.ToShortDateString();
                txt_1st_time.Text = DateTime.Now.ToShortTimeString();
                dateTime = DateTime.Now.ToString();


                txt_2nd_weight.Text = "";
                txt_2nd_date.Text = "";
                txt_2nd_time.Text = "";


            }
            else
            {

                txt_2nd_weight.Text = lbl_weight.Text.ToString();
                txt_2nd_date.Text = DateTime.Now.ToShortDateString();
                txt_2nd_time.Text = DateTime.Now.ToShortTimeString();
                dateTime = DateTime.Now.ToString();

                txt_1st_weight.Text = "";
                txt_1st_date.Text = "";
                txt_1st_time.Text = "";

            }

        }

        private void cb_1st_weight_CheckedChanged(object sender, EventArgs e)
        {
            cb_2nd_weight.Checked = false;
        }

        private void cb_2nd_weight_CheckedChanged(object sender, EventArgs e)
        {
            cb_1st_weight.Checked = false;
        }

        private async void btn_save_ClickAsync(object sender, EventArgs e)
        {
            this.Enabled = false;

            string weightText, type, fmsID, container_no;

            container_no = txt_container_no.Text;

            if (cb_1st_weight.Checked)
            {
                weightText = txt_1st_weight.Text;

                type = "1";
            }
            else
            {
                weightText = txt_2nd_weight.Text;

                type = "2";
            }
            if (string.IsNullOrEmpty(weightText))
            {
                this.Enabled = true;
                CustomMessageBox.ShowError("Please provide the weight.");
                return;
            }

            // with FMS

            if (chk_box.Checked == true)
            {

                fmsID = txt_fms_no.Text.ToString();


                if (string.IsNullOrEmpty(dateTime))
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError("Please provide the date and time.");
                    return;
                }

                if (string.IsNullOrEmpty(fms_no))
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError("Please provide the FMS number.");
                    return;
                }


                string result = await postData(fmsID, weightText, dateTime, type, "", _userId, container_no);

                MessageBox.Show(result);


            }
            // without FMS
            else
            {
                if (txt_vehicle_no.Text.Length == 0)
                {
                    this.Enabled = true;

                    CustomMessageBox.ShowError("Please provide vehicle no.");
                    return;

                }

                if (cb_item.SelectedIndex == 0)
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError("Please provide item.");
                    return;
                }
                if (cb_transporter.SelectedIndex == 0)
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError("Please provide transporter.");
                    return;
                }

                if (cb_location.SelectedIndex == 0)
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError("Please provide location.");
                    return;
                }

                //if ((txt_2nd_weight.Text != "0" || txt_2nd_weight.Text != "") && (txt_1st_weight.Text != "0" || txt_1st_weight.Text != ""))
                //{
                //    MessageBox.Show("Error,Contact to technology");
                //    return;
                //}
                string result = await postDataWithoutFMS(txt_vehicle_no.Text.ToUpper(), weightText, dateTime, type, "", _userId, cb_item.SelectedValue.ToString(), cb_transporter.SelectedValue.ToString(), cb_location.SelectedValue.ToString(), container_no);

                if (result.Contains("Error"))
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowError(result);
                }
                else
                {
                    this.Enabled = true;
                    CustomMessageBox.ShowSuccess(result);
                }
            }
            resetFields(0);
        }

        public async Task<string> postData(string fmsID, string weightText, string dateText, string type, string comment, Int32 userid, string container_no)
        {
            try
            {
                // Assuming dataAccessObject is an instance of your data access class
                string result = await dataAccessObject.postDataAsync(fmsID, Convert.ToInt32(weightText), dateText, type, comment, userid, siteTextBox.Text, container_no);
                this.Enabled = true;
                return result;
            }
            catch (Exception ex)
            {
                this.Enabled = true;
                // Log the exception or handle it as needed             
                return "false";
            }
        }


        public async Task<string> postDataWithoutFMS(string vehicleNO, string weightText, string dateText, string type, string comment, Int32 userid, string item, string transporter, string location, string container_no)
        {
            try
            {
                // Assuming dataAccessObject is an instance of your data access class
                string result = await dataAccessObject.postDataAsyncWithoutFMS(vehicleNO, Convert.ToInt32(weightText), dateText, type, comment, userid, siteTextBox.Text, item, transporter, location, container_no);
                this.Enabled = true;

                return result;
            }
            catch (Exception ex)
            {
                this.Enabled = true;
                // Log the exception or handle it as needed             
                return "Error";
            }
        }




        public async Task getData(string fmsID)
        {
            try
            {
                apiResponse = await dataAccessObject.GetRegNo(fmsID);

                if (apiResponse.VehicleRequest != null)
                {
                    // Access apiResponse properties here

                    if (apiResponse.VehicleRequest.Id == 0)
                    {
                        CustomMessageBox.ShowError("Invalid response");
                        txt_vehicle_no.BackColor = Color.PaleVioletRed;
                    }
                    else
                    {
                        txt_vehicle_no.Text = apiResponse.VehicleRequest.FmsVehicle.RegistrationNumber.ToString();
                        txt_vehicle_no.BackColor = Color.LightGreen;
                    }
                }
                else
                {
                    CustomMessageBox.ShowError("Invalid data");
                }
            }
            catch (Exception ex)
            {
                CustomMessageBox.ShowError("No response");
            }
        }



        private void btn_print_Click(object sender, EventArgs e)
        {
            if (chk_box.Checked == false)
            {
                if (txt_vehicle_no.Text.Length > 0)
                {

                    if (apiResponse.LoadingVehicleWeightInfo != null)
                    {
                        ShowWeightReport();
                    }
                    else
                    {
                        CustomMessageBox.ShowError("Record not exists - " + txt_vehicle_no.Text);
                    }
                }
                else
                {
                    CustomMessageBox.ShowError("Please provide vehicle #");
                }
            }
            else
            {

                if (txt_fms_no.Text.Length > 0)
                {
                    if (txt_vehicle_no.Text.Length > 0)
                    {

                        if (apiResponse.LoadingVehicleWeightInfo != null)
                        {
                            ShowWeightReport();
                        }
                        else
                        {
                            CustomMessageBox.ShowError("Record not exists - " + txt_fms_no.Text);
                        }
                    }
                    else
                    {
                        CustomMessageBox.ShowError("Please provide vehicle #");
                    }
                }
                else
                {
                    CustomMessageBox.ShowError("Please provide FMS #");
                }
            }

        }

        public void ShowWeightReport()
        {
            DataSet1.DailyReportDataTable dt = new DataSet1.DailyReportDataTable();
            ds.DailyReport.Clear();
            dt = ds.DailyReport;

            // Add a new row to the DataTable
            DataRow dr = dt.NewRow();
            if (apiResponse.LoadingVehicleWeightInfo?.DeadWeight != null)
                dr[0] = apiResponse.LoadingVehicleWeightInfo.DeadWeight;

            if (apiResponse.LoadingVehicleWeightInfo?.FinalWeight != null)
                dr[1] = apiResponse.LoadingVehicleWeightInfo.FinalWeight;




            if (!string.IsNullOrEmpty(apiResponse.VehicleRequest?.FmsVehicle?.RegistrationNumber))
                dr[2] = apiResponse.VehicleRequest.FmsVehicle.RegistrationNumber;

            if (apiResponse.LoadingVehicleWeightInfo?.DeadWeightDateTime != null)
                dr[3] = apiResponse.LoadingVehicleWeightInfo.DeadWeightDateTime.Value.ToShortTimeString();


            if (apiResponse.LoadingVehicleWeightInfo?.FinalWeightDateTime != null)
                dr[4] = apiResponse.LoadingVehicleWeightInfo.FinalWeightDateTime.Value.ToShortTimeString();

            if (apiResponse.LoadingVehicleWeightInfo?.DeadWeightDateTime != null)
                dr[5] = apiResponse.LoadingVehicleWeightInfo.DeadWeightDateTime.Value.ToShortDateString();

            if (apiResponse.LoadingVehicleWeightInfo?.FinalWeightDateTime != null)
                dr[6] = apiResponse.LoadingVehicleWeightInfo.FinalWeightDateTime.Value.ToShortDateString();


            if (!string.IsNullOrEmpty(apiResponse.LoadingVehicleWeightInfo?.Comment))
                dr[7] = apiResponse.LoadingVehicleWeightInfo.Comment;

            if (chk_box.Checked)
            {
                if (!string.IsNullOrEmpty(apiResponse.VehicleRequest?.FmsVehicle?.RegistrationNumber))
                    dr[8] = apiResponse.VehicleRequest.FmsVehicle.RegistrationNumber;
            }
            else
            {
                if (!string.IsNullOrEmpty(apiResponse.LoadingVehicleWeightInfo?.VehicleNo))
                    dr[8] = apiResponse.LoadingVehicleWeightInfo.VehicleNo.ToUpper();
                dr["ProductName"] = cb_item.Text;
                dr["PartyName"] = cb_location.Text;
                dr["TransporterName"] = cb_transporter.Text;

                if (!string.IsNullOrEmpty(apiResponse.LoadingVehicleWeightInfo?.ContainerNo))
                {
                    dr["ContainerNo"] = apiResponse.LoadingVehicleWeightInfo?.ContainerNo;
                }

            }
            if (!string.IsNullOrEmpty(apiResponse.LoadingVehicleWeightInfo?.VehicleRequestCode))
                dr[9] = apiResponse.LoadingVehicleWeightInfo.VehicleRequestCode;

            dt.Rows.Add(dr); // Add the DataRow to the DataTable

            // Set up the Crystal Report
            ReportDocument rprt = new ReportDocument();
            string reportPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DailyWeight.rpt");
            rprt.Load(reportPath);
            rprt.SetDataSource(ds);

            DailyReport reportForm = new DailyReport();
            reportForm.ShowReport(rprt);

            // Attach the Print event handler for Ctrl+P
            reportForm.KeyDown += (sender, e) =>
            {
                if (e.Control && e.KeyCode == Keys.P)
                {
                    PrintReport(rprt);
                }
            };

            // Set form to capture key events
            reportForm.KeyPreview = true;
        }
        private void PrintReport(ReportDocument reportDocument)
        {
            try
            {
                // Set page orientation to landscape
                reportDocument.PrintOptions.PrinterDuplex = CrystalDecisions.Shared.PrinterDuplex.Horizontal;
                reportDocument.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Landscape;

                // Set paper size if supported by printer
                // For custom paper size, ensure it's defined in the printer settings
                reportDocument.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.DefaultPaperSize; // Use custom size

                // Print 1 copy
                reportDocument.PrintToPrinter(1, false, 0, 0);
            }
            catch (Exception ex)
            {
                CustomMessageBox.ShowError("Error printing report: " + ex.Message);
            }
        }
        private void txt_fms_no_KeyPress(object sender, KeyPressEventArgs e)
        {

            if (e.KeyChar == (char)13)
            {
                if (string.IsNullOrEmpty(txt_fms_no.Text))
                {
                    CustomMessageBox.ShowError("Please provide FMS #");
                    return;
                }

                fms_no = txt_fms_no.Text.ToString();
                _ = getData(fms_no);
            }
        }

        private void btn_clear_Click(object sender, EventArgs e)
        {
            resetFields(1);
        }
        public void resetFields(int val)
        {

            if (val == 0)
            {
                txt_vehicle_no.Text = "";
                // Vehicle no not empty
            }

            else
            {    // Vehicle no empty
                 // 
                txt_vehicle_no.Text = "";
            }
            cb_1st_weight.Checked = false;
            cb_2nd_weight.Checked = false;
            txt_fms_no.Text = "";
            txt_container_no.Text = "";
            txt_1st_weight.Text = "";
            txt_1st_date.Text = "";
            txt_1st_time.Text = "";
            txt_2nd_weight.Text = "";
            txt_2nd_date.Text = "";
            txt_2nd_time.Text = "";
            txt_container_no.Text = "";
            if (cb_item.SelectedIndex != -1)
            {
                cb_item.SelectedIndex = 0;
            }
            if (cb_transporter.SelectedIndex != -1)
            {
                cb_transporter.SelectedIndex = 0;
            }
            if (cb_location.SelectedIndex != -1)
            {
                cb_location.SelectedIndex = 0;
            }
            //cb_comment.Text = "";
            txt_vehicle_no.BackColor = Color.LightGray;
        }

        private void scanTrollyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            disableControls();
        }

        private void weightScaleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            enableControls();
        }
        public void enableControls()
        {
            pb1.Visible = true;
            cb_1st_weight.Visible = true;
            pb_get.Visible = true;
            pb2.Visible = true;
            cb_2nd_weight.Visible = true;
            panel2.Visible = true;
            txt_scan.Visible = false;
            lbl_scan.Visible = false;
            btn_clear.Visible = true;
            btn_print.Visible = true;
            btn_save.Visible = true;
            txt_dc.Visible = false;
            lbl_dc.Visible = false;
            cb_trolley.Visible = false;
            lbl_trolly.Visible = false;


        }
        public void disableControls()
        {
            pb1.Visible = false;
            cb_1st_weight.Visible = false;
            pb_get.Visible = false;
            pb2.Visible = false;
            cb_2nd_weight.Visible = false;
            panel2.Visible = false;
            txt_scan.Visible = true;
            lbl_scan.Visible = true;
            btn_clear.Visible = false;
            btn_print.Visible = false;
            btn_save.Visible = false;
            cb_trolley.Visible = true;
            lbl_trolly.Visible = true;

        }
        private void groupBox2_Paint(object sender, PaintEventArgs e)
        {
            // Set the desired border color and thickness
            int borderThickness = 3; // You can adjust the thickness
            Color borderColor = Color.Black;

            // Set the pen for drawing the border
            using (Pen borderPen = new Pen(borderColor, borderThickness))
            {
                // Get the area where the border will be drawn
                Rectangle rect = groupBox2.ClientRectangle;
                rect.X += borderThickness / 2;
                rect.Y += (groupBox2.Font.Height / 2) - (borderThickness / 2);
                rect.Width -= borderThickness;
                rect.Height -= (groupBox2.Font.Height / 2) + borderThickness;

                // Draw the border
                e.Graphics.DrawRectangle(borderPen, rect);
            }
            using (SolidBrush brush = new SolidBrush(groupBox2.ForeColor))
            {
                e.Graphics.DrawString(groupBox2.Text, groupBox2.Font, brush, new PointF(6, 0));
            }


        }
        private DateTime lastKeystroke = DateTime.Now;

        private async void txt_scan_KeyPress(object sender, KeyPressEventArgs e)
        {
            ////TimeSpan timeSinceLastKeystroke = DateTime.Now - lastKeystroke;

            //////Clear input if keystroke is too slow (likely manual typing)
            ////if (timeSinceLastKeystroke.TotalMilliseconds > 100)
            ////{
            ////    txt_scan.Clear();
            ////    return;
            ////}

            ////lastKeystroke = DateTime.Now; // Update last keystroke time

            if (e.KeyChar == (char)13) // Enter key
            {
                if (cb_trolley.SelectedIndex == 0)
                {
                    CustomMessageBox.ShowError("Please select trolley #");
                    return;
                }

                string qrCode = txt_scan.Text.Trim();
                string weightText = lbl_weight.Text;

                if (string.IsNullOrEmpty(qrCode))
                {
                    CustomMessageBox.ShowError("Please scan QR code");
                    return;
                }

                if (string.IsNullOrEmpty(weightText) || weightText == "0")
                {
                    //weightText = "2000";
                    CustomMessageBox.ShowError("Please provide a valid weight");
                    return;
                }

                try
                {
                    decimal weight = Convert.ToDecimal(weightText);
                    int trolleyId = Convert.ToInt32(cb_trolley.SelectedValue.ToString());

                    string result = await dataAccessObject.StoreWeightAgainstAPI(qrCode, weight, trolleyId);

                    // Update UI and clear input
                    txt_dc.Text = qrCode.ToUpper();
                    txt_scan.Clear();
                    txt_dc.Visible = true;
                    lbl_dc.Visible = true;
                    cb_trolley.SelectedIndex = 0;

                    CustomMessageBox.ShowSuccess(result);

                    txt_scan.Enabled = false;
                    await Task.Delay(15000); // 15-second delay
                    txt_scan.Enabled = true;
                }
                catch (Exception ex)
                {
                    CustomMessageBox.ShowError("Data not saved.");
                }
                finally
                {
                    // Ensure txt_scan is enabled after delay, even if an error occurs
                    txt_scan.Enabled = true;
                }
            }
        }

        private void menuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            itemText = e.ClickedItem.Text;
        }

        public void adjustForFMS()
        {
            if (chk_box.Checked == true)
            {
            }
        }

        private void chk_box_CheckedChanged(object sender, EventArgs e)
        {
            if (chk_box.Checked == true)
            {
                controlVisibleFalse();
                lbl_fmsno.Visible = true;
                txt_fms_no.Visible = true;
            }
            else
            {
                controlVisibleTrue();
                lbl_fmsno.Visible = false;
                txt_fms_no.Visible = false;
            }

        }
        public void controlVisibleTrue()
        {
            cb_item.Visible = true;
            cb_location.Visible = true;
            cb_transporter.Visible = true;
            lbl_party_name.Visible = true;
            lbl_product_name.Visible = true;
            lbl_trnsporter.Visible = true;
            txt_container_no.Visible = true;
            lbl_container.Visible = true;
        }
        public void controlVisibleFalse()
        {
            cb_item.Visible = false;
            cb_location.Visible = false;
            cb_transporter.Visible = false;
            lbl_party_name.Visible = false;
            lbl_product_name.Visible = false;
            lbl_trnsporter.Visible = false;
            txt_container_no.Visible = false;
            lbl_container.Visible = false;

        }

        private void txt_vehicle_no_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                // Call the async method and handle the response with ContinueWith
                var task = getVehicleDetails();

                task.ContinueWith(responseTask =>
                {
                    // Check if the task is completed successfully
                    if (responseTask.Status == TaskStatus.RanToCompletion)
                    {
                        // Get the result
                        string result = responseTask.Result;

                        // Ensure UI updates happen on the main thread
                        this.Invoke(new Action(() =>
                        {
                            fillFields(result);

                        }));

                    }
                    else if (responseTask.Status == TaskStatus.Faulted)
                    {
                        // Handle any exceptions
                        this.Invoke(new Action(() =>
                        {
                            CustomMessageBox.ShowError($"Error");

                        }));
                    }
                });

            }
        }

        private async Task<string> getVehicleDetails()
        {
            string response = await dataAccessObject.GetVehicleDetails(txt_vehicle_no.Text.ToUpper());
            apiResponse = JsonConvert.DeserializeObject<VehicleRequestApiResponse>(response);
            return response;
        }
        public void fillFields(string result)
        {
            try
            {
                // Parse the JSON to extract loadingVehicleWeightInfo

                var jsonObject = JObject.Parse(result);
                var vehicleInfoJson = jsonObject["loadingVehicleWeightInfo"]?.ToString();

                // Check if loadingVehicleWeightInfo exists and is not empty
                if (!string.IsNullOrEmpty(vehicleInfoJson))
                {
                    // Deserialize loadingVehicleWeightInfo into LoadingVehicleWeightInfo object
                    var vehicleInfo = JsonConvert.DeserializeObject<LoadingVehicleWeightInfo>(vehicleInfoJson);

                    if (vehicleInfo.Id == 0)
                    {
                        txt_vehicle_no.BackColor = Color.PaleVioletRed;

                        return;
                    }
                    else
                    {
                        txt_vehicle_no.BackColor = Color.LightGreen;
                    }


                    // Populate ComboBoxes if values are not null or empty
                    if (!string.IsNullOrEmpty(vehicleInfo?.productCode))
                        cb_item.SelectedValue = vehicleInfo.productCode;

                    if (!string.IsNullOrEmpty(vehicleInfo?.transporterCode))
                        cb_transporter.SelectedValue = vehicleInfo.transporterCode;

                    if (!string.IsNullOrEmpty(vehicleInfo?.partyCode))
                        cb_location.SelectedValue = vehicleInfo.partyCode;

                    // Set weights if values are valid, and clear if both are zero
                    if (vehicleInfo?.DeadWeight == 0 && vehicleInfo?.FinalWeight == 0)
                    {
                        txt_1st_weight.Clear();
                        txt_2nd_weight.Clear();
                    }
                    else
                    {
                        txt_1st_weight.Text = vehicleInfo?.DeadWeight?.ToString() ?? string.Empty;
                        txt_2nd_weight.Text = vehicleInfo?.FinalWeight?.ToString() ?? string.Empty;
                    }

                    // Separate date and time for the DeadWeightDateTime if not null
                    if (vehicleInfo?.DeadWeightDateTime != null)
                    {
                        txt_1st_date.Text = vehicleInfo.DeadWeightDateTime.Value.ToShortDateString();
                        txt_1st_time.Text = vehicleInfo.DeadWeightDateTime.Value.ToShortTimeString();
                    }
                    else
                    {
                        txt_1st_date.Clear();
                        txt_1st_time.Clear();
                    }

                    // Separate date and time for the FinalWeightDateTime if not null
                    if (vehicleInfo?.FinalWeightDateTime != null)
                    {
                        txt_2nd_date.Text = vehicleInfo.FinalWeightDateTime.Value.ToShortDateString();
                        txt_2nd_time.Text = vehicleInfo.FinalWeightDateTime.Value.ToShortTimeString();
                    }
                    else
                    {
                        txt_2nd_date.Clear();
                        txt_2nd_time.Clear();
                    }

                    // Set comment if not null or empty
                    //cb_comment.Text = vehicleInfo?.Comment ?? string.Empty;
                }
                else
                {
                    // Clear fields if no vehicle info is found
                    resetFields(0);
                }
            }
            catch (Exception ex)
            {
                CustomMessageBox.ShowError($"Error parsing vehicle details: {ex.Message}");
            }
        }



        private void cb_location_Leave(object sender, EventArgs e)
        {
            string enteredValue = cb_location.Text.ToUpper();
            bool valueExists = false;

            // Check if the entered value exists in the ComboBox
            foreach (DataRowView item in cb_location.Items)
            {
                if (item["party_name"].ToString().ToUpper() == enteredValue) // Use the actual column for display
                {
                    valueExists = true;
                    break;
                }
            }

            // If the value does not exist, prompt to add it
            if (!valueExists)
            {
                var result = MessageBox.Show($"The value '{enteredValue}' is not in the list. Would you like to add it?",
                                             "Add New Value",
                                             MessageBoxButtons.YesNo,
                                             MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    dataAccessObject.AddValueToDatabase(enteredValue, "weight_scale_party", "party_name");
                    DataTable partyData = dataAccessObject.GetWeightScaleData("weight_scale_party");

                    // Invoke UI updates for other ComboBoxes
                    Invoke((Action)(() =>
                    {

                        // Bind party data to comboBoxParty
                        cb_location.DataSource = partyData;
                        cb_location.DisplayMember = "party_name";
                        cb_location.ValueMember = "party_code";
                        SetupSearchableComboBox(cb_location);

                    }));
                }
            }
        }

        private void cb_transporter_Leave(object sender, EventArgs e)
        {
            string enteredValue = cb_transporter.Text.ToUpper();
            bool valueExists = false;

            // Check if the entered value exists in the ComboBox
            foreach (DataRowView item in cb_transporter.Items)
            {
                if (item["transporter_name"].ToString().ToUpper() == enteredValue) // Use the actual column for display
                {
                    valueExists = true;
                    break;
                }
            }

            // If the value does not exist, prompt to add it
            if (!valueExists)
            {
                var result = MessageBox.Show($"The value '{enteredValue}' is not in the list. Would you like to add it?",
                                             "Add New Value",
                                             MessageBoxButtons.YesNo,
                                             MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    dataAccessObject.AddValueToDatabase(enteredValue, "weight_scale_transporter", "transporter_name");
                    DataTable transporterData = dataAccessObject.GetWeightScaleData("weight_scale_transporter");

                    // Invoke UI updates for other ComboBoxes
                    Invoke((Action)(() =>
                    {

                        // Bind party data to comboBoxParty
                        cb_transporter.DataSource = transporterData;
                        cb_transporter.DisplayMember = "transporter_name";
                        cb_transporter.ValueMember = "transporter_code";
                        SetupSearchableComboBox(cb_transporter);

                    }));
                }
            }
        }
    }
}
