﻿using System;
using System.ComponentModel;
using Xamarin.Codebase.iOS.ViewControllers.Views;
using Foundation;
using UIKit;
using Xamarin.Codebase.UIController.Models.Base;

namespace Xamarin.Codebase.iOS.ViewControllers.Base
{
    public abstract class UITableViewControllerBase<TViewModel> : UITableViewControllerBase
        where TViewModel : ViewModelBase
    {
        #region Fields

        private TViewModel _viewModel;

        #endregion

        #region Properties

        public TViewModel ViewModel
        {
            get { return _viewModel; }
            set
            {
                if (_viewModel == value) return;
                OnModelChanging();
                _viewModel = value;
                OnModelChanged();
            }
        }

        /// <summary>
        /// Defines a loading overlay view.
        /// </summary>
        protected LoadingOverlay LoadingOverlay { get; private set; }

        #endregion

        #region Constructors

        protected UITableViewControllerBase()
            : base()
        {
        }

        protected UITableViewControllerBase(IntPtr handle)
            : base(handle)
        {
        }

        protected UITableViewControllerBase(string nibName, NSBundle bundle)
            : base(nibName, bundle)
        {
        }

        #endregion

        #region ViewController lifecycle

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            LoadingOverlay = new LoadingOverlay(UIScreen.MainScreen.Bounds, UIApplication.SharedApplication.KeyWindow, "Loading...");
        }

        #endregion

        #region Event handlers

        public virtual void OnModelChanging()
        {
            if (ViewModel != null)
            {
                ViewModel.PropertyChanged -= OnModelPropertyChanged;
                ViewModel.LongTimeOpertaionFinished -= ViewModelOnLongTimeOpertaionFinished;
                ViewModel.LongTimeOpertaionStarted -= ViewModelOnLongTimeOpertaionStarted;
            }
        }

        public void OnModelPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
        }

        public virtual void OnModelChanged()
        {
            if (ViewModel != null)
            {
                ViewModel.PropertyChanged += OnModelPropertyChanged;
                ViewModel.LongTimeOpertaionFinished += ViewModelOnLongTimeOpertaionFinished;
                ViewModel.LongTimeOpertaionStarted += ViewModelOnLongTimeOpertaionStarted;
            }
        }

        protected virtual void ViewModelOnLongTimeOpertaionFinished(object sender, string callerName)
        {
            LoadingOverlay.Hide();
        }

        protected virtual void ViewModelOnLongTimeOpertaionStarted(object sender, string callerName)
        {
            LoadingOverlay.Show();
        }

        #endregion
    }
}
