using BoFilTest.Domain;
using BoFilTest.Export;
using BoFilTest.Utils;
using System;
using System.Windows;
using System.Windows.Controls;
using Unity;

namespace BoFilTest.UI
{
    /// <summary>
    /// Interaction logic for EndWindow.xaml
    /// </summary>
    public partial class EndPage : Page
    {
        private readonly IUnityContainer container;
        private readonly EventBus eventBus;
        private readonly DataModel dataModel;
        private readonly String titleTemplate;

        public EndPage(IUnityContainer container, EventBus eventBus, DataModel dataModel)
        {
            this.DataContext = new EndModel(dataModel);
            
            InitializeComponent();
            AllTextBlocks.TranslateForRoot(MainLayout);
            this.container = container;
            this.eventBus = eventBus;
            this.dataModel = dataModel;
            this.titleTemplate = this.Title;

            CakeProperties.FilterCakeConsistencyNames.BindTo(this.CakeConsistencyComboBox);
            CakeProperties.FilterCakeCrackingNames.BindTo(this.CakeCrackingComboBox);
            CakeProperties.EdgeDissolutionNames.BindTo(this.EdgeDissolutionComboBox);

            Loaded += EndPage_Loaded;
        }

        private void EndPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.Title = Translated.FromKey(this.titleTemplate, dataModel.TestNumber);
            this.titleLabel.Text = this.Title;
            ReloadViewModel();
        }

        private void ReloadViewModel()
        {
            // This is a bit of a hack to reload all the data from the view model into the bound components
            // See: https://stackoverflow.com/questions/5157068/is-there-a-way-to-refresh-all-bindings-in-wpf
            // It's probably better if this refresh comes from the model
            var model = (EndModel)DataContext;
            model.RefreshAll();
        }

        private void ClearHistory()
        {
            var entry = this.NavigationService.RemoveBackEntry();
            while (entry != null)
            {
                entry = this.NavigationService.RemoveBackEntry();
            }
        }

        private void GoToStart()
        {
            NavigationService.Navigate(container.Resolve<StartPage>());
            ClearHistory(); // Need to clear the history or we'll have memory leaking in the long run
        }

        private void DropTest_Click(object sender, RoutedEventArgs e)
        {
            GoToStart();
        }

        private void Export(Func<IExcelExport> exportProcessThunk)
        {   
            try
            {
                // This executes the thunk so that object creation is in the try/catch block
                var filename = exportProcessThunk().Run();
                MessageBox.Show(Window.GetWindow(this), Translated.FromKey("EXPORTED_TO", filename), Translated.FromKey("EXPORT_SUCCESSFUL"), MessageBoxButton.OK, MessageBoxImage.Information);
            }
            catch(Exception error)
            {
                MessageBox.Show(Window.GetWindow(this), Translated.FromKey("EXPORT_FAILED", error.Message), Translated.FromKey("ERROR_TITLE"), MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }

            dataModel.Store.EndTest(dataModel.Form);
            GoToStart();
        }

        private void FilterExport_Click(object sender, RoutedEventArgs e)
        {
            Export(() => new FilterExcelExport(this.dataModel));
        }
    }
}
