using System;
using Syncfusion.XForms.PopupLayout;
using Xamarin.CommunityToolkit.Extensions;
using Xamarin.Forms;

namespace InABox.Mobile
{
    public abstract class MobileView<TViewModel> : BaseMobileView 
        where TViewModel : class, IMobileViewModel
    {
        private static readonly BindableProperty ViewModelProperty =
            BindableProperty.Create(
                nameof(ViewModel), 
                typeof(TViewModel), 
                typeof(MobileView<TViewModel>), 
                null
            );
        
        public TViewModel ViewModel
        {
            get => (TViewModel)GetValue(ViewModelProperty);
            set
            {
                if (ViewModel != null)
                    ViewModel.Loaded -= ViewModel_OnLoaded;
                
                SetValue(ViewModelProperty,value);                
                
                if (ViewModel != null)
                    ViewModel.Loaded += ViewModel_OnLoaded;
            }
        }

        private bool _loaded = false;
        
        protected override void DoBindingContextChanged()
        {
            ViewModel = BindingContext as TViewModel;
            Refresh();
            _loaded = ViewModel != null;
        }
        
        public void RefreshBindings()
        {
            var model = ViewModel;
            BindingContext = null;
            BindingContext = model;
        }
        
        private void ViewModel_OnLoaded(object sender, MobileViewModelLoadedEventArgs args)
        {
            Refresh();
        }

        public abstract void Refresh();
        
        public event MobileViewChangedEvent Changed;

        protected void DoChanged(params string[] properties)
        {
            if (_loaded)
                Changed?.Invoke(this, new MobileViewChangedEventArgs(String.Join('.',properties)));
        }
        
        protected void ShowPopup(Func<View> view, PopupManagerConfiguration config = null) 
            => PopupManager.ShowPopup(this, view, config);
        
        protected void DismissPopup() 
            => PopupManager.DismissPopup();
        
    }
}