using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows;
using static FSI.BT.Tools.Global.Settings.Cmd;
using static FSI.BT.Tools.Global.Settings.Exe;

namespace FSI.BT.Tools.Global.Commands
{
    /// <summary>
    /// Shows the main window.
    /// </summary>
    public class CmdCommand : CommandBase<CmdCommand>
    {
        public override void Execute(object parameter)
        {
            if (parameter is not string)
            {
                Global.Vars.Log.Error("Parameter ist kein String");
                return;
            }

            var cmds = Vars.GlobalSettings.Cmds.ToList();
            ICmd selectedCmd = null;



            switch ((string)parameter)
            {

                case "DarkMode":
                    RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", true);

                    if (key.GetValue("AppsUseLightTheme") != null)
                    {
                        if (Convert.ToInt32(key.GetValue("AppsUseLightTheme")) == 0)
                            key.SetValue("AppsUseLightTheme", 1); //sets 'someData' in 'someValue' 
                        else
                            key.SetValue("AppsUseLightTheme", 0); //sets 'someData' in 'someValue' 
                        key.Close();
                    }

                    return;


                case "Epl.Prj":
                    Lib.Guis.Prj.Mgt.FrmMain frmMainEplPrj = new()
                    {
                        ShowPdf = false,
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterScreen,
                        Path = Helpers.GetFolderByName.Get(Vars.GlobalSettings.Folders, "EplPrj").path,
                        EplExe = GetExeByCmdName("Epl").ExePath,
                    };
                    frmMainEplPrj.Show();
                    return;

                case "Epl.Pdf":
                    Lib.Guis.Prj.Mgt.FrmMain frmMainEplPdf = new()
                    {
                        ShowPdf = true,
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterScreen,
                        Path = Helpers.GetFolderByName.Get(Vars.GlobalSettings.Folders, "EplPdf").path
                    };
                    frmMainEplPdf.Show();
                    return;

                case "Epl.PdfMgt":
                    Lib.Guis.Pdf.Mgt.FrmMain frmMainEplPdfMgt = new()
                    {
                        CloseAtLostFocus = true
                    };
                    frmMainEplPdfMgt.Show();
                    return;

                case "DeEncrypt":
                    Lib.Guis.DeEncryptMessage.FrmMain frmMainDeEnCrypt = new()
                    {
                        Password = AppDomain.CurrentDomain.FriendlyName,
                        CloseAtLostFocus = true,
                        WindowStartupLocation = WindowStartupLocation.CenterScreen,
                    };
                    frmMainDeEnCrypt.Show();
                    return;

                case "StarterCsvExporter":
                    Lib.Guis.SieStarterCsvExporter.FrmMain frmMain = new();
                    frmMain.Show();
                    return;

                case "Folder":
                    Lib.Guis.Folder.Mgt.FrmMain frmFolderMgtMain = new()
                    {
                        CloseAtLostFocus = true,
                        Data = Global.Vars.GlobalSettings.Folders
                    };
                    frmFolderMgtMain.Show();
                    return;

                //case "TxtToClip":
                //    Lib.Guis.TxtToClip.Mgt.FrmMain frmTxtToClipMain = new()
                //    {
                //        CloseAtLostFocus = true,
                //        InputData = Global.AppSettings.TxtToClip
                //    };
                //    frmTxtToClipMain.Show();
                //    return;

                case "Rdp.Mgt":
                    Lib.Guis.Rdp.Mgt.FrmMain frmRdpMain = new()
                    {
                        CloseAtLostFocus = true,
                        InputData = Global.Vars.GlobalSettings.Rdps,
                        Exe = GetExeByCmdName("Rdp").ExePath,
                        FrmTitle = "Remotedesktopverbindungen",
                    };
                    frmRdpMain.Show();
                    break;

                case "WebRadio":
                    //Lib.Guis.WebRadio.FrmMain frmWebRadio = new()
                    //{
                    //    CloseAtLostFocus = false,
                    //    InputData = Global.AppSettings.WebRadioUrls,
                    //};
                    //frmWebRadio.Show();
                    break;

                default:
                    foreach (ICmd cmd in cmds)
                    {
                        if (String.Equals(parameter.ToString(), cmd.Cmd))
                            selectedCmd = cmd;
                    }
                    break;
            }

            if (selectedCmd == null)
                return;

            OpenExe(selectedCmd);
            OpenUrl(selectedCmd);
        }

        public override bool CanExecute(object parameter)
        {
            if (parameter == null)
                return false;

            var cmds = Global.Vars.GlobalSettings.Cmds.ToList();
            ICmd selectedCmd = null;

            switch ((string)parameter)
            {
                case "DarkMode":
                    return Vars.AdminRights;

                case "Epl.Prj":
                    return true;

                case "Epl.Pdf":
                    return true;

                case "Epl.PdfMgt":
                    return Vars.AdminRights;

                case "DeEncrypt":
                    return Vars.AdminRights;

                case "StarterCsvExporter":
                    return Vars.AdminRights;

                case "Folder":
                    return Vars.GlobalSettings.Folders != null;

                //case "TxtToClip":
                //    return Vars.GlobalSettings.TxtToClip != null;

                case "Rdp.Mgt":
                    return Vars.GlobalSettings.Rdps != null;

                case "WebRadio":
                    return false;// Global.AppSettings.WebRadioUrls != null;

                default:
                    foreach (ICmd cmd in cmds)
                    {
                        if (String.Equals(parameter.ToString(), cmd.Cmd))
                            selectedCmd = cmd;
                    }
                    break;
            }

            if (selectedCmd == null)
                return false;

            foreach (var file in selectedCmd.Exe.ToList())
            {

                if (File.Exists(Environment.ExpandEnvironmentVariables(file.ExePath.Trim())))
                    return true;
                else if (File.Exists(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), file.ExePath.Trim())))
                    return true;
            }

            foreach (var url in selectedCmd.Urls)
            {
                if (url != String.Empty)
                    return true;
            }

            return false;
        }

        private static void OpenExe(ICmd selectedCmd)
        {
            IExe selectedFile = GetApp(selectedCmd.Exe);

            if (selectedFile == null)
                return;

            if (selectedFile.ExePath == String.Empty)
                return;

            if (ProgramIsRunning(selectedFile.ExePath))
            {
                ProgramToFront(selectedFile.ExePath);
                Vars.Log.Info("Anwendung \"{0}\" wurde in den Vordergrund gebracht", selectedFile.ExePath);
            }
            else
            {
                var selectedFileExePath = string.Empty;
                if (File.Exists(Environment.ExpandEnvironmentVariables(selectedFile.ExePath.Trim())))
                    selectedFileExePath = Environment.ExpandEnvironmentVariables(selectedFile.ExePath.Trim());
                if (File.Exists(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), selectedFile.ExePath.Trim())))
                    selectedFileExePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), selectedFile.ExePath.Trim());

                var abc = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), selectedFileExePath.Trim());
                Process process = new();
                process.StartInfo.FileName = selectedFileExePath;
                process.StartInfo.WorkingDirectory = selectedFile.Path ?? Path.GetDirectoryName(selectedFileExePath);
                process.StartInfo.Arguments = selectedFile.Arguments ?? string.Empty;

                try
                {

                    process.Start();
                    Vars.Log.Info("Anwendung \"{0}\" wurde gestartet", selectedFile.ExePath);
                }
                catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 740)
                {
                    try
                    {
                        process.StartInfo.UseShellExecute = true;
                        process.StartInfo.Verb = "runas";
                        process.Start();
                        Vars.Log.Info("Anwendung \"{0}\" wurde als Admin gestartet", selectedFile.ExePath);
                    }
                    catch (Exception ex2)
                    {
                        Vars.Log.Info("Anwendung konnte durch folgenden Fehler \"{0}\" nicht gestartet werden.", ex2.Message);
                    }
                }
            }
        }

        private static void OpenUrl(ICmd selectedCmd)
        {

            foreach (var url in selectedCmd.Urls)
            {

                if (url == String.Empty)
                    return;

                Process.Start(new ProcessStartInfo(url.Replace("&", "^&")) { UseShellExecute = true });
                Vars.Log.Info("Link \"{0}\" wurde geföffnet.", url.Replace("&", "^&"));
                Thread.Sleep(100);
            }
        }

        private static IExe GetExeByCmdName(string cmdName)
        {
            foreach (var cmd in Vars.GlobalSettings.Cmds)
            {
                if (string.Equals(cmd.Cmd, cmdName, StringComparison.InvariantCultureIgnoreCase))
                    return GetApp(cmd.Exe);
            }

            return null;
        }

        private static bool ProgramIsRunning(string FullPath)
        {
            string FilePath = Path.GetDirectoryName(FullPath);
            string FileName = Path.GetFileNameWithoutExtension(FullPath).ToLower();
            bool isRunning = false;

            Process[] pList = Process.GetProcessesByName(FileName);

            foreach (Process p in pList)
            {
                if (p.MainModule.FileName.StartsWith(FilePath, StringComparison.InvariantCultureIgnoreCase))
                {
                    isRunning = true;
                    break;
                }
            }

            return isRunning;
        }

        private static IExe GetApp(IEnumerable<IExe> files)
        {
            if (files.ToList().Count == 0)
                return null;

            var selectedFile = files.ToList()[0];

            foreach (var file in files.ToList())
            {
                if (File.Exists(Environment.ExpandEnvironmentVariables(file.ExePath.Trim())))
                    selectedFile = (IExe)file;
                else
                    continue;
            }

            return selectedFile;
        }

        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool SetForegroundWindow(IntPtr handle);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool ShowWindow(IntPtr handle, int nCmdShow);
        [System.Runtime.InteropServices.DllImport("User32.dll")]
        private static extern bool IsIconic(IntPtr handle);

        private static void ProgramToFront(string FullPath)
        {
            string FilePath = Path.GetDirectoryName(FullPath);
            string FileName = Path.GetFileNameWithoutExtension(FullPath).ToLower();

            Process[] pList = Process.GetProcessesByName(FileName);

            foreach (Process p in pList)
            {
                if (p.MainModule.FileName.StartsWith(FilePath, StringComparison.InvariantCultureIgnoreCase))
                {
                    IntPtr handle = p.MainWindowHandle;
                    if (IsIconic(handle))
                        ShowWindow(handle, 9);

                    SetForegroundWindow(handle);
                    break;
                }
            }
        }
    }
}