using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Markup;
using Microsoft.Win32;
using QC.QMine.QMineInterface;
using QC.Tools;

namespace QC.QMine;

public partial class MainWindow : Window, INotifyPropertyChanged, ILogger, IComponentConnector
{
	public delegate void RunReportEventHandler(bool useSelectedResultPlugins);

	public delegate void NewPluginSettingsEventHandler();

	public delegate void ResetPluginSettingsEventHandler();

	public delegate void DatabaseChangedEventHandler();

	private const string mainWindowConfigFilename = "QMineMainWindow.config";

	private QueryPluginCollection queryPluginList = new QueryPluginCollection();

	private RecentFileCollection recentQMineSettingsFilePathCollection;

	private OutputLogWindow outputLogWindow;

	private string queryPluginStatusText = "Query plugins loaded";

	private string resultPluginStatusText = "Result Plugins loaded";

	private string qMineStatusText = "QMine ready";

	private string mainWindowTitle = "QMine";

	private ResultPluginCollection resultsPluginList = new ResultPluginCollection();

	private PluginSettingsManager pluginSettingsManager;

	public string QueryPluginStatusText
	{
		get
		{
			return queryPluginStatusText;
		}
		set
		{
			if (!(queryPluginStatusText == value))
			{
				queryPluginStatusText = value;
				OnPropertyChanged("QueryPluginStatusText");
			}
		}
	}

	public string ResultPluginStatusText
	{
		get
		{
			return resultPluginStatusText;
		}
		set
		{
			if (!(resultPluginStatusText == value))
			{
				resultPluginStatusText = value;
				OnPropertyChanged("ResultPluginStatusText");
			}
		}
	}

	public string QMineStatusText
	{
		get
		{
			return qMineStatusText;
		}
		set
		{
			if (!(qMineStatusText == value))
			{
				qMineStatusText = value;
				OnPropertyChanged("QMineStatusText");
			}
		}
	}

	public string ServerName => QMineGlobalInformation.ServerName;

	public string DatabaseName => QMineGlobalInformation.DatabaseName;

	public string ServerDescription => QMineGlobalInformation.ServerDescription;

	public string DatabaseDescription => QMineGlobalInformation.DatabaseDescription;

	public RecentFileCollection RecentQMineSettingsFilePathCollection
	{
		get
		{
			if (recentQMineSettingsFilePathCollection == null)
			{
				recentQMineSettingsFilePathCollection = new RecentFileCollection();
			}
			return recentQMineSettingsFilePathCollection;
		}
		set
		{
			if (recentQMineSettingsFilePathCollection != value)
			{
				recentQMineSettingsFilePathCollection = value;
				OnPropertyChanged("RecentQMineSettingsFilePathCollection");
			}
		}
	}

	public QueryPluginCollection QueryPluginList
	{
		get
		{
			return queryPluginList;
		}
		set
		{
			if (queryPluginList != value)
			{
				queryPluginList = value;
				OnPropertyChanged("QueryPluginList");
			}
		}
	}

	public string MainWindowTitle
	{
		get
		{
			return mainWindowTitle;
		}
		set
		{
			if (!(mainWindowTitle == value))
			{
				mainWindowTitle = "QMine: " + value;
				OnPropertyChanged("MainWindowTitle");
			}
		}
	}

	public ResultPluginCollection ResultsPluginList
	{
		get
		{
			return resultsPluginList;
		}
		set
		{
			if (resultsPluginList != value)
			{
				resultsPluginList = value;
				OnPropertyChanged("ResultsPluginList");
			}
		}
	}

	public PluginSettingsManager PluginSettingsManager
	{
		get
		{
			return pluginSettingsManager;
		}
		set
		{
			pluginSettingsManager = value;
			pluginSettingsManager.OnPluginSettingsModified += pluginSettingsManager_OnPluginSettingsModified;
		}
	}

	public event RunReportEventHandler OnRunReport;

	public event Action<string> OnSavePluginSettings;

	public event NewPluginSettingsEventHandler OnNewPluginSettings;

	public event ResetPluginSettingsEventHandler OnResetPluginSettings;

	public event Action<string> OnLoadPluginSettings;

	public event Func<bool> OnMainWindowClosing;

	public event DatabaseChangedEventHandler OnDatabaseChanged;

	public event PropertyChangedEventHandler PropertyChanged;

	protected virtual void SaveMainWindowConfiguration()
	{
		string filePath = Path.Combine(CommonFunctions.QMineDataPath, "QMineMainWindow.config");
		CommonFunctions.Serialize(filePath, RecentQMineSettingsFilePathCollection);
	}

	protected virtual void LoadMainWindowConfiguration()
	{
		string text = Path.Combine(CommonFunctions.QMineDataPath, "QMineMainWindow.config");
		try
		{
			if (File.Exists(text) && File.ReadAllBytes(text).Length > 0)
			{
				RecentQMineSettingsFilePathCollection = CommonFunctions.Deserialize<RecentFileCollection>(text);
			}
		}
		catch (Exception)
		{
			if (RecentQMineSettingsFilePathCollection == null)
			{
				RecentQMineSettingsFilePathCollection = new RecentFileCollection();
			}
		}
	}

	protected virtual void OnPropertyChanged(string propertyName)
	{
		PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
		if (propertyChanged != null)
		{
			PropertyChangedEventArgs e = new PropertyChangedEventArgs(propertyName);
			propertyChanged(this, e);
		}
	}

	public MainWindow()
	{
		InitializeComponent();
		LoadMainWindowConfiguration();
		outputLogWindow = new OutputLogWindow();
	}

	private void About_Click(object sender, RoutedEventArgs e)
	{
		About about = new About();
		about.Owner = this;
		about.ShowDialog();
	}

	private void Exit_Click(object sender, RoutedEventArgs e)
	{
		Close();
	}

	private void CommandBinding_RunReport(object sender, ExecutedRoutedEventArgs e)
	{
		WriteQMineStatus("Generating report");
		if (this.OnRunReport != null)
		{
			this.OnRunReport(useSelectedResultPlugins: false);
		}
	}

	private void WriteQMineStatus(string statusText)
	{
		QMineStatusText = statusText;
	}

	private void CommandBinding_OpenPluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		string text = e.Parameter as string;
		CheckUnsavedPluginSettings();
		List<string> list = new List<string>();
		if (string.IsNullOrWhiteSpace(text))
		{
			OpenFilesDialog(list, ".qmine", "QMine plugin settings files (*.qmine)|*.qmine", selectMultipleFiles: false);
		}
		else
		{
			list.Add(text);
		}
		if (list.Count == 1 && this.OnLoadPluginSettings != null)
		{
			this.OnLoadPluginSettings(list[0]);
		}
		UpdateMainWindowTitle();
		if (list.Count == 1)
		{
			WriteQMineStatus("Loaded plugin settings");
			RecentQMineSettingsFilePathCollection.Add(new RecentFileItem
			{
				FilePath = list[0]
			});
		}
	}

	private void OpenFilesDialog(List<string> filesList, string extension, string filter, bool selectMultipleFiles)
	{
		Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
		openFileDialog.AddExtension = true;
		openFileDialog.DefaultExt = extension;
		openFileDialog.Filter = filter;
		openFileDialog.Multiselect = selectMultipleFiles;
		if (openFileDialog.ShowDialog() == true)
		{
			filesList.AddRange(openFileDialog.FileNames);
		}
	}

	private string SaveFileDialog(string extension, string filter)
	{
		Microsoft.Win32.SaveFileDialog saveFileDialog = new Microsoft.Win32.SaveFileDialog();
		saveFileDialog.AddExtension = true;
		saveFileDialog.DefaultExt = extension;
		saveFileDialog.Filter = filter;
		if (saveFileDialog.ShowDialog() == true)
		{
			return saveFileDialog.FileName;
		}
		return null;
	}

	private void CommandBinding_ClosePluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		CheckUnsavedPluginSettings();
		if (this.OnNewPluginSettings != null)
		{
			this.OnNewPluginSettings();
		}
		UpdateMainWindowTitle();
	}

	private void UpdateMainWindowTitle()
	{
		if (PluginSettingsManager.IsCurrentPluginSettingsModified)
		{
			MainWindowTitle = PluginSettingsManager.CurrentPluginSettings.FilePath + " * ";
		}
		else
		{
			MainWindowTitle = PluginSettingsManager.CurrentPluginSettings.FilePath;
		}
	}

	private void CommandBinding_NewPluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		CheckUnsavedPluginSettings();
		if (this.OnNewPluginSettings != null)
		{
			this.OnNewPluginSettings();
		}
		UpdateMainWindowTitle();
	}

	private void CommandBinding_SavePluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		string text = null;
		text = ((!string.IsNullOrEmpty(PluginSettingsManager.CurrentPluginSettings.FilePath)) ? PluginSettingsManager.CurrentPluginSettings.FilePath : SaveFileDialog(".qmine", "QMine plugin settings files (*.qmine)|*.qmine"));
		if (!string.IsNullOrWhiteSpace(text))
		{
			if (this.OnSavePluginSettings != null)
			{
				this.OnSavePluginSettings(text);
			}
			UpdateMainWindowTitle();
		}
		if (!string.IsNullOrWhiteSpace(text))
		{
			WriteQMineStatus("Saved plugin settings");
			RecentQMineSettingsFilePathCollection.Add(new RecentFileItem
			{
				FilePath = text
			});
		}
	}

	private void CommandBinding_SaveAsPluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		string text = SaveFileDialog(".qmine", "QMine PluginSettings files (*.qmine)|*.qmine");
		if (!string.IsNullOrEmpty(text))
		{
			this.OnSavePluginSettings(text);
		}
		UpdateMainWindowTitle();
		if (!string.IsNullOrWhiteSpace(text))
		{
			WriteQMineStatus("Saved plugin settings");
			RecentQMineSettingsFilePathCollection.Add(new RecentFileItem
			{
				FilePath = text
			});
		}
	}

	private void CommandBinding_ResetPluginSettings(object sender, ExecutedRoutedEventArgs e)
	{
		if (System.Windows.MessageBox.Show("Are you sure you want to reset all plugin settings to their default?", "QMine", MessageBoxButton.YesNoCancel) == MessageBoxResult.Yes)
		{
			if (this.OnResetPluginSettings != null)
			{
				this.OnResetPluginSettings();
			}
			WriteQMineStatus("Reset plugin settings");
		}
	}

	public void StartNewLog()
	{
		OutputLogger.OutputCollection.StartNewLog();
		outputLogWindow.tabControlOutput.SelectedItem = OutputLogger.OutputCollection[OutputLogger.OutputCollection.Count - 1];
	}

	public void WriteLog(string message, LogType logType)
	{
		OutputLogger.OutputCollection.WriteLogMessageToCurrentLog(message);
	}

	private void Window_Loaded(object sender, RoutedEventArgs e)
	{
		outputLogWindow.tabControlOutput.ItemsSource = OutputLogger.OutputCollection;
	}

	private void ResultPluginMinize_Click(object sender, RoutedEventArgs e)
	{
		MinimizeResultPlugin();
	}

	private void MinimizeResultPlugin()
	{
		resultPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Auto);
		queryPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Star);
		resultPluginTabControl.Visibility = Visibility.Collapsed;
		queryPluginTabControl.Visibility = Visibility.Visible;
		pluginGridSplitterRowDefinition.Height = new GridLength(0.0);
	}

	private void MinimizeQueryPlugin()
	{
		queryPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Auto);
		resultPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Star);
		queryPluginTabControl.Visibility = Visibility.Collapsed;
		resultPluginTabControl.Visibility = Visibility.Visible;
		pluginGridSplitterRowDefinition.Height = new GridLength(0.0);
	}

	private void RestoreLayout()
	{
		resultPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Star);
		queryPluginRowDefinition.Height = new GridLength(1.0, GridUnitType.Star);
		resultPluginTabControl.Visibility = Visibility.Visible;
		queryPluginTabControl.Visibility = Visibility.Visible;
		pluginGridSplitterRowDefinition.Height = new GridLength(5.0);
	}

	private void ResultPluginMaximize_Click(object sender, RoutedEventArgs e)
	{
		MinimizeQueryPlugin();
	}

	private void ResultPluginRestore_Click(object sender, RoutedEventArgs e)
	{
		RestoreLayout();
	}

	private void QueryPluginMinimize_Click(object sender, RoutedEventArgs e)
	{
		MinimizeQueryPlugin();
	}

	private void QueryPluginRestore_Click(object sender, RoutedEventArgs e)
	{
		RestoreLayout();
	}

	private void QueryPluginMaximize_Click(object sender, RoutedEventArgs e)
	{
		MinimizeResultPlugin();
	}

	private void CommandBinding_RunSelectedReport(object sender, ExecutedRoutedEventArgs e)
	{
		if (this.OnRunReport != null)
		{
			this.OnRunReport(useSelectedResultPlugins: true);
		}
	}

	private void pluginSettingsManager_OnPluginSettingsModified()
	{
		if (!string.IsNullOrEmpty(PluginSettingsManager.CurrentPluginSettings.FilePath))
		{
			UpdateMainWindowTitle();
		}
	}

	private void KillAll_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.KillProcess("EXCEL");
		CommonFunctions.KillProcess("POWERPNT");
		CommonFunctions.KillProcess("DataMiner");
	}

	private void KillExcel_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.KillProcess("EXCEL");
	}

	private void KillPPT_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.KillProcess("POWERPNT");
	}

	private void KillDataMiner_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.KillProcess("DataMiner");
	}

	private void Help_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.LaunchEmailClient("http://sharepoint/qces/Home/ESS/toolsanddataservices/QMine/Lists/QMineHelp/AllItems.aspx");
	}

	private void Bug_Click(object sender, RoutedEventArgs e)
	{
		CommonFunctions.LaunchEmailClient("mailto:qmine.help@qualcomm.com");
	}

	private void CommandLineHelp_Click(object sender, RoutedEventArgs e)
	{
		if (File.Exists(Constants.CommandLineHelpFilePath))
		{
			Process.Start(Constants.CommandLineHelpFilePath);
		}
		else
		{
			System.Windows.MessageBox.Show("QMine command line help file cannot be found. Please reinstall QMine.");
		}
	}

	private void MainWindow_Closing(object sender, CancelEventArgs e)
	{
		CheckUnsavedPluginSettings();
		if (this.OnMainWindowClosing != null)
		{
			e.Cancel = this.OnMainWindowClosing();
		}
		if (!e.Cancel)
		{
			SaveMainWindowConfiguration();
			outputLogWindow.Exit();
		}
	}

	private void CheckUnsavedPluginSettings()
	{
		if (PluginSettingsManager.IsCurrentPluginSettingsModified && !string.IsNullOrEmpty(PluginSettingsManager.CurrentPluginSettings.FilePath) && System.Windows.MessageBox.Show("Plugin Settings have been modified. Do you want to save them?", "QMine", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
		{
			CommandBinding_SavePluginSettings(null, null);
		}
	}

	private void SavePluginSettingsCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
	{
		if (PluginSettingsManager != null)
		{
			e.CanExecute = PluginSettingsManager.IsCurrentPluginSettingsModified;
		}
		else
		{
			e.CanExecute = false;
		}
	}

	private void CommandBinding_ChangeDatabase(object sender, ExecutedRoutedEventArgs e)
	{
		DatabaseOptions databaseOptions = new DatabaseOptions();
		databaseOptions.ServerName = QMineGlobalInformation.ServerName;
		databaseOptions.DatabaseName = QMineGlobalInformation.DatabaseName;
		if (System.Windows.Forms.DialogResult.OK != databaseOptions.ShowDialog())
		{
			return;
		}
		try
		{
			QMineGlobalInformation.ServerName = databaseOptions.ServerName;
			QMineGlobalInformation.DatabaseName = databaseOptions.DatabaseName;
			QMineGlobalInformation.ServerDescription = databaseOptions.ServerDescription;
			QMineGlobalInformation.DatabaseDescription = databaseOptions.DatabaseDescription;
			if (this.OnDatabaseChanged != null)
			{
				this.OnDatabaseChanged();
			}
			OnPropertyChanged("ServerName");
			OnPropertyChanged("DatabaseName");
			OnPropertyChanged("ServerDescription");
			OnPropertyChanged("DatabaseDescription");
		}
		catch (Exception ex)
		{
			System.Windows.MessageBox.Show("There was an issue connecting to the database: " + ex.Message);
		}
	}

	private void OpenOutputLogButton_Click(object sender, RoutedEventArgs e)
	{
		outputLogWindow.Owner = this;
		outputLogWindow.ShowDialog();
	}
}
