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

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

        public FrmRegisterAdSpecial()
        {
            InitializeComponent();
            newAdSpecialTextBox.TextChanged += NewAdSpecialTextChanged;
            var columnHeader = new ColumnHeader
            {
                Name = "AdSpecialsHeaderColumn",
                Text = @"Current Ad Special Grouping Keywords:",
                Width = Width / 2
            };
            adSpecialsListBox.Columns.Add(columnHeader);
            adSpecialsListBox.ItemSelectionChanged += UpdateAdSpecialTextBoxes;
            RefreshAdSpecialListing();
        }

        private void UpdateAdSpecialTextBoxes(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            newAdSpecialTextBox.Text = ((AdSpecial) e.Item.Tag).Name;
            descriptionTextBox.Text = ((AdSpecial) e.Item.Tag).Description;
            _isUpdating = true;
            deleteAdSpecialButton.Enabled = true;
            registerAdSpecialButton.Text = @"Update Ad Special";
            newAdSpecialLabel.Text = @"Update Ad Special:";
        }

        private void NewAdSpecialTextChanged(object sender, EventArgs e)
        {
            if (_isUpdating && newAdSpecialTextBox.Text.Length == 0)
            {
                _isUpdating = false;
                descriptionTextBox.Text = string.Empty;
                registerAdSpecialButton.Text = @"Register Ad Special";
                newAdSpecialLabel.Text = @"Register New Ad Special:";
            }
            registerAdSpecialButton.Enabled = newAdSpecialTextBox.Text.Length > 0;
        }

        private void RegisterNewAdSpecial(object sender, EventArgs e)
        {
            var db = new AdvertisingProfitControlModel();
            if (!_isUpdating)
            {
                if (!db.AdSpecials.Any(x => x.Name == newAdSpecialTextBox.Text))
                {
                    var adSpecial = new AdSpecial
                    {
                        Name = newAdSpecialTextBox.Text,
                        Description = descriptionTextBox.Text
                    };
                    db.AdSpecials.Add(adSpecial);
                    try
                    {
                        db.SaveChanges();
                        informationLabel.Text = @"Registered '" + Environment.NewLine + adSpecial.Name + Environment.NewLine + @"' successfully.";
                    }
                    catch (DbUpdateException ex)
                    {
                        informationLabel.Text = @"Failed to register '" + Environment.NewLine + adSpecial.Name + @"'." + Environment.NewLine +
                                                ex.Message;
                    }
                }
                else
                {
                    MessageBox.Show(@"Ad Special '" + newAdSpecialTextBox.Text + @"' already exists.",
                        @"Duplicate Entry", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    newAdSpecialTextBox.Text = string.Empty;
                }
            }
            else
            {
                var item = adSpecialsListBox.SelectedItems[0];
                var index = ((AdSpecial) item.Tag).Id;
                var adSpecial = db.AdSpecials.SingleOrDefault(x => x.Id == index);
                if (adSpecial == null)
                {
                    informationLabel.Text = @"Failed to retrieve " + Environment.NewLine + @"ad special keyword ID.";
                    return;
                }
                adSpecial.Name = newAdSpecialTextBox.Text;
                adSpecial.Description = descriptionTextBox.Text;
                db.SaveChanges();
                informationLabel.Text = @"Updated '" + Environment.NewLine + newAdSpecialTextBox.Text + Environment.NewLine + @"' successfully.";
            }
            RefreshAdSpecialListing();
        }

        private void RefreshAdSpecialListing()
        {
            adSpecialsListBox.Items.Clear();
            var db = new AdvertisingProfitControlModel();
            var adSpecials = db.AdSpecials.Select(x => x).OrderBy(x => x.Name);
            foreach (var adSpecial in adSpecials)
            {
                var item = new ListViewItem
                {
                    Text = adSpecial.Name,
                    Tag = adSpecial
                };
                adSpecialsListBox.Items.Add(item);
            }
            deleteAdSpecialButton.Enabled = false;
            newAdSpecialTextBox.Text = string.Empty;
            descriptionTextBox.Text = string.Empty;
        }

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