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 ProjectViewModel : TasksViewModelBase
    {
        private Project _selectedItem;
        private ProjectNote _selectedNote;

        public ProjectViewModel()
        {
            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 (IsProject(args))
            {
                Mode = ItemMode.Add;
                SelectedItem = new Project
                   {
                       Name = CommonStrings.Watermark_Name,
                       UserID = Utils.CurrentUserID,
                       CreatedDate = DateTime.Now
                   };
            }

            if (IsProjectNote(args))
            {           
                SelectedNote = new ProjectNote
                   {
                       Text = CommonStrings.Watermark_Name,
                       UserID = Utils.CurrentUserID,
                       ProjectID = SelectedItem.ID,
                       CreatedDate = DateTime.Now
                   };
            }
        }

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

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

        protected void OnSaveItem(SaveEntityArgs args)
        {
            if (IsProject(args) && Mode == ItemMode.Add)
            {
                Utils.DataContext.Projects.Add(SelectedItem);
            }
            else if (IsProjectNote(args))
            {
                Utils.DataContext.ProjectNotes.Add(SelectedNote);
            }
        }

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

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

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

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

        # region Properties

        private static bool IsProject(EntityArgs args)
        {
            return args.EntityType == EntityType.Project;
        }

        private static bool IsProjectNote(EntityArgs args)
        {
            return args.EntityType == EntityType.ProjectNote;
        }

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

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

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

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

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

        # endregion

        # region Resource Strings

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

        # endregion

    }
}