using System;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Windows;
using Microsoft.Win32;
using static EdecBeispielClient.Properties.Settings;

namespace EdecBeispielClient
{
    public partial class MainWindow : Window
    {
        const string XmlOpenFileDialogTitle = "Select XMl file";
        const string XmlSaveFileDialogTitle = "Save soap response as";
        const string XmlFileDialogDefaultExt = ".xml";
        const string XmlFileDialogFilter = "Xml Files|*.xml|All Files|*.*";
        const string CertOpenFileDialogTitle = "Select certificate";
        const string CertOpenFileDialogDefaultExt = ".pem";
        const string CertOpenFileDialogFilter = "Certificates|*.pem;*.p12|All Files|*.*";

        static readonly string[] DefaultSoapActions =
        {
            "goodsDeclarations",
            "selectionAndTransit",
            "receiptRequest"
        };

        public MainWindow()
        {
            InitializeComponent();

            // Load settings and fill the wpf components
            InitializeWpfComponents();

            // Save paths on closing
            Closing += (s, e) => SaveSettings();
        }


        // Events

        private void SelectSoapEnvelopePath(object sender, RoutedEventArgs e)
        {
            var openFileDialog = GetXmlOpenFileDialog();

            if (openFileDialog.ShowDialog() == true) // ShowDialog returns Nullable<bool>
            {
                soapEnvBox.Text = openFileDialog.FileName;
                UpdateStatusBar("Soap envelope changed");
            }
        }

        private void SelectCertificatePath(object sender, RoutedEventArgs e)
        {
            var openFileDialog = GetCertOpenFileDialog();

            if (openFileDialog.ShowDialog() == true) // ShowDialog returns Nullable<bool>
            {
                certBox.Text = openFileDialog.FileName;
                UpdateStatusBar("Certificate changed");
            }
        }

        private void SendRequest(object sender, RoutedEventArgs e)
        {
            var fileName = soapEnvBox.Text;
            var endpoint = endpointComboBox.Text;
            var certificateLocation = certBox.Text;

            try
            {
                if (!File.Exists(fileName))
                    throw new Exception("Soap envelope not found");

                if (!File.Exists(certificateLocation))
                    throw new Exception("Certificate file not found");

                using (var cert = new X509Certificate2(certificateLocation, pwBox.Password))
                {
                    var edecRequest = new SoapRequest(endpoint, fileName, cert);
                    responseOutputTextBox.Text = edecRequest.Request();
                    UpdateStatusBar("Soap request sent");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Request failed", MessageBoxButton.OK, MessageBoxImage.Warning);
            }
        }

        private void CopyResponseToClipboard(object sender, RoutedEventArgs e)
        {
            var response = responseOutputTextBox.Text;

            if (string.IsNullOrWhiteSpace(response))
            {
                System.Media.SystemSounds.Exclamation.Play();
                UpdateStatusBar("Cannot copy empty response. Send a request");
            }
            else
            {
                System.Windows.Forms.Clipboard.SetText(response);
                UpdateStatusBar($"Copied soap response to clipboard ({response.Length} characters)");
            }
        }

        private void SaveResponseToFile(object sender, RoutedEventArgs e)
        {
            var saveFileDialog = GetXmlSaveFileDialog();

            if (saveFileDialog.ShowDialog() == true) // ShowDialog returns Nullable<bool>
            {
                File.WriteAllText(saveFileDialog.FileName, responseOutputTextBox.Text);
                UpdateStatusBar($"Soap response saved to {saveFileDialog.FileName}");
            }
        }


        // Utility functions

        private void InitializeWpfComponents()
        {
            soapEnvBox.Text = Default.fileToSend;
            endpointComboBox.Text = Default.edecEndpoint;
            
            certBox.Text = File.Exists(Default.certificateLocation)
                ? Default.certificateLocation
                : "";
        }

        private void SaveSettings()
        {
            Default.fileToSend = soapEnvBox.Text;
            Default.edecEndpoint = endpointComboBox.Text;
            Default.certificateLocation = certBox.Text;
            Default.Save();
        }

        private void UpdateStatusBar(string text = "")
        {
            statusBarTextBlock.Text = text;
        }

        private OpenFileDialog GetXmlOpenFileDialog()
        {
            return new OpenFileDialog
            {
                Title = XmlOpenFileDialogTitle,
                DefaultExt = XmlFileDialogDefaultExt,
                InitialDirectory = string.IsNullOrWhiteSpace(soapEnvBox.Text)
                    ? null
                    : Path.GetDirectoryName(soapEnvBox.Text),
                Filter = XmlFileDialogFilter
            };
        }

        private OpenFileDialog GetCertOpenFileDialog()
        {
            return new OpenFileDialog
            {
                Title = CertOpenFileDialogTitle,
                InitialDirectory = string.IsNullOrWhiteSpace(certBox.Text)
                    ? null
                    : Path.GetDirectoryName(certBox.Text),
                DefaultExt = CertOpenFileDialogDefaultExt,
                Filter = CertOpenFileDialogFilter
            };
        }

        private SaveFileDialog GetXmlSaveFileDialog()
        {
            return new SaveFileDialog
            {
                Title = XmlSaveFileDialogTitle,
                DefaultExt = XmlFileDialogDefaultExt,
                Filter = XmlFileDialogFilter
            };
        }
    }
}
