using System;
using Pixiview.UI.Theme;
using Pixiview.Utils;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Pixiview.UI
{
    public class AdaptedPage : ContentPage
    {
        public static readonly BindableProperty PageTopMarginProperty = BindableProperty.Create(
            nameof(PageTopMargin), typeof(Thickness), typeof(AdaptedPage));

        public Thickness PageTopMargin
        {
            get => (Thickness)GetValue(PageTopMarginProperty);
            protected set => SetValue(PageTopMarginProperty, value);
        }
        public Orientation CurrentOrientation { get; private set; }

        public event EventHandler Load;
        public event EventHandler Unload;
        public event EventHandler<OrientationEventArgs> OrientationChanged;

        protected readonly bool isPhone = DeviceInfo.Idiom == DeviceIdiom.Phone;

        public AdaptedPage()
        {
            SetDynamicResource(Screen.StatusBarStyleProperty, ThemeBase.StatusBarStyle);
            Shell.SetNavBarHasShadow(this, true);
        }

        public virtual void OnLoad()
        {
            Load?.Invoke(this, EventArgs.Empty);
        }

        public virtual void OnUnload()
        {
            Unload?.Invoke(this, EventArgs.Empty);
        }

        public virtual void OnOrientationChanged(Orientation orientation)
        {
            switch (orientation)
            {
                case Orientation.Portrait:
                    PageTopMargin = AppShell.TotalBarOffset;
                    break;
                case Orientation.PortraitUpsideDown:
                    PageTopMargin = isPhone ? AppShell.NavigationBarOffset : AppShell.TotalBarOffset;
                    break;
                case Orientation.Unknown:
                case Orientation.LandscapeLeft:
                case Orientation.LandscapeRight:
                default:
                    PageTopMargin = AppShell.NavigationBarOffset;
                    break;
            }
            OrientationChanged?.Invoke(this, new OrientationEventArgs { CurrentOrientation = orientation });
        }

        public void InitOrientation(Orientation orientation)
        {
            CurrentOrientation = orientation;
        }

        protected void Start(Action action)
        {
            if (Tap.IsBusy)
            {
                App.DebugPrint("gesture recognizer is now busy...");
                return;
            }
            using (Tap.Start())
            {
                action();
            }
        }

        private class Tap : IDisposable
        {
            public static bool IsBusy => _instance?.isBusy == true;

            private static readonly object sync = new object();
            private static Tap _instance;

            private Tap() { }

            public static Tap Start()
            {
                if (_instance == null)
                {
                    _instance = new Tap();
                }
                lock (sync)
                {
                    _instance.isBusy = true;
                }
                return _instance;
            }

            private bool isBusy = false;

            public void Dispose()
            {
                lock (sync)
                {
                    isBusy = false;
                }
            }
        }
    }

    public class OrientationEventArgs : EventArgs
    {
        public Orientation CurrentOrientation { get; set; }
    }

    public enum Orientation
    {
        Unknown,
        Portrait,
        PortraitUpsideDown,
        LandscapeLeft,
        LandscapeRight
    }
}
