using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace InABox.Mobile
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MobilePageStack
    {
        public IList<MobilePageStackItem> Items { get; private set; }
        
        public static readonly BindableProperty SelectedIndexProperty = BindableProperty.Create(
            nameof(SelectedIndex),
            typeof(int),
            typeof(MobilePageStack),
            -1,
            propertyChanged:SelectedIndexChanged);

        private static void SelectedIndexChanged(BindableObject bindable, object oldvalue, object newvalue)
        {
            (bindable as MobilePageStack)?.SelectPage((int)newvalue);
        }

        public void SelectPage(int page)
        {
            SelectPage((page > -1) && (page < Items.Count) ? Items[page] : null);
        }

        private MobilePageStackItem _current = null;
        public void SelectPage([CanBeNull] MobilePageStackItem page)
        {
            if (_current != null)
                _current.DoDisappearing();
            _current = page;
            Content = _current?.Content;
            _current?.DoAppearing();
            SelectionChanged?.Invoke(this, EventArgs.Empty);
        }
        
        public int SelectedIndex
        {
            get => (int)GetValue(SelectedIndexProperty);
            set => SetValue(SelectedIndexProperty, value);
        }
        
        public static readonly BindableProperty SelectedItemProperty = BindableProperty.Create(
            nameof(SelectedItem),
            typeof(MobilePageStackItem),
            typeof(MobilePageStack),
            propertyChanged:SelectedItemChanged);

        private static void SelectedItemChanged(BindableObject bindable, object oldvalue, object newvalue)
        {
            (bindable as MobilePageStack)?.SelectPage(newvalue as MobilePageStackItem);
        }
        
        public MobilePageStackItem SelectedItem 
        {
            get => GetValue(SelectedItemProperty) as MobilePageStackItem;
            set => SetValue(SelectedItemProperty, value);
        }
        
        public event EventHandler SelectionChanged;

        public void DoSelectionChanged()
        {
            SelectionChanged?.Invoke(this, EventArgs.Empty);
        }

        public MobilePageStack()
        {
            var items = new ObservableCollection<MobilePageStackItem>();
            items.CollectionChanged += ItemsChanged;
            Items = items;
            InitializeComponent();
        }

        private void ItemsChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                SelectedItem ??= Items.FirstOrDefault();
            });
        }
    }
}