using CloudBuilder.Gui.DependencyInjection;
using CloudBuilder.Gui.Policy;
using DocumentFormat.OpenXml.Vml.Spreadsheet;
using Krypton.Toolkit;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace CloudBuilder.Gui
{
    public class ShowMessageBox
    {
        public static void ShowError(string msg, string caption)
        {
            ShowCore(msg, caption, KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowError(string msg)
        {
            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_ERROR), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowError(Exception ex)
        {
            string msg = ex.Message;
            if (ex.InnerException != null) msg += "\r\n" + ex.InnerException.Message;

            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_ERROR), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowError(Exception ex, string caption)
        {
            string msg = ex.Message;
            if (ex.InnerException != null) msg += "\r\n" + ex.InnerException.Message;

            ShowCore(msg, caption, KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Error, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowInfo(ValidationException validation)
        {
            string msg = validation.Message;

            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowInfo(string msg, Control ct)
        {
            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);

            if (ct != null) ct.Focus();
        }

        public static void ShowInfo(string msg)
        {
            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static void ShowInfo(string msg, string caption)
        {
            ShowCore(msg, GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION), KryptonMessageBoxButtons.OK, KryptonMessageBoxIcon.Information, KryptonMessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static DialogResult ShowOption(string msg, string caption, KryptonMessageBoxButtons buttons, KryptonMessageBoxIcon icon, KryptonMessageBoxDefaultButton defaultButton)
        {
            if (string.IsNullOrEmpty(caption)) caption = GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION);

            return ShowCore(msg, caption, buttons, icon, defaultButton, MessageBoxOptions.DefaultDesktopOnly);
        }

        public static DialogResult ShowOption(string msg, string caption)
        {
            if (string.IsNullOrEmpty(caption)) caption = GeneralToolkitStringsPolicy.GetInstance().ComposeMessage(GeneralToolkitStringsPolicy.GUI_CAPTION_INFORMATION);

            return ShowCore(msg, caption, KryptonMessageBoxButtons.YesNo, KryptonMessageBoxIcon.Question, KryptonMessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
        }


        private static DialogResult ShowCore(string text, string caption, KryptonMessageBoxButtons buttons, KryptonMessageBoxIcon icon, KryptonMessageBoxDefaultButton defaultButton, MessageBoxOptions options, HelpInfo? helpInfo = null!, bool? showCtrlCopy = false, bool? showHelpButton = false, bool? showActionButton = false, string? actionButtonText = null!, KryptonCommand? actionButtonCommand = null!, Image? applicationImage = null!, string? applicationPath = null!, MessageBoxContentAreaType? contentAreaType = null!, KryptonCommand? linkLabelCommand = null!, ProcessStartInfo? linkLaunchArgument = null!, LinkArea? contentLinkArea = null!)
        {
            IWin32Window? owner = null!;
            caption = (string.IsNullOrEmpty(caption) ? " " : caption);
            IWin32Window win32Window = ValidateOptions(owner, options, helpInfo);
            using KryptonMessageBoxForm kryptonMessageBoxForm = new KryptonMessageBoxForm(win32Window, text, caption, buttons, icon, defaultButton, options, helpInfo, showCtrlCopy, showHelpButton, showActionButton, actionButtonText, actionButtonCommand, applicationImage, applicationPath, contentAreaType, linkLabelCommand, linkLaunchArgument, contentLinkArea);
            kryptonMessageBoxForm.StartPosition = ((win32Window == null) ? FormStartPosition.CenterScreen : FormStartPosition.CenterParent);
            return kryptonMessageBoxForm.ShowDialog(win32Window);
        }

        private static IWin32Window? ValidateOptions(IWin32Window? owner, MessageBoxOptions options, HelpInfo? helpInfo)
        {
            if (!SystemInformation.UserInteractive && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) == 0)
            {
                throw new InvalidOperationException("Cannot show modal dialog when non-interactive");
            }

            if (owner != null && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != 0)
            {
                throw new ArgumentException("Cannot show message box from a service with an owner specified", "options");
            }

            if (helpInfo != null && (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) != 0)
            {
                throw new ArgumentException("Cannot show message box from a service with help specified", "options");
            }

            IWin32Window result = null;
            if (helpInfo != null || (options & (MessageBoxOptions.ServiceNotification | MessageBoxOptions.DefaultDesktopOnly)) == 0)
            {
                result = owner ?? Control.FromHandle(GetActiveWindow());
            }

            return result;
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        [DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
        internal static extern nint GetActiveWindow();
    }
}
