using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using GalaSoft.MvvmLight.Messaging;
using TaskIt.Assets.Resources;
using TaskIt.Core;
using TaskIt.Infrastructure;
using TaskIt.Modules.Tasks.Assets.Resources;
using TaskIt.Modules.Tasks.Core;
using TaskIt.Web;

namespace TaskIt.Modules.Tasks.ViewModels
{
    [Export]
    public class ContactViewModel : TasksViewModelBase
    {
        private Contact _selectedItem;
        private ContactNote _selectedNote;

        public ContactViewModel()
        {            
            Messenger.Default.Register<NewEntityArgs>(this, OnNewItem);
            Messenger.Default.Register<EditEntityArgs>(this, OnEditItem);
            Messenger.Default.Register<SaveEntityArgs>(this, OnSaveItem);            
            Messenger.Default.Register<NoteSaveCompletedArgs>(this, OnNoteSaveCompleted);            
        }

        protected void OnNewItem(NewEntityArgs args)
        {
            if (IsContact(args))
            {
                Mode = ItemMode.Add;
                SelectedItem = new Contact
                {
                    Name = CommonStrings.Watermark_Name,
                    UserID = Utils.CurrentUserID,
                    CreatedDate = DateTime.Now
                };
            }

            if (IsContactNote(args))
            {
                SelectedNote = new ContactNote
                {
                    Text = CommonStrings.Watermark_Name,
                    UserID = Utils.CurrentUserID,
                    ContactID = SelectedItem.ID,
                    CreatedDate = DateTime.Now
                };
            }
        }

        protected void OnEditItem(EditEntityArgs args)
        {
            if (!IsContact(args))
            {
                return;
            }

            Mode = ItemMode.Edit;
            SelectedItem = Contacts.Where(p => p.ID == args.ID).FirstOrDefault();
        }

        protected void OnSaveItem(SaveEntityArgs args)
        {
            if (IsContact(args) && Mode == ItemMode.Add)
            {
                Utils.DataContext.Contacts.Add(SelectedItem);
            }
            else if (IsContactNote(args))
            {
                Utils.DataContext.ContactNotes.Add(SelectedNote);
            }
        }

        private static bool IsContact(EntityArgs args)
        {
            return args.EntityType == EntityType.Contact;
        }

        private static bool IsContactNote(EntityArgs args)
        {
            return args.EntityType == EntityType.ContactNote;
        }

        protected void OnNoteSaveCompleted(NoteSaveCompletedArgs args)
        {
            if (!IsContactNote(args))
            {
                return;
            }
            HasNotes = true;
            this.OnPropertyChanged(p => p.Notes);
        }

        public override void OnLoadNotes()
        {
            base.OnLoadNotes();
            DataProvider.GetContactNotes(SelectedItem.ID, OnNotesLoaded);
        }

        void OnNotesLoaded(LoadOperation<ContactNote> lo)
        {
            if (lo.HasError)
            {
                Utils.ShowErrorMessage(TasksErrorStrings.Message_LoadingNotesFailed, lo.Error.Message);
                lo.MarkErrorAsHandled();
                return;
            }

            this.OnPropertyChanged(p => p.Notes);
            Utils.HideBusyIndicator();
        }

        # region Properties

        public Contact SelectedItem
        {
            get { return _selectedItem; }
            set { _selectedItem = value; this.OnPropertyChanged(p => p.SelectedItem); }
        }

        public ContactNote SelectedNote
        {
            get { return _selectedNote; }
            set { _selectedNote = value; this.OnPropertyChanged(p => p.SelectedNote); }
        }

        public EntityType EntityType
        {
            get { return EntityType.Contact; }
        }

        public EntityType NoteEntityType
        {
            get { return EntityType.ContactNote; }
        }

        public IOrderedEnumerable<ContactNote> Notes
        {
            get { return Utils.DataContext.ContactNotes.OrderByDescending(n => n.CreatedDate); }
        }

        # endregion

        # region ResourceStrings

        public string ResourceFormLabelEmail
        {
            get { return ContactsStrings.FormLabel_Email; }
        }

        public string ResourceFormLabelUsername
        {
            get { return ContactsStrings.FormLabel_Username; }
        }

        public string ResourceMessageSaveBeforeAddingNotes
        {
            get { return ContactsStrings.Message_SaveBeforeAddingNotes; }
        }

        # endregion

    }
}