// Copyright © 2015 Genesys. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Genesyslab.Desktop.Infrastructure.Commands;
using Genesyslab.Desktop.Infrastructure.DependencyInjection;
using Genesyslab.Desktop.Modules.Gms.CallbackInvitation.Generic;
using Genesyslab.Platform.Commons.Logging;
using System.Windows;
using System.Windows.Threading;
using Genesyslab.Desktop.Modules.Core.Model.Agents;
using Genesyslab.Enterprise.Model.Device;
using Genesyslab.Desktop.Modules.Gms.CallbackInvitation.CallbackInvitation;
using System.Collections.ObjectModel;
using Genesyslab.Desktop.Modules.Voice.Model.Agents;

namespace Genesyslab.Desktop.Modules.Gms.CallbackInvitation.CustomCommands {
    class AfterMediaVoiceLogOnCommand : IElementOfCommand {
        private readonly IObjectContainer container;
        private readonly ICfgReader config;
        private readonly ILogger log;
        private string _commandName = "AfterMediaVoiceLogOnCommand";

        public AfterMediaVoiceLogOnCommand(IObjectContainer container) {
            this.container = container;
            this.config = this.container.Resolve<ICfgReader>();

            // Initialize the trace system
            this.log = this.container.Resolve<ILogger>().CreateChildLogger(this.Name);
        }

        #region IElementOfCommand Members

        public string Name {
            get { return this._commandName; }
            set { if (this._commandName != value) { this._commandName = value; } }
        }

        public bool Execute(IDictionary<string, object> parameters, IProgressUpdater progress) {
            // To go to the main thread
            if (Application.Current.Dispatcher != null && !Application.Current.Dispatcher.CheckAccess()) {
                object result = Application.Current.Dispatcher.Invoke(DispatcherPriority.Send, new ExecuteDelegate(Execute), parameters, progress);
                return (bool)result;
            }
            else {
                // Ok, we are in the main thread
                this.log.Debug(String.Format("{0} Starting custom {1} functionality", GConst.LOG_PREFIX, this.Name));

                IAgent agent = this.container.Resolve<IAgent>();
                List<String> loginDNs = agent.LoginDNs;
                ObservableCollection<IMedia> agentMedias = agent.Place.ListOfMedia;
                IMediaVoice mediaVoice = null;
                foreach (var media in agentMedias)
                {
                    IMediaVoice testMediaVoice = media as IMediaVoice;
                    this.log.Debug(String.Format("{0} current Media is {1} ", GConst.LOG_PREFIX, testMediaVoice));
                    if (testMediaVoice != null && !testMediaVoice.IsOutOfService) // && !testMediaVoice.IsLogOff) 
                    {
                        // get the right media !!!
                        mediaVoice = testMediaVoice;
                        this.log.Debug(String.Format("{0} current Media IsLogOff is {1} ", GConst.LOG_PREFIX, testMediaVoice.IsLogOff));
                        this.log.Debug(String.Format("{0} current Media IsOutOfService is {1} ", GConst.LOG_PREFIX, testMediaVoice.IsOutOfService));
                    }
                }
                this.log.Debug(String.Format("{0} final Media is {1} ", GConst.LOG_PREFIX, mediaVoice));
                String agentDN = "";
                if (loginDNs.Count > 0) {
                    agentDN = loginDNs[0].Substring(0, loginDNs[0].IndexOf('@'));

                    this.log.Debug(String.Format("{0} Agent [{1}] is logged into [{2}]. Extracted DN = [{3}]",
                            GConst.LOG_PREFIX, agent.UserName, loginDNs[0], agentDN));
                }

                // Set up the listener to the DN
                if (mediaVoice != null) {
                    this.log.Debug(String.Format("mediaVoice is not null ", GConst.LOG_PREFIX));
                    IUserEventListener userEventListener = this.container.Resolve<IUserEventListener>();
                    userEventListener.AgentDN = agentDN;
                    userEventListener.MediaVoice = mediaVoice;
                    userEventListener.SetupHandler();
                }

                this.log.Debug(String.Format("{0} Finished custom {1} functionality", GConst.LOG_PREFIX, this.Name));

                // Always allow remaining elements in the command chain to execute: set return value to false
                return false;
            }
        }

        /// <summary>
        /// This delegate allows to go to the main thread.
        /// </summary>
        delegate bool ExecuteDelegate(IDictionary<string, object> parameters, IProgressUpdater progressUpdater);

        #endregion
    }
}
