using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

/* References */
// Using a delegate to trigger method on the customer view form
// https://www.coderslexicon.com/passing-data-between-forms-using-delegates-and-events/

namespace QueueSys
{
    public partial class frmEmployeeView : Form
    {
        public frmEmployeeView()
        {
            InitializeComponent();
        }

        // Our delegate (which "points" at any method which takes an object and EventArgs)
        // Look familiar? This is the signature of most control events on a form
        public delegate void SendMessage(object obj, EventArgs e);

        // Here is the event we trigger to send messages out to listeners
        public event SendMessage OnSendMessage;

        /* Execute when program / main form loads.
         * Pop up the customer view screen to drag onto second monitor 
         * creates our second form, says "attach its MessageReceived function to the event"
         */
        private void frmEmployeeView_Load(object sender, EventArgs e)
        {
            frmCustomerView frm = new frmCustomerView();
            OnSendMessage += frm.MessageReceived;
            frm.Show();
            RefreshEmployeeView();
        }

        /* Enable options menu. */
        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmOptions frm = new frmOptions();
            frm.Show();
            frm.Activate();
        }

        // Exits the application.
        private void exitAltF4ToolStripMenuItem_Click(object sender, EventArgs e) => Application.Exit();

        private void generateReportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("To-do: Generate excel report from SQL Database.");
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            SqliteDataAccess sda = new SqliteDataAccess();
            ReportView evNewCx = new ReportView();

            evNewCx.customer_name = tbCustomerName.Text;
            evNewCx.num_bags = Int32.Parse(cbNumBags.Text);
            evNewCx.employee = tbEmployeeName.Text;

            sda.SaveCustomer(evNewCx);

            //Invoke the delegate to update customer view.
            OnSendMessage?.Invoke(this, e);

            tbCustomerName.Text = "";
            cbNumBags.Text = "";
            tbEmployeeName.Text = "";

            MessageBox.Show("Customer has been added!", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.Information);

            RefreshEmployeeView();
        }

        private void RefreshEmployeeView()
        {
            dgvEmployeeView.Rows.Clear();
            dgvEmployeeView.Refresh();

            // Build the row.
            SqliteDataAccess sdaEvView = new SqliteDataAccess();
            List<EmployeeView> evList = new List<EmployeeView>();

            evList = sdaEvView.LoadEmployeeView();

            foreach (EmployeeView item in evList)
            {
                string[] row = new string[] { item.id.ToString(), item.customer_name };
                dgvEmployeeView.Rows.Add(row);
            }

            DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
            cmb.HeaderText = "Status";
            cmb.MaxDropDownItems = 3;

            //Allows for dynamic adding/removing status items per
            //the status lookup table in the sqlite db.
            List<StatusModel> s = new List<StatusModel>();
            s = sdaEvView.LoadStatusStrings();

            foreach (StatusModel item in s)
            {
                cmb.Items.Add(item.status);
            }

            dgvEmployeeView.Columns.Add(cmb);

            //Change the status of the combobox based on the query from the db.
            List<StatusModel> cxStatus = new List<StatusModel>();

            //Select the id column from the current row.
            foreach(DataGridViewRow row in dgvEmployeeView.Rows)
            {
                cxStatus = sdaEvView.GetCxStatus(Int32.Parse(dgvEmployeeView.Rows[row.Index].Cells[0].Value.ToString()));
                row.Cells[2].Value = cxStatus[0].status;
            }

            // Add the delete button.
            DataGridViewButtonColumn btn = new DataGridViewButtonColumn();
            btn.HeaderText = "Delete";
            btn.Text = "Delete";
            btn.Name = "btn";
            btn.UseColumnTextForButtonValue = true;

            dgvEmployeeView.Columns.Add(btn);
        }


        private void dgvEmployeeView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            //The delete button was clicked.
            if (e.ColumnIndex == 3)
            {
                //Sanity check, per option.
                if (Properties.Settings.Default.ConfirmDelete)
                {
                    DialogResult result = MessageBox.Show("Are you sure you want to delete this customer?", "Queue System", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);

                    if (result == DialogResult.No)
                    {
                        MessageBox.Show("Customer was not deleted.", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }
                }

                SqliteDataAccess sdaEvView = new SqliteDataAccess();

                EmployeeView evCustomer = new EmployeeView();
                evCustomer.id = Int32.Parse(dgvEmployeeView.CurrentRow.Cells[0].Value.ToString());

                sdaEvView.ArchiveCustomer(evCustomer);
                RefreshEmployeeView();

                //Invoke the delegate to update customer view with updated data.
                OnSendMessage?.Invoke(this, e);

                MessageBox.Show("Customer has been removed from the queue", "Queue System", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        // This event hooks the status combobox into the change commit event
        private void dgvEmployeeView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
        {
            if (dgvEmployeeView.CurrentCell.ColumnIndex == 2)
            {
                ComboBox combo = e.Control as ComboBox;

                if(combo != null)
                {
                    combo.SelectionChangeCommitted += new EventHandler(dgvCbStatus_SelectionChangeCommitted);
                }
            }
        }

        /* This event fires when the "status" combo box was changed
         * and that change was "committed"
         * This is needed to update the backend SQL db on demand,
         * then update the customer view screen.
         */
        private void dgvCbStatus_SelectionChangeCommitted(object sender, EventArgs e)
        {
            DataGridViewComboBoxEditingControl dgvcbec = sender as DataGridViewComboBoxEditingControl;
            int CustomerId = Int32.Parse(dgvcbec.EditingControlDataGridView.CurrentRow.Cells[0].Value.ToString());

            string new_status = dgvcbec.Text;

            //Check to see if we need an update.
            SqliteDataAccess sdaEvView = new SqliteDataAccess();

            List<StatusModel> cxStatus = new List<StatusModel>();
            cxStatus = sdaEvView.GetCxStatus(CustomerId);

            // Update not required.
            if (cxStatus[0].status == new_status)
                return;

            /* Update of the backend DB required beyond this point
             * Update the customer status on the backend db.
             */
            sdaEvView.UpdateCustomerStatus(CustomerId, new_status);

            //Invoke the delegate to update customer view with updated data.
            OnSendMessage?.Invoke(this, e);
        }
    }
}
