using System;
using System.Diagnostics;
using KellermanSoftware.ContactsModule.DataAccess;
using KellermanSoftware.ContactsModule.Events;
using KellermanSoftware.ContactsModule.Models;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.ViewModel;
using Microsoft.Practices.Unity;

namespace KellermanSoftware.ContactsModule.ViewModels
{
    public sealed class ContactDetailsViewModel : NotificationObject,
                                                  IContactDetailsViewModel
    {
        private readonly IUnityContainer _container;
        private readonly IRepository _repository;
        private readonly IEventAggregator _eventAggregator;
        private readonly IContactsViewModel _contactsViewModel;
        private Contact _contact;

        public ContactDetailsViewModel(IUnityContainer container,
                                       IRepository repository,
                                       IEventAggregator eventAggregator,
                                       IContactsViewModel contactsViewModel)
        {
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            if (repository == null)
            {
                throw new ArgumentNullException("repository");
            }
            if (eventAggregator == null)
            {
                throw new ArgumentNullException("eventAggregator");
            }
            if (contactsViewModel == null)
            {
                throw new ArgumentNullException("contactsViewModel");
            }

            _container = container;
            _repository = repository;
            _eventAggregator = eventAggregator;
            _contactsViewModel = contactsViewModel;
           
            _contactsViewModel.ContactSelected += OnContactSelected;
            _contactsViewModel.EditContactDetailsRequested += 
                OnEditContactDetailsRequested;
        }

        #region IContactDetailsViewModel Members

        public event EventHandler<ContactChangedEventArgs> ContactChanged = delegate { };

        #endregion IContactDetailsViewModel Members

        public string Name
        {
            get 
            { 
                return _contact == null ? null : _contact.Name; 
            }
        }

        public string Address
        {
            get 
            {
                return _contact == null ? null : _contact.Address; 
            }
        }

        public string Email
        {
            get 
            { 
                return _contact == null ? null : _contact.Email; 
            }
        }

        public string Phone
        {
            get 
            { 
                return _contact == null ? null : _contact.Phone; 
            }
        }

        private void OnContactSelected(object sender, 
                                       ContactSelectedEventArgs e)
        {
            _contact = 
                e.ContactId == null ? null 
                                    : _repository.LoadContact(e.ContactId.Value);
            RaisePropertyChanged(() => Name);
            RaisePropertyChanged(() => Address);
            RaisePropertyChanged(() => Email);
            RaisePropertyChanged(() => Phone);

            ContactChanged(this, new ContactChangedEventArgs(_contact));
        }

        private void OnEditContactDetailsRequested(object sender, EventArgs e)
        {
            // Create EditContactDetailsViewModel.
            Debug.Assert(_contact != null);
            ParameterOverride constructorParameter =
                new ParameterOverride("contact", new Contact(_contact));
            EditContactDetailsViewModel viewModel =
                _container.Resolve<EditContactDetailsViewModel>(constructorParameter);

            // Publish the EditContactDetailsEvent event.
            _eventAggregator.GetEvent<EditContactDetailsEvent>().Publish(viewModel);
        }
    }
}
