using System;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Transactions;
using System.Windows.Forms;

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

        public FrmManageAdItems()
        {
            InitializeComponent();
            newItemTextBox.TextChanged += NewItemTextChanged;
            adItemsListView.ItemSelectionChanged += UpdateAdItemTextFields;
            var columnHeader = new ColumnHeader
            {
                Name = "AdItemHeaderColumn",
                Width = Width / 2
            };
            adItemsListView.Columns.Add(columnHeader);
            RefreshAdItemListing();
        }

        private void FilterValueChanged(object sender, EventArgs e)
        {
            if(filterComboBox.Enabled == false) return;
            adItemsListView.Columns[0].Text = @"Current Ad Items (" + (filterComboBox.SelectedItem.ToString() == "All" ? "No Filter" : @"Filter " + filterComboBox.SelectedItem) + @"):";
            adItemsListView.Items.Clear();
            var db = new AdvertisingProfitControlModel();
            var adItems = db.AdItems.Select(x => x);
            foreach (var adItem in adItems)
            {
                var item = new ListViewItem
                {
                    Text = adItem.Name,
                    Tag = adItem
                };

                if (string.Equals(filterComboBox.SelectedItem.ToString(), "All", StringComparison.Ordinal))
                {
                    adItemsListView.Items.Add(item);
                    continue;
                }

                if (string.Equals(filterComboBox.SelectedItem.ToString(), "0-9", StringComparison.Ordinal) && char.IsNumber(adItem.Name[0]))
                {
                    adItemsListView.Items.Add(item);                    
                }
                else if (!string.Equals(filterComboBox.SelectedItem.ToString(), "0-9", StringComparison.Ordinal) && char.IsLetter(adItem.Name[0]))
                {
                    if(filterComboBox.SelectedItem.ToString()[0] == adItem.Name[0])
                    { adItemsListView.Items.Add(item);}
                }
            }
            newItemTextBox.Text = string.Empty;
            descriptionTextBox.Text = string.Empty;
            removeAdItemButton.Enabled = false;

        }

        private void UpdateAdItemTextFields(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            newItemTextBox.Text = ((AdItem)e.Item.Tag).Name;
            descriptionTextBox.Text = ((AdItem)e.Item.Tag).Description;
            _isUpdating = true;
            removeAdItemButton.Enabled = true;
            addUpdateItemButton.Text = @"Update Ad Item";
            newItemLabel.Text = @"Update Ad Item:";
        }

        private void NewItemTextChanged(object sender, EventArgs e)
        {
            if (_isUpdating && newItemTextBox.Text.Length == 0)
            {
                _isUpdating = false;
                descriptionTextBox.Text = string.Empty;
                addUpdateItemButton.Text = @"Register Ad Item";
                newItemLabel.Text = @"Register New Ad Item:";
            }
            addUpdateItemButton.Enabled = newItemTextBox.Text.Length > 0;
        }

        private void RefreshAdItemListing(string filter = "")
        {
            filterComboBox.SelectedIndexChanged -= FilterValueChanged;
            //Check to see if the current view is empty.
            if (adItemsListView.Items.Count == 0) filter = string.Empty;
            adItemsListView.Items.Clear();
            filterComboBox.Items.Clear();
            filterComboBox.Items.Add("All");
            var db = new AdvertisingProfitControlModel();
            var adItems = db.AdItems.Select(x => x).OrderBy(x => x.Name);
            var adItemCount = 0;
            var numberFound = false;
            foreach (var adItem in adItems)
            {
                var item = new ListViewItem
                {
                    Text = adItem.Name,
                    Tag = adItem
                };
                if (filter == string.Empty || filter == "All")
                {
                    adItemsListView.Items.Add(item);
                }
                else if (adItem.Name[0].ToString() == filter)
                {
                    adItemsListView.Items.Add(item);
                }
                else if (filter == "0-9" && char.IsNumber(adItem.Name[0]))
                {
                    adItemsListView.Items.Add(item);
                }
                //Populate the filter.
                if (!filterComboBox.Items.Contains(adItem.Name[0].ToString()))
                {
                    if (char.IsDigit(adItem.Name[0]) && !numberFound)
                    {
                        filterComboBox.Items.Add("0-9");
                        numberFound = true;
                    }
                    else
                    {
                        filterComboBox.Items.Add(adItem.Name[0].ToString());                        
                    }
                }
                adItemCount++;
            }

            if (adItemCount > 0)
            {
                filterComboBox.Enabled = true;
                filterComboBox.SelectedIndex = filterComboBox.Items.Contains(filter) ? filterComboBox.Items.IndexOf(filter) : 0;
                adItemsListView.Columns[0].Text = @"Current Ad Items (" + (filterComboBox.SelectedItem.ToString() == "All" ? "No Filter" : @"Filter " + filterComboBox.SelectedItem) + @"):";
            }
            else
            {
                adItemsListView.Columns[0].Text = @"No Ad Items to Display.";
                filterComboBox.Enabled = false;
                filterComboBox.SelectedIndex = 0;
            }
            removeAdItemButton.Enabled = false;
            newItemTextBox.Text = string.Empty;
            descriptionTextBox.Text = string.Empty;
            filterComboBox.SelectedIndexChanged += FilterValueChanged;
        }

        private void RemoveSelectedAdItem(object sender, EventArgs e)
        {
            var item = adItemsListView.SelectedItems[0];
            var oldAdItem = (AdItem)item.Tag;
            var db = new AdvertisingProfitControlModel();
            var adItemEntry = db.AdItems.Single(x => x.Id == oldAdItem.Id);
            //Check to see if the ad special is used by other tables.
            if (adItemEntry.ActualSales.Count > 0)
            {
                //If so, display a warning to the user about the potential data loss.
                var result =
                    MessageBox.Show(
                        adItemEntry.ActualSales.Count +
                        @" reference(s) to this item found. Do you want to delete these records? This can not be undone.",
                        @"References to " + oldAdItem.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.Projections.RemoveRange(db.Projections.Where(x => x.FkAdItemId == oldAdItem.Id));
                        db.Inventories.RemoveRange(db.Inventories.Where(x => x.FkAdItemId == oldAdItem.Id));
                        db.ActualSales.RemoveRange(db.ActualSales.Where(x => x.FkAdItemId == oldAdItem.Id));
                        db.AdItems.Remove(adItemEntry);
                        db.SaveChanges();
                        scope.Complete();
                        informationLabel.Text = @"Removed '" + Environment.NewLine + oldAdItem.Name +
                                                Environment.NewLine + @"' successfully.";
                        adItemsListView.Items.RemoveAt(adItemsListView.SelectedItems[0].Index);
                    }
                    catch (DbUpdateException ex)
                    {
                        informationLabel.Text = @"Failed to remove " + Environment.NewLine + oldAdItem.Name + @"." +
                                                Environment.NewLine + ex.Message;
                    }
                }
            }
            else
            {
                try
                {
                    db.AdItems.Remove(adItemEntry);
                    db.SaveChanges();
                    informationLabel.Text = @"Removed '" + Environment.NewLine + oldAdItem.Name +
                                            Environment.NewLine + @"' successfully.";
                    adItemsListView.Items.RemoveAt(adItemsListView.SelectedItems[0].Index);
                }
                catch (DbUpdateException ex)
                {
                    informationLabel.Text = @"Failed to remove " + Environment.NewLine + oldAdItem.Name + @"." + Environment.NewLine + ex.Message;
                }
            }
            RefreshAdItemListing(filterComboBox.SelectedItem.ToString());
        }

        private void AddUpdateItem(object sender, EventArgs e)
        {
            var db = new AdvertisingProfitControlModel();
            if (!_isUpdating)
            {
                if (!db.AdItems.Any(x => x.Name == newItemTextBox.Text))
                {
                    var adItem = new AdItem
                    {
                        Name = newItemTextBox.Text,
                        Description = descriptionTextBox.Text
                    };
                    db.AdItems.Add(adItem);
                    try
                    {
                        db.SaveChanges();
                        informationLabel.Text = @"Registered '" + Environment.NewLine + adItem.Name + Environment.NewLine + @"' successfully.";
                    }
                    catch (DbUpdateException ex)
                    {
                        informationLabel.Text = @"Failed to register '" + Environment.NewLine + adItem.Name + @"'." + Environment.NewLine +
                                                ex.Message;
                    }
                }
                else
                {
                    MessageBox.Show(@"Ad item '" + newItemTextBox.Text + @"' already exists.",
                        @"Duplicate Entry", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    newItemTextBox.Text = string.Empty;
                }
            }
            else
            {
                var item = adItemsListView.SelectedItems[0];
                var index = ((AdItem)item.Tag).Id;
                var adItem = db.AdItems.SingleOrDefault(x => x.Id == index);
                if (adItem == null)
                {
                    informationLabel.Text = @"Failed to retrieve " + Environment.NewLine + @"ad item ID.";
                    return;
                }
                adItem.Name = newItemTextBox.Text;
                adItem.Description = descriptionTextBox.Text;
                db.SaveChanges();
                informationLabel.Text = @"Updated '" + Environment.NewLine + newItemTextBox.Text + Environment.NewLine + @"' successfully.";
            }
            RefreshAdItemListing(filterComboBox.SelectedItem.ToString());
        }
    }
}
