using IdentityModel.OidcClient.Browser;
using Microsoft.Web.WebView2.WinForms;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AudioWallpaper.SSO {

    public class WebView2Browser : IBrowser {
        private readonly int _windowWidth;
        private readonly int _windowHeight;
        private readonly Form? _form;
        public WebView2Browser(int width = 600, int height = 800) {
            _windowWidth = width;
            _windowHeight = height;
        }
        public WebView2Browser(Form form, int width = 600, int height = 800) {
            _windowWidth = width;
            _windowHeight = height;
            _form = form;
        }
        public WebView2Browser(Form form) {
            _windowWidth = 600;
            _windowHeight = 800;
            _form = form;
        }


        public Task<BrowserResult> InvokeAsync(BrowserOptions options, CancellationToken cancellationToken = default) {
            var tcs = new TaskCompletionSource<BrowserResult>();

            var thread = new Thread(() => {
                var form = new Form {
                    Width = _windowWidth,
                    Height = _windowHeight,
                    StartPosition = FormStartPosition.CenterScreen,
                    Text = "登录认证"
                };

                var webView = new WebView2 {
                    Dock = DockStyle.Fill
                };

                form.Controls.Add(webView);

                form.FormClosed += (s, e) => {
                    if (!tcs.Task.IsCompleted) {
                        tcs.TrySetResult(new BrowserResult {
                            ResultType = BrowserResultType.UserCancel,
                            Error = "User closed the login window"
                        });
                    }
                };

                webView.NavigationStarting += (s, e) => {
                    if (e.Uri.StartsWith(options.EndUrl)) {
                        tcs.TrySetResult(new BrowserResult {
                            ResultType = BrowserResultType.Success,
                            Response = e.Uri
                        });
                        form.Invoke(new Action(() => form.Close()));
                    }
                };

                webView.CoreWebView2InitializationCompleted += async (s, e) => {
                    if (e.IsSuccess) {
                        webView.CoreWebView2.Settings.AreDevToolsEnabled = false;
                        webView.CoreWebView2.ContextMenuRequested += (s, e) => {
                            e.Handled = true;
                        };
                        webView.CoreWebView2.Navigate(options.StartUrl);
                    } else {
                        tcs.TrySetResult(new BrowserResult {
                            ResultType = BrowserResultType.UnknownError,
                            Error = "WebView2 initialization failed"
                        });
                        form.Close();
                    }
                };

                form.Load += async (s, e) => {
                    await webView.EnsureCoreWebView2Async(null);
                };
                if (_form != null) {
                    _form.Invoke(new Action(() => {
                        form.ShowDialog(_form);
                    }));
                } else {
                    Application.Run(form);
                }
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();

            return tcs.Task;
        }
    }

}
