using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;
using QC.QMine.Core;
using QC.QMine.QMineInterface;

namespace QC.QMine;

public class App : Application
{
	private QMineCore appCore = new QMineCore();

	private MainWindow mainWindow;

	public static QMineSecurityConfiguration SecurityConfig
	{
		get
		{
			return QMineCore.SecurityConfig;
		}
		set
		{
			QMineCore.SecurityConfig = value;
		}
	}

	private void Application_Startup(object sender, StartupEventArgs e)
	{
		CommonFunctions.CreateQMineDirectories();
		appCore.OnQueryPluginWriteStatus += QueryPluginWriteStatus;
		appCore.OnResultPluginWriteStatus += ResultPluginWriteStatus;
		appCore.OnShowMessage += ShowMessage;
		appCore.LoadQMineConfiguration();
		if (e.Args.Length == 1)
		{
			if (e.Args[0].Contains(".config"))
			{
				appCore.LoadPluginSettingsFromConfigFile(e.Args[0]);
			}
		}
		else
		{
			appCore.LoadPluginSettingsFromConfigFile();
		}
		appCore.LoadPlugins();
		appCore.InitializePlugins();
		appCore.SubscribeToPluginMessages();
		LoadMainWindow();
		appCore.LoadPluginConfigurations();
		appCore.SetResultPluginToProcessQueryMessage();
		CommonFunctions.CleanupTemporaryFolder();
	}

	private void QueryPluginWriteStatus(string message)
	{
		mainWindow.QueryPluginStatusText = message;
	}

	private void ResultPluginWriteStatus(string message)
	{
		mainWindow.ResultPluginStatusText = message;
	}

	private void ShowMessage(string message, string senderName = "")
	{
		MessageBox.Show(message, senderName);
	}

	private void LoadMainWindow()
	{
		mainWindow = new MainWindow();
		Constants.MainWindow = mainWindow;
		InitializeMainWindowWithPlugins();
		mainWindow.OnRunReport += mainWindow_OnRunReport;
		mainWindow.OnLoadPluginSettings += mainWindow_OnLoadPluginSettings;
		mainWindow.OnNewPluginSettings += mainWindow_OnNewPluginSettings;
		mainWindow.OnResetPluginSettings += mainWindow_OnResetPluginSettings;
		mainWindow.OnSavePluginSettings += mainWindow_OnSavePluginSettings;
		mainWindow.PluginSettingsManager = appCore.PluginSettingsMgr;
		mainWindow.OnMainWindowClosing += mainWindow_OnClosing;
		mainWindow.OnDatabaseChanged += mainWindow_OnDatabaseChanged;
		mainWindow.Show();
		appCore.Logger = mainWindow;
	}

	private void mainWindow_OnDatabaseChanged()
	{
		appCore.SendMessageToAllQueryPlugins(QMineMessageType.DatabaseChanged);
		appCore.SendMessageToAllResultPlugins(QMineMessageType.DatabaseChanged);
	}

	private bool mainWindow_OnClosing()
	{
		bool result = false;
		appCore.SendClosePluginMessage();
		appCore.SavePluginConfigurations();
		SaveCurrentPluginSettings();
		appCore.SaveQMineConfiguration();
		return result;
	}

	private void mainWindow_OnSavePluginSettings(string filePath)
	{
		appCore.SavePluginConfigurations();
		appCore.PluginSettingsMgr.SaveCurrentPluginSettings(filePath);
		ShowMessage("Plugin settings have been saved to " + appCore.PluginSettingsMgr.CurrentPluginSettings.FilePath, "QMine");
	}

	private void mainWindow_OnResetPluginSettings()
	{
		appCore.PluginSettingsMgr.ResetCurrentPluginSettings();
		appCore.ResetPluginConfigurations();
	}

	private void mainWindow_OnNewPluginSettings()
	{
		appCore.PluginSettingsMgr.CreateNewPluginSettings();
		appCore.ResetPluginConfigurations();
	}

	private void mainWindow_OnLoadPluginSettings(string filePath)
	{
		appCore.PluginSettingsMgr.LoadPluginSettings(filePath);
		appCore.LoadPluginConfigurations();
	}

	private void InitializeMainWindowWithPlugins()
	{
		appCore.QueryPluginColl.ForEach(delegate(QueryPlugin queryPlugin)
		{
			mainWindow.QueryPluginList.Add(queryPlugin);
		});
		appCore.ResultsPluginColl.ForEach(delegate(ResultsPlugin resultPlugin)
		{
			mainWindow.ResultsPluginList.Add(resultPlugin);
		});
	}

	private void mainWindow_OnRunReport(bool useSelectedResultPlugins)
	{
		appCore.RunReport();
	}

	private IEnumerable<ResultsPlugin> GetSelectedResultPlugins(bool useSelectedResultPlugins)
	{
		if (useSelectedResultPlugins)
		{
			return appCore.ResultsPluginColl.FindAll((ResultsPlugin resultPlugin) => resultPlugin.CanProcessMessages);
		}
		ResultsPlugin item = appCore.ResultsPluginColl.Find((ResultsPlugin rp) => rp.IsSelected);
		List<ResultsPlugin> list = new List<ResultsPlugin>();
		list.Add(item);
		return list;
	}

	private void SaveCurrentPluginSettings()
	{
		appCore.PluginSettingsMgr.SaveCurrentPluginSettings(Constants.PluginSettingsMainConfigPath);
	}

	private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
	{
		ShowMessage("An unknown error has occurred. Please close current QMine30 and launch new QMine30 to generate report again." + Environment.NewLine + ExceptionToString(e.Exception));
		e.Handled = true;
	}

	private string ExceptionToString(Exception ex)
	{
		if (ex != null)
		{
			return ex.Message + Environment.NewLine + ExceptionToString(ex.InnerException);
		}
		return "";
	}

	private void WriteQMineStatus(string message)
	{
		if (Constants.QMineMode == QMineModes.GUI && mainWindow != null)
		{
			mainWindow.QMineStatusText = message;
		}
	}

	[DebuggerNonUserCode]
	[GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
	public void InitializeComponent()
	{
		base.Startup += Application_Startup;
		base.DispatcherUnhandledException += Application_DispatcherUnhandledException;
	}

	[GeneratedCode("PresentationBuildTasks", "4.0.0.0")]
	[DebuggerNonUserCode]
	[STAThread]
	public static void Main()
	{
		App app = new App();
		app.InitializeComponent();
		app.Run();
	}
}
