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

namespace AdvertsingProfitControl
{
    public partial class FrmManageSuppliers : Form
    {
        private bool _isUpdating;

        public FrmManageSuppliers()
        {
            InitializeComponent();
            newSupplierTextBox.TextChanged += UpdateButtonOnTextChanged;
            suppliersListBox.ItemSelectionChanged += UpdateSupplierFields;
            var columnHeader = new ColumnHeader
            {
                Name = "SupplierHeaderColumn",
                Width = Width / 2
            };
            suppliersListBox.Columns.Add(columnHeader);
            RefreshSupplierListing();
        }

        private void UpdateSupplierFields(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            newSupplierTextBox.Text = ((Supplier)e.Item.Tag).Name;
            descriptionTextBox.Text = ((Supplier)e.Item.Tag).Description;
            _isUpdating = true;
            deleteSupplierButton.Enabled = true;
            registerSupplierButton.Text = @"Update Supplier";
            newSupplierLabel.Text = @"Update Supplier:";
        }

        private void UpdateButtonOnTextChanged(object sender, EventArgs e)
        {
            if (_isUpdating && newSupplierTextBox.Text.Length == 0)
            {
                _isUpdating = false;
                descriptionTextBox.Text = string.Empty;
                registerSupplierButton.Text = @"Register Supplier";
                newSupplierLabel.Text = @"Register New Supplier:";
            }
            registerSupplierButton.Enabled = newSupplierTextBox.Text.Length > 0;
        }

        private void RefreshSupplierListing()
        {
            suppliersListBox.Items.Clear();
            var db = new AdvertisingProfitControlModel();
            var suppliers = db.Suppliers.Select(x => x).OrderBy(x => x.Name);
            var supplierCount = 0;
            foreach (var supplier in suppliers)
            {
                var item = new ListViewItem
                {
                    Text = supplier.Name,
                    Tag = supplier
                };
                suppliersListBox.Items.Add(item);
                supplierCount++;
            }

            suppliersListBox.Columns[0].Text = supplierCount > 0 ? @"Current Suppliers:" : @"No Suppliers to Display";
            deleteSupplierButton.Enabled = false;
            newSupplierTextBox.Text = string.Empty;
            descriptionTextBox.Text = string.Empty;
        }

        private void registerSupplierButton_Click(object sender, EventArgs e)
        {
            var db = new AdvertisingProfitControlModel();
            if (!_isUpdating)
            {
                if (!db.Suppliers.Any(x => x.Name == newSupplierTextBox.Text))
                {
                    var supplier = new Supplier()
                    {
                        Name = newSupplierTextBox.Text,
                        Description = descriptionTextBox.Text
                    };
                    db.Suppliers.Add(supplier);
                    try
                    {
                        db.SaveChanges();
                        informationLabel.Text = @"Registered '" + Environment.NewLine + supplier.Name + Environment.NewLine + @"' successfully.";
                    }
                    catch (DbUpdateException ex)
                    {
                        informationLabel.Text = @"Failed to register '" + Environment.NewLine + supplier.Name + @"'." + Environment.NewLine +
                                                ex.Message;
                    }
                }
                else
                {
                    MessageBox.Show(@"Supplier '" + newSupplierTextBox.Text + @"' already exists.",
                        @"Duplicate Entry", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    newSupplierTextBox.Text = string.Empty;
                }
            }
            else
            {
                var item = suppliersListBox.SelectedItems[0];
                var index = ((Supplier)item.Tag).Id;
                var supplier = db.Suppliers.SingleOrDefault(x => x.Id == index);
                if (supplier == null)
                {
                    informationLabel.Text = @"Failed to retrieve " + Environment.NewLine + @"supplier ID.";
                    return;
                }
                supplier.Name = newSupplierTextBox.Text;
                supplier.Description = descriptionTextBox.Text;
                db.SaveChanges();
                informationLabel.Text = @"Updated '" + Environment.NewLine + newSupplierTextBox.Text + Environment.NewLine + @"' successfully.";
            }
            RefreshSupplierListing();
        }

        private void deleteSupplierButton_Click(object sender, EventArgs e)
        {
            var item = suppliersListBox.SelectedItems[0];
            var oldSupplier = (Supplier)item.Tag;
            var db = new AdvertisingProfitControlModel();
            var supplier = db.Suppliers.Single(x => x.Id == oldSupplier.Id);
            //Check to see if the ad special is used by other tables.
            if (supplier.Invoices.Count > 0)
            {
                //If so, display a warning to the user about the potential data loss.
                var result =
                    MessageBox.Show(
                        supplier.Invoices.Count +
                        @" reference(s) to this supplier found. Do you want to delete these records? This can not be undone.",
                        @"References to " + oldSupplier.Name + @" Found", MessageBoxButtons.YesNoCancel,
                        MessageBoxIcon.Question);
                if (result != DialogResult.Yes) return;
                //Perform the necessary operations to remove all references to the key word.
                using (var scope = new TransactionScope())
                {
                    try
                    {
                        db.Invoices.RemoveRange(db.Invoices.Where(x => x.FkSupplierId == oldSupplier.Id));
                        db.Suppliers.Remove(supplier);
                        db.SaveChanges();
                        scope.Complete();
                        informationLabel.Text = @"Removed '" + Environment.NewLine + oldSupplier.Name +
                                                Environment.NewLine + @"' successfully.";
                    }
                    catch (DbUpdateException ex)
                    {
                        informationLabel.Text = @"Failed to remove " + Environment.NewLine + oldSupplier.Name + @"." +
                                                Environment.NewLine + ex.Message;
                    }
                }
            }
            else
            {
                try
                {
                    db.Suppliers.Remove(supplier);
                    db.SaveChanges();
                    informationLabel.Text = @"Removed '" + Environment.NewLine + oldSupplier.Name +
                                            Environment.NewLine + @"' successfully.";
                }
                catch (DbUpdateException ex)
                {
                    informationLabel.Text = @"Failed to remove " + Environment.NewLine + oldSupplier.Name + @"." + Environment.NewLine + ex.Message;
                }
            }
            RefreshSupplierListing();
        }
    }
}
