using mshtml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows;
using ZionRobot.Models.Search;

namespace ZionRobot.Handlers
{
    /// <summary>
    /// Interaction logic for Browser.xaml
    /// </summary>
    public partial class Browser : Window
    {
        #region Singleton
        private static Browser instance = null;

        public static Browser Instance
        {
            get
            {
                if (instance == null)
                    instance = new Browser();

                return instance;
            }
        }
        #endregion

        private System.Windows.Controls.WebBrowser browser;
        private bool wait = false;

        private System.Threading.Thread main;
        private bool terminate = false;
        private Models.Source.Origin source;
        //private Models.Source.BlockElement blockElement;
        private Dictionary<string, string> dictionaryValues;
        private List<List<Models.Search.Element>> searchElements;

        public System.Threading.Thread Main { get => main; }
        public bool Terminate { get => this.terminate; }
        public Models.Source.Origin Source { get => this.source; set => this.source = value; }
        //public Models.Source.BlockElement BlockElement { get => this.blockElement; set => this.blockElement = value; }
        public Dictionary<string, string> DictionaryValues { get => dictionaryValues; set => dictionaryValues = value; }
        public List<List<Models.Search.Element>> SearchElements { get => searchElements; set => searchElements = value; }

        public Models.ZFlow.Activity Activity;

        public Browser()
        {
            InitializeComponent();

            //this.Visibility = Visibility.Visible;
            //this.ShowInTaskbar = true;

            //this.Visibility = Visibility.Hidden;
            //this.ShowInTaskbar = false;
            this.Closing += Browser_Closing;

            var parent = this._holder;
            var replacement = new System.Windows.Controls.WebBrowser();
            replacement.Name = @"browser";

            parent.Children.Clear();
            parent.Children.Add(replacement);

            this.browser = null;
            this.browser = replacement;

            this.browser.VerticalAlignment = VerticalAlignment.Stretch;
            this.browser.HorizontalAlignment = HorizontalAlignment.Stretch;
            this.browser.Navigating += Browser_Navigating;
            this.browser.LoadCompleted += Browser_LoadComplete;
            this.browser.Unloaded += Browser_Unloaded;
            HideScriptErrors(this.browser, true);

            this.dictionaryValues = new Dictionary<string, string>();
            this.searchElements = new List<List<Models.Search.Element>>();

        }

        private void Browser_Unloaded(object sender, RoutedEventArgs e)
        {
            this.browser.ContextMenu = null;
            this.browser.DataContext = null;
            this.browser.Resources = null;
            this.browser.Source = null;

            this.browser.Navigating -= Browser_Navigating;
            this.browser.LoadCompleted -= Browser_LoadComplete;
            this.browser.Unloaded -= Browser_Unloaded;

            this.browser.Dispose();
        }

        private void Browser_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        { 
            //e.Cancel = true;

            this.terminate = true;

            this.Dispose();

            this.main = null;
            this.source = null;
            this.dictionaryValues.Clear();
            this.dictionaryValues = null;
            this.searchElements.Clear();
            this.searchElements = null;
            instance = null;

            GC.SuppressFinalize(this);
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();

            /*this.browser.ContextMenu = null;
            this.browser.DataContext = null;
            this.browser.Source = null;
            this.browser.Resources = null;*/

        }

        public void Dispose()
        {
            main.Abort();

            System.Windows.Data.BindingOperations.ClearAllBindings(this.browser);

            var w = getWindowElement(this.browser);

             var field = typeof(Window).GetField("_swh", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

             var valueSWH = field.GetValue(this);

             var valueSourceWindow = valueSWH.GetType().GetField("_sourceWindow", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSWH);

             var valueKeyboardInput = valueSourceWindow.GetType().GetField("_keyboardInputSinkChildren", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(valueSourceWindow);

             var inputSites = valueKeyboardInput as IEnumerable<System.Windows.Interop.IKeyboardInputSite>;

             if (inputSites == null)
                 return;

             var currentSite = inputSites.FirstOrDefault(s => ReferenceEquals(s.Sink, this.browser));

             if (currentSite != null)
                 currentSite.Unregister();

             this._holder.Children.Remove(this.browser);

        }
        
        private static Window getWindowElement(DependencyObject element)
        {
            while(element != null && !(element is Window))
            {
                element = System.Windows.Media.VisualTreeHelper.GetParent(element);
            }

            return element as Window;
        }

        #region BrowserEvents
        private void Browser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
        {
            wait = true;
            Console.WriteLine(e.Uri);
        }

        private void Browser_LoadComplete(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            wait = false;
            //browser.LayoutUpdated += Browser_LayoutUpdated;
        }

        private void Browser_LayoutUpdated(object sender, EventArgs e)
        {
            mshtml.HTMLDocument doc = null;

            doc = (mshtml.HTMLDocument)this.browser.Document;

            browser.LayoutUpdated -= Browser_LayoutUpdated;
        }

        private void HideScriptErrors(System.Windows.Controls.WebBrowser wb, bool hide)
        {
            var fiComWebBrowser = typeof(System.Windows.Controls.WebBrowser)
                .GetField("_axIWebBrowser2",
                System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            if (fiComWebBrowser == null) return;
            var objComWebBrowser = fiComWebBrowser.GetValue(wb);
            if (objComWebBrowser == null)
            {
                wb.Loaded += (o, s) => HideScriptErrors(wb, hide);
                return;
            }
            objComWebBrowser.GetType().InvokeMember("Silent", System.Reflection.BindingFlags.SetProperty,
                null, objComWebBrowser, new object[] { hide });
        }
        #endregion

        private void Wait()
        {
            while (wait)
            {
                System.Threading.Thread.Sleep(1000);
            }
        }
        #region Lawsuit
        public void CreateLawsuit(Models.ZFlow.Lawsuit lawsuit)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuit").FirstOrDefault().Actions;

                lawsuit.Fields.ToList().ForEach(f =>
                {
                    string value = f.Value;
                    DateTime date;
                    
                    this.dictionaryValues.Add(f.Key, DateTime.TryParse(f.Value, out date) ? Helpers.Shift.formatDate(f.Value, @"dd/MM/yyyy") : f.Value);
                });

                this.dictionaryValues.Add(@"Adverse_name", lawsuit.Adverse.Name.ToString());
                this.dictionaryValues.Add(@"Accountable", lawsuit.Accountable);
                this.dictionaryValues.Add(@"Physical", lawsuit.Physical.ToString());
                this.dictionaryValues.Add(@"Folder_number", lawsuit.FolderNumber);
                this.dictionaryValues.Add(@"Opening_date", Helpers.Shift.formatDate(lawsuit.OpeningDate.ToString(), @"dd/MM/yyyy"));
                this.dictionaryValues.Add(@"Distribution_date", Helpers.Shift.formatDate(lawsuit.DistributionDate.ToString(), @"dd/MM/yyyy"));
                this.dictionaryValues.Add(@"Client", lawsuit.Client);
                this.dictionaryValues.Add(@"Field_of_law", lawsuit.FieldOfLaw);
                this.dictionaryValues.Add(@"Subject", lawsuit.Subject);

                if (lawsuit.Adverse.Juridical_person)
                {
                    this.dictionaryValues.Add(@"Adverse_juridical_person", lawsuit.Adverse.Juridical_person.ToString());
                }

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if (this.dictionaryValues.ContainsKey("Lawsuit_link"))
                {
                    lawsuit.Link = this.dictionaryValues["Lawsuit_link"];
                    lawsuit.UpdateUrl();
                    lawsuit.UpdateSycn(2);

                }
                else
                {
                    lawsuit.UpdateSycn(5);
                }

            });

            Main.Start();
        }
         public void UpdateLawsuit(Models.ZFlow.Lawsuit lawsuit)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"UpdateLawsuit").FirstOrDefault().Actions;

                lawsuit.Fields.ToList().ForEach(f =>
                {
                    string value = f.Value;
                    DateTime date;
                    
                    this.dictionaryValues.Add(f.Key, DateTime.TryParse(f.Value, out date) ? Helpers.Shift.formatDate(f.Value, @"dd/MM/yyyy") : f.Value);
                });

                this.dictionaryValues.Add(@"Adverse_name", lawsuit.Adverse?.Name?.ToString() ?? "");
                this.dictionaryValues.Add(@"Accountable", lawsuit.Accountable);
                this.dictionaryValues.Add(@"Physical", lawsuit.Physical.ToString());
                this.dictionaryValues.Add(@"Folder_number", lawsuit.FolderNumber);
                this.dictionaryValues.Add(@"Opening_date", lawsuit.OpeningDate);
                this.dictionaryValues.Add(@"Distribution_date", lawsuit.DistributionDate);
                //this.dictionaryValues.Add(@"Opening_date", Helpers.Shift.formatDate(lawsuit.OpeningDate.ToString(), @"dd/MM/yyyy"));
                //this.dictionaryValues.Add(@"Distribution_date", Helpers.Shift.formatDate(lawsuit.DistributionDate.ToString(), @"dd/MM/yyyy"));
                this.dictionaryValues.Add(@"Client", lawsuit.Client);
                this.dictionaryValues.Add(@"Field_of_law", lawsuit.FieldOfLaw);
                this.dictionaryValues.Add(@"Subject", lawsuit.Subject);

                if (lawsuit.Adverse.Juridical_person)
                {
                    this.dictionaryValues.Add(@"Adverse_juridical_person", lawsuit.Adverse.Juridical_person.ToString());
                }

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                lawsuit.UpdateSycn(2);


            });

            Main.Start();
        }

        #endregion
        #region LawsuitPhases
        public void CreateLawsuitPhase(Models.ZFlow.LawsuitPhase lawsuitPhase)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitPhase").FirstOrDefault().Actions;

                lawsuitPhase.Fields.ToList().ForEach(f =>
                {
                    string value = f.Value;
                    DateTime date;

                    this.dictionaryValues.Add(f.Key, DateTime.TryParse(f.Value, out date) ? Helpers.Shift.formatDate(f.Value, @"dd/MM/yyyy") : f.Value);
                });

                string path = Environment.CurrentDirectory;

                System.IO.StringReader sr = new System.IO.StringReader(string.Join("/", path, "Persistence/orgao.json"));

                string json = System.IO.File.ReadAllText($"{path}\\Persistence\\orgao.json");
                List<Models.ZFlow.Orgao> orgaos = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.ZFlow.Orgao>>(json);

                //var y = Newtonsoft.Json.Linq.JObject.Parse(x);

                this.dictionaryValues.Add(@"ParentLink", lawsuitPhase.ParentLink);
                this.dictionaryValues.Add(@"Number", lawsuitPhase.Number);
                this.dictionaryValues.Add(@"Type", lawsuitPhase.Type);
                this.dictionaryValues.Add(@"Accountable", lawsuitPhase.Accountable);
                this.dictionaryValues.Add(@"OpeningDate", Helpers.Shift.formatDate(lawsuitPhase.OpeningDate.ToString(), @"dd/MM/yyyy"));
                this.dictionaryValues.Add(@"Current", lawsuitPhase.Current.ToString());


                Models.ZFlow.Orgao orgao = orgaos.Where(o => $"{o.Abreviacao} - {o.Nome}" == this.dictionaryValues["Órgão_Judicial"]).FirstOrDefault();

                if (orgao != null)
                {
                    this.dictionaryValues.Remove(@"Órgão_Judicial");
                    this.dictionaryValues.Add(@"Órgão_Judicial", orgao.Id.ToString());
                }


                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if (this.dictionaryValues.ContainsKey("LawsuitPhaseLink"))
                {
                    lawsuitPhase.Link = this.dictionaryValues["LawsuitPhaseLink"];
                    lawsuitPhase.UpdateUrl();
                    lawsuitPhase.UpdateSycn(2);
                }
                else
                {
                    lawsuitPhase.UpdateSycn(5);
                }

            });

            Main.Start();
        }

        #endregion


        #region LawsuitPhaseProgress
        public void CreateLawsuitPhaseProgress(Models.ZFlow.LawsuitPhaseProgress lawsuitPhaseProgress)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                if(lawsuitPhaseProgress.Fields.Count() < 5)
                {
                    lawsuitPhaseProgress.UpdateSycn(5);
                    return;
                }

                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitPhaseProgress").FirstOrDefault().Actions;

                lawsuitPhaseProgress.Fields.ToList().ForEach(f =>
                {
                    string value = f.Value;
                    DateTime date;

                    this.dictionaryValues.Add(f.Key, DateTime.TryParse(f.Value, out date) ? Helpers.Shift.formatDate(f.Value, @"dd/MM/yyyy") : f.Value);
                });

                string path = Environment.CurrentDirectory;

                System.IO.StringReader sr = new System.IO.StringReader(string.Join("/", path, "Persistence/orgao.json"));

                string json = System.IO.File.ReadAllText($"{path}\\Persistence\\orgao.json");
                List<Models.ZFlow.Orgao> orgaos = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Models.ZFlow.Orgao>>(json);

                //var y = Newtonsoft.Json.Linq.JObject.Parse(x);

                this.dictionaryValues.Add(@"ParentLink", lawsuitPhaseProgress.ParentLink);
                this.dictionaryValues.Add(@"Number", lawsuitPhaseProgress.Number);
                this.dictionaryValues.Add(@"Type", lawsuitPhaseProgress.Type);
                this.dictionaryValues.Add(@"Accountable", lawsuitPhaseProgress.Accountable);
                this.dictionaryValues.Add(@"OpeningDate", Helpers.Shift.formatDate(lawsuitPhaseProgress.Date.ToString(), @"dd/MM/yyyy"));
                this.dictionaryValues.Add(@"Current", lawsuitPhaseProgress.Current.ToString());


                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if (this.dictionaryValues.ContainsKey("LawsuitPhaseProgressLink"))
                {
                    lawsuitPhaseProgress.Link = this.dictionaryValues["LawsuitPhaseProgressLink"];
                    lawsuitPhaseProgress.UpdateUrl();
                    lawsuitPhaseProgress.UpdateSycn(2);
                }
                else
                {
                    lawsuitPhaseProgress.UpdateSycn(5);
                }

            });

            Main.Start();
        }


        #endregion

        #region SyncFromLocal

        private string translateAnaliseDeRisco(string value)
        {
            string result = string.Empty;
            switch (value.ToUpper())
            {
                case "REMOTA":
                    result = "1";
                    break;
                case "POSSÍVEL":
                    result = "2";
                    break;
                case "PROVÁVEL":
                    result = "3";
                    break;
            }
            return result;
        }

        private string valueHelper(KeyValuePair<string, string> pair)
        {
            string value = System.Text.RegularExpressions.Regex.Replace(pair.Value.Trim(), "\r\n", @"");
            if (pair.Key.ToLower().Contains("valor"))
            {
                value = this.currencyHelper(value);
            }

            if(pair.Key.ToLower() == "análise_de_risco")
            {
                value = this.translateAnaliseDeRisco(pair.Value);
            }

            return value;
        }

        private string currencyHelper(string value)
        {
            decimal result;

            if (string.IsNullOrEmpty(value) || !decimal.TryParse(value, out result))
            {
                return value;
            }

            System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture("pt-BR");
            value = value.Replace(".", "");
            value = decimal.Parse(value).ToString("C", culture);
            value = value.Replace("R$ ", "");

            return value;
        }

        public void CreateWithLocal(string file, Models.Source.BlockElement mainActionBlock)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                /*List<Models.Source.Action> CreateLawsuitPhaseProgressActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitDepositLocal").FirstOrDefault().Actions;*/


                string content = System.IO.File.ReadAllText(file);
                JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                Dictionary<string, string> dicProgress = json_serializer.Deserialize<Dictionary<string, string>>(content);

                foreach (KeyValuePair<string, string> prog in dicProgress)
                {
                    this.dictionaryValues.Add(prog.Key.Replace(' ', '_'), this.valueHelper(prog));
                }

                this.dictionaryValues.Remove("Data");

                this.dictionaryValues.Add("Data", "22/12/2021");

                foreach (Models.Source.Action action in mainActionBlock.Actions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                /*if (this.dictionaryValues.ContainsKey("LawsuitPhaseProgressLink"))
                {
                    lawsuitPhase.Link = this.dictionaryValues["LawsuitPhaseLink"];
                    lawsuitPhase.UpdateUrl();
                    lawsuitPhase.UpdateSycn(2);
                }
                else
                {
                    lawsuitPhase.UpdateSycn(5);
                }*/

            });

            Main.Start();


        }

        public void CreateLawsuitPhaseProgressLocal(string file)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> CreateLawsuitPhaseProgressActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitPhaseProgressLocal").FirstOrDefault().Actions;


                string content = System.IO.File.ReadAllText(file);
                JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                Dictionary<string, string> dicProgress = json_serializer.Deserialize<Dictionary<string, string>>(content);

                foreach (KeyValuePair<string, string> prog in dicProgress)
                {
                    this.dictionaryValues.Add(prog.Key.Replace(' ', '_'), prog.Value);
                }

                foreach (Models.Source.Action action in CreateLawsuitPhaseProgressActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                /*if (this.dictionaryValues.ContainsKey("LawsuitPhaseProgressLink"))
                {
                    lawsuitPhase.Link = this.dictionaryValues["LawsuitPhaseLink"];
                    lawsuitPhase.UpdateUrl();
                    lawsuitPhase.UpdateSycn(2);
                }
                else
                {
                    lawsuitPhase.UpdateSycn(5);
                }*/

            });

            Main.Start();


        }

        public void CreateLawsuitDeposit(string file, Models.Source.BlockElement mainActionBlock)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                /*List<Models.Source.Action> CreateLawsuitPhaseProgressActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitDepositLocal").FirstOrDefault().Actions;*/


                string content = System.IO.File.ReadAllText(file);
                JavaScriptSerializer json_serializer = new JavaScriptSerializer();
                Dictionary<string, string> dicProgress = json_serializer.Deserialize<Dictionary<string, string>>(content);

                foreach (KeyValuePair<string, string> prog in dicProgress)
                {
                    this.dictionaryValues.Add(prog.Key.Replace(' ', '_'), this.valueHelper(prog));
                }

                foreach (Models.Source.Action action in mainActionBlock.Actions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                /*if (this.dictionaryValues.ContainsKey("LawsuitPhaseProgressLink"))
                {
                    lawsuitPhase.Link = this.dictionaryValues["LawsuitPhaseLink"];
                    lawsuitPhase.UpdateUrl();
                    lawsuitPhase.UpdateSycn(2);
                }
                else
                {
                    lawsuitPhase.UpdateSycn(5);
                }*/

            });

            Main.Start();


        }
        #endregion

        #region LawsuitDemands
        public void CreateLawsuitDemand(Models.ZFlow.LawsuitDemand lawsuitDemand)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateLawsuitDemand").FirstOrDefault().Actions;

                lawsuitDemand.Fields.ToList().ForEach(f =>
                {
                    string value = f.Value;

                    if(f.Key == @"Análise_de_Risco")
                    {
                        switch (f.Value)
                        {
                            case @"Remota":
                                value = "1";
                                break;
                            case @"Possível":
                                value = "2";
                                break;
                            case @"Provável":
                                value = "3";
                                break;
                        }
                    }

                    if(f.Key == @"Causa_de_Pedir")
                    {
                        HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                        htmlDoc.LoadHtml(f.Value);
                        value= htmlDoc.DocumentNode.InnerText;
                    }
                    DateTime date;

                    this.dictionaryValues.Add(f.Key, DateTime.TryParse(f.Value, out date) ? Helpers.Shift.formatDate(f.Value, @"dd/MM/yyyy") : value);
                });

                this.dictionaryValues.Add(@"ParentLink", lawsuitDemand.ParentLink);
                this.dictionaryValues.Add(@"Accountable", lawsuitDemand.Accountable);
                this.dictionaryValues.Add(@"OpeningDate", Helpers.Shift.formatDate(lawsuitDemand.OpeningDate.ToString(), @"dd/MM/yyyy"));

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if (this.dictionaryValues.ContainsKey("LawsuitDemandLink"))
                {
                    lawsuitDemand.Link = this.dictionaryValues["LawsuitDemandLink"];
                    lawsuitDemand.UpdateUrl();
                    lawsuitDemand.UpdateSycn(2);
                }
                else
                {
                    lawsuitDemand.UpdateSycn(5);
                }

            });

            Main.Start();
        }

        #endregion


        #region Activity
        public void ExecuteAndSave(string path)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                //this.Visibility = Visibility.Visible;
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                this.Show();
                this.terminate = false;
            });
            

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;
                foreach (Models.Source.ActionsElement actionElement in Source.ActionsElements)
                {
                    foreach (Models.Source.Action action in actionElement.Actions)
                    {
                        executeAction(action).Wait();
                        //Task<bool> task = executeAction(action);
                        //task.Wait();
                        //execute = task.Result;

                        //if (!execute)
                            //break;
                    }
                    //if (!execute)
                        //break;
                }

                //if (execute)
                    SaveData(path);
            });

            main.Start();
        }
        private void SaveData(string path)
        {
            this.searchElements.ForEach(data =>
            {
                string allElementsTxt = string.Join(@" ", data.Where(d => d.GoTo == @"SearchLog").Select(e => e.Value).ToArray());

                if (!hasLog(allElementsTxt))
                {
                    DateTime datenow = DateTime.Now;

                    string fileName = string.Format("Publicação-{0}-{1}", source.OutputFolder, datenow.ToString(@"yyyyMMdd-HHmmssffff"));

                    ZionVault.Binder.OCR.Document doc = new ZionVault.Binder.OCR.Document();

                    doc.Pages.Add(
                        new ZionVault.Binder.OCR.Page(
                            string.Join(Environment.NewLine, data.Where(d => d.GoTo == @"Meta").Select(e => e.Value).ToArray())));

                    System.IO.Directory.CreateDirectory(path);

                    string fileFullPath = Helpers.Naming.GetFileFullPath(path, fileName, ".ocr");

                    doc.Save(fileFullPath, false, false);

                    System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(@"pt-BR");

                    Persistence.Logs.SearchLog.SearchResults.Add(
                        $"{datenow.ToString("G", culture)}||" +
                        $"{source.Title}||" +
                        $"{fileFullPath}||" +
                        $"{allElementsTxt}");

                    Persistence.Logs.SearchLog.Save();
                }
            });
        }
        public void ExecuteAndMove(Models.Items.File file, string outputPath)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                //this.Visibility = Visibility.Visible;

                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                foreach(Models.Source.ActionsElement actionElement in Source.ActionsElements)
                {
                    foreach (Models.Source.Action action in actionElement.Actions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;

                        //if (!execute)
                            //break;
                    }
                    //if (!execute)
                        //break;
                }

                //if (execute)
                //{
                //}

                /*Source.ActionsElements.ForEach(actionsElement =>
                {
                    actionsElement.Actions.ForEach(action =>
                    {
                        executeAction(action).Wait();
                    });
                });

                file.METAObject.Status = Persistence.Basic.INTEGRATED;
                file.METAObject.Save(file.META, false, false);
                file.Status = Persistence.Basic.INTEGRATED;*/

                Models.ZFlow.Activity activity = new Models.ZFlow.Activity();
                activity.Date = dictionaryValues["ActivityDate"];
                activity.DateFinal = dictionaryValues["ActivityDate"];
                activity.TypeId = 152; //1 = id do tipo de atividade "Verificar"
                activity.Subject = @"Verificar";

                activity.Client = dictionaryValues["Cliente"];
                activity.Sponsor = dictionaryValues["userName"];

                activity.Fields.Add(@"1", activity.Sponsor);
                activity.Fields.Add(@"2", activity.Client);
                activity.Fields.Add(@"3", dictionaryValues["Número da pasta"]);

                activity.Fields.Add(@"4", dictionaryValues["URL da atividade"]);//.Replace(@"?", @"U+003F"));//.Split('?').Last().Split('&').First().Split('=').Last());

                activity.Fields.Add(@"5", dictionaryValues.FirstOrDefault(x => x.Key == @"ProcessUrl").Key != null ?
                        dictionaryValues["ProcessUrl"] : @"");//.Replace(@"?", @"U+003F") : @"");
                activity.Fields.Add(@"6",
                    dictionaryValues.FirstOrDefault(x => x.Key == @"SharpointUrl").Key != null ?
                        dictionaryValues["SharpointUrl"] : @"");//.Replace(@"?", @"U+003F") : @"");//.Split('?').Last());
                activity.Fields.Add(@"7", Helpers.Shift.formatDate(dictionaryValues["Data da publicação"], @"yyyy-MM-dd HH:mm:ss"));
                activity.Fields.Add(@"9", dictionaryValues["SearchElements.Fields.ConteudoCompleto"]);
                activity.Fields.Add(@"10", 
                    dictionaryValues.FirstOrDefault(x => x.Key == @"Parecer").Key != null ? 
                        dictionaryValues[@"Parecere"] : @"");

                try
                {
                    activity.createActivity();
                } catch(Exception ex)
                {

                }
                finally
                {
                    file.METAObject.Status = Persistence.Basic.INTEGRATED;
                    file.METAObject.Save(file.META, false, false);
                    file.Status = Persistence.Basic.INTEGRATED;
                }


            });

            Main.Start();
        }
        public void ExecuteDemo()
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                //this.Visibility = Visibility.Visible;

                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                foreach(Models.Source.ActionsElement actionElement in Source.ActionsElements)
                {
                    foreach (Models.Source.Action action in actionElement.Actions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;

                        //if (!execute)
                            //break;
                    }
                    //if (!execute)
                        //break;
                }
            });

            Main.Start();
        }

        public void SyncActivity(Models.ZFlow.Activity activity)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                //this.DictionaryValues.Add(@"ActivityUrl",
                //                Persistence.DataJuri.Host + Persistence.DataJuri.Activity + activity.DataJuri);

                this.DictionaryValues.Add(@"ActivityUrl", activity.DataJuri);

                this.DictionaryValues.Add(@"Responsável", activity.Sponsor);
                this.DictionaryValues.Add(@"EmailResponsável", activity.SponsorEmail);
                this.DictionaryValues.Add(@"Cliente", activity.Client);
                this.DictionaryValues.Add(@"NumeroPasta", activity.ProcessNumber);
                this.DictionaryValues.Add(@"Data", Helpers.Shift.formatDate(activity.Date, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"DataFatal", Helpers.Shift.formatDate(activity.DateFinal, @"dd/MM/yyyy"));


                //this.DictionaryValues.Add(@"CommentsCount", activity.Comments.Count().ToString());

                //this.DictionaryValues.Add(@"DeadlinesCount", activity.Deadlines.Count().ToString());

                foreach (Models.Source.ActionsElement actionElement in Source.ActionsElements)
                {
                    foreach (Models.Source.Action action in actionElement.Actions)
                    {

                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;

                        //if (!execute)
                        //break;
                    }
                    //if (!execute)
                    //break;\
                }

                //this.DictionaryValues.Remove(@"Cliente");

                if (activity.Parecer != null && activity.TypeId == 1)
                {
                    this.DictionaryValues.Add(@"ActivityParecer", activity.Parecer);

                    List<Models.Source.Action> createParecerActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateParecer").FirstOrDefault().Actions;

                    if (createParecerActions != null)
                    {
                        foreach (Models.Source.Action action in createParecerActions)
                        {
                            Task<bool> task = executeAction(action);
                            task.Wait();
                            execute = task.Result;
                        }
                    }
                }

                List<Models.Source.Action> createCommentActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateComment").FirstOrDefault().Actions;

                if (createCommentActions != null)
                {
                    activity.Comments.OrderBy(c => c.CreatedAt).ToList().ForEach(comment =>
                    {
                        this.DictionaryValues.Add(@"CommentResponser", comment.CreatedByName);
                        this.DictionaryValues.Add(@"CommentSubject", comment.Subject);
                        this.DictionaryValues.Add(@"CommentValue", comment.Value);

                        foreach (Models.Source.Action action in createCommentActions)
                        {
                            Task<bool> task = executeAction(action);
                            task.Wait();
                            execute = task.Result;
                        }

                        this.DictionaryValues.Remove(@"CommentResponser");
                        this.DictionaryValues.Remove(@"CommentSubject");
                        this.DictionaryValues.Remove(@"CommentValue");

                    });
                }

                /*List<Models.ZFlow.Deadline> deadlines = new List<Models.ZFlow.Deadline>();

                activity.Deadlines.OrderByDescending(d => d.CreatedAt).ToList().ForEach(deadline =>
                {
                    var af = deadlines.Where(d => d.DeadlineId == deadline.DeadlineId).FirstOrDefault();
                    if (deadlines.Where(d => d.DeadlineId == deadline.DeadlineId).FirstOrDefault() == null)
                    {
                        deadlines.Add(deadline);
                    }
                });*/

                List<Models.Source.Action> createDeadlineActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateDeadline").FirstOrDefault().Actions;

                activity.Deadlines.ForEach(deadline =>
                {
                    if (createDeadlineActions != null)
                    {
                        this.DictionaryValues.Add(@"DeadlineResponser", deadline.SponserName);
                        this.DictionaryValues.Add(@"DeadlineResponserEmail", deadline.SponserEmail);
                        this.DictionaryValues.Add(@"DeadlineSubject", deadline.Subject);
                        this.DictionaryValues.Add(@"DeadlineDate", Helpers.Shift.formatDate(deadline.Pre, @"dd/MM/yyyy"));
                        this.DictionaryValues.Add(@"DeadlineFinal", Helpers.Shift.formatDate(deadline.Value, @"dd/MM/yyyy"));
                        this.DictionaryValues.Add(@"SearchElements.Fields.Tipo", @"Publicação");
                        

                        foreach (Models.Source.Action action in createDeadlineActions)
                        {
                            Task<bool> task = executeAction(action);
                            task.Wait();
                            execute = task.Result;
                        }

                        Models.ZFlow.Activity subActivity = new Models.ZFlow.Activity();

                        subActivity.EntityId = activity.EntityId;
                        subActivity.ParentId = activity.Id;
                        subActivity.Date = dictionaryValues["DeadlineDate"];
                        subActivity.DateFinal = dictionaryValues["DeadlineFinal"];
                        subActivity.TypeId = 4; //4 = id do tipo de atividade "Prazo"
                        subActivity.Subject = dictionaryValues["DeadlineSubject"];

                        subActivity.Client = dictionaryValues["Cliente"];
                        subActivity.Sponsor = dictionaryValues["DeadlineResponser"];

                        subActivity.Fields.Add(@"1", subActivity.Client);
                        subActivity.Fields.Add(@"2", subActivity.Sponsor);
                        subActivity.Fields.Add(@"3", !string.IsNullOrEmpty(activity.ProcessNumber) ? activity.ProcessNumber : @"");
                        subActivity.Fields.Add(@"4", dictionaryValues["URL da atividade"]);
                        subActivity.Fields.Add(@"5", activity.ProcessURL != null ? activity.ProcessURL : @"");
                        subActivity.Fields.Add(@"6", activity.Sharepoint != null ? activity.Sharepoint : @"");

                        subActivity.createActivity();

                        this.DictionaryValues.Remove(@"DeadlineResponser");
                        this.DictionaryValues.Remove(@"DeadlineResponserEmail");
                        this.DictionaryValues.Remove(@"DeadlineSubject");
                        this.DictionaryValues.Remove(@"DeadlineDate");
                        this.DictionaryValues.Remove(@"DeadlineFinal");
                        this.DictionaryValues.Remove(@"SearchElements.Fields.Tipo");

                        //append do mapeamento
                        this.DictionaryValues.Remove(@"Número da pasta");
                        this.DictionaryValues.Remove(@"URL da atividade");
                        this.DictionaryValues.Remove(@"1");
                        this.DictionaryValues.Remove(@"2");
                        this.DictionaryValues.Remove(@"3");
                        this.DictionaryValues.Remove(@"4");
                        this.DictionaryValues.Remove(@"5");
                        this.DictionaryValues.Remove(@"6");
                    }
                });

                /*if(activity.TypeId == 4) //4 = id do tipo de atividade "Prazo"
                {
                    List<Models.Source.Action> createSubActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateSubActivity").FirstOrDefault().Actions;

                    this.DictionaryValues.Add(@"Responser", activity.Sponsor);
                    this.DictionaryValues.Add(@"ResponserEmail", activity.SponsorEmail);
                    this.DictionaryValues.Add(@"Subject", @"Protocolo");
                    this.DictionaryValues.Add(@"Date", Helpers.Shift.formatDate(DateTime.Now.ToString(), @"dd/MM/yyyy"));
                    this.DictionaryValues.Add(@"DateFinal", Helpers.Shift.formatDate(activity.DateFinal, @"dd/MM/yyyy"));
                    this.DictionaryValues.Add(@"SearchElements.Fields.Tipo", @"Publicação");

                    foreach (Models.Source.Action action in createSubActivityActions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;
                    }

                    Models.ZFlow.Activity subActivity = new Models.ZFlow.Activity();

                    subActivity.EntityId = activity.EntityId;
                    subActivity.ParentId = activity.Id;
                    subActivity.Date = dictionaryValues["Date"];
                    subActivity.DateFinal = dictionaryValues["DateFinal"];
                    subActivity.TypeId = 9; //9 = id do tipo de atividade "Protocolo"
                    subActivity.Subject = activity.Subject;

                    subActivity.Client = activity.Client;
                    subActivity.Sponsor = activity.Sponsor;

                    subActivity.Fields.Add(@"1", subActivity.Client);
                    subActivity.Fields.Add(@"2", subActivity.Sponsor);
                    subActivity.Fields.Add(@"3", activity.ProcessNumber);
                    subActivity.Fields.Add(@"4", dictionaryValues["URL da atividade"]);
                    subActivity.Fields.Add(@"5", activity.ProcessURL != null ? activity.ProcessURL : @"");
                    subActivity.Fields.Add(@"6", activity.Sharepoint != null ? activity.Sharepoint : @"");

                    subActivity.createActivity();

                    this.DictionaryValues.Remove(@"Responser");
                    this.DictionaryValues.Remove(@"ResponserEmail");
                    this.DictionaryValues.Remove(@"Subject");
                    this.DictionaryValues.Remove(@"Date");
                    this.DictionaryValues.Remove(@"DateFinal");
                    this.DictionaryValues.Remove(@"SearchElements.Fields.Tipo");

                    //append do mapeamento
                    this.DictionaryValues.Remove(@"1");
                    this.DictionaryValues.Remove(@"2");
                    this.DictionaryValues.Remove(@"3");
                    this.DictionaryValues.Remove(@"4");
                    this.DictionaryValues.Remove(@"5");
                    this.DictionaryValues.Remove(@"6");
                }*/

                List<Models.Source.Action> doneActivityActions =
                        Source.BlockElements.Where(be => be.Name == @"DoneActivity").FirstOrDefault().Actions;
                if (doneActivityActions != null)
                {
                    foreach (Models.Source.Action action in doneActivityActions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;
                    }
                }

                activity.DoneActivity();
            });

            Main.Start();
        }
        public void OldUploadAttachments(Models.ZFlow.Activity activity)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                /*if (activity.Attachments.Count() == 0)
                {
                    activity.UpdateActivitySycn(2);
                    return;
                }*/
                string clientFolder = activity.ClientCode != null ? $"{activity.ClientCode} {activity.Client}" : activity.Client;

                string numberFolder = $"Consultas/{clientFolder}/{activity.ProcessNumber}";

                string attachmentsFolder = activity.Action == @"Sharepoint" ? @"Anexos Recebidos" : @"Anexos Enviados";

                string subDir = activity.Attachments.Count() == 0 ? numberFolder : $"{numberFolder}/{attachmentsFolder}";

                ZionExchangeManagement.ZionSharePointManager manager =
                    new ZionExchangeManagement.ZionSharePointManager(Persistence.SoaresPiconSharePoint.UserName, Persistence.SoaresPiconSharePoint.Password);
                manager.ConnectToSharePointOnline(Persistence.SoaresPiconSharePoint.ConsultaUrl);

                var collection = manager.GetCollection("Documentos");

                var folder = manager.GetFolder(collection, subDir.Trim('/'));

                if ((folder.Name != subDir.Split('/').Last() || !folder.Name.StartsWith(subDir.Split('/').Last())))
                {
                    folder = manager.BuildFolder(collection, subDir);
                }

                Microsoft.SharePoint.Client.File file = null;

                foreach (Models.ZFlow.Attachment attach in activity.Attachments)
                {
                    file = manager.UploadFile(folder, attach.Name, attach.Content);
                    if (file == null)
                    {
                        activity.UpdateActivitySycn(3);
                        return;
                    }

                    attach.Link = new Uri($"{Persistence.SoaresPiconSharePoint.SiteUrl}{file.ServerRelativeUrl}");
                    attach.UpdateLinkOnZion();
                }

                if ((folder.Name != numberFolder.Split('/').Last() || !folder.Name.StartsWith(numberFolder.Split('/').Last())))
                {
                    folder = manager.GetFolder(collection, numberFolder);
                }
                HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                htmlDoc.LoadHtml(activity.EmailContent);
                string result = htmlDoc.DocumentNode.SelectSingleNode("//body").InnerText;
                //string result = htmlDoc.DocumentNode.InnerHtml;

                //byte[] emailContent = System.Text.Encoding.UTF8.GetBytes(activity.EmailContent);
                byte[] emailContent = System.Text.Encoding.UTF8.GetBytes(result);
                file = manager.UploadFile(folder, $"{activity.EmailSubject}.txt", Convert.ToBase64String(emailContent));

                activity.Sharepoint = new Uri($"{Persistence.SoaresPiconSharePoint.SiteUrl}/{folder.ServerRelativeUrl}").AbsoluteUri;
                activity.UpdateActivityFieldValue(@"Link do Sharepoint", activity.Sharepoint);
                activity.UpdateActivitySycn(2);
            });

            Main.Start();
        }
        public void UploadAttachments(Models.ZFlow.Activity activity)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                try
                {

                    string clientFolder = activity.ClientCode != null && activity.ClientCode != string.Empty ? $"{activity.ClientCode} {activity.Client}" : activity.Client;

                    string numberFolder = $"Consultas/{clientFolder}/{activity.ProcessNumber}";

                    string attachmentsFolder = null;

                    string emailContent = null;
                    string emailSubject = null;

                    if (string.IsNullOrEmpty(activity.EmailReplyContent))
                    {
                        attachmentsFolder = @"Anexos Recebidos";
                        emailContent = activity.EmailContent;
                        emailSubject = activity.EmailSubject;
                    }
                    else
                    {
                        attachmentsFolder = @"Anexos Enviados";
                        emailContent = activity.EmailReplyContent;
                        emailSubject = activity.EmailSubject;
                    }

                    string subDir = activity.Attachments.Count() == 0 ? numberFolder : $"{numberFolder}/{attachmentsFolder}";

                    ZionExchangeManagement.ZionSharePointManager manager =
                        new ZionExchangeManagement.ZionSharePointManager(Persistence.SoaresPiconSharePoint.UserName, Persistence.SoaresPiconSharePoint.Password);
                    manager.ConnectToSharePointOnline(Persistence.SoaresPiconSharePoint.ConsultaUrl);

                    var collection = manager.GetCollection("Documentos");

                    var folder = manager.GetFolder(collection, subDir.Trim('/'));

                    if ((folder.Name != subDir.Split('/').Last() || !folder.Name.StartsWith(subDir.Split('/').Last())))
                    {
                        folder = manager.BuildFolder(collection, subDir);
                    }

                    Microsoft.SharePoint.Client.File file = null;

                    foreach (Models.ZFlow.Attachment attach in activity.Attachments)
                    {
                        file = manager.UploadFile(folder, attach.Name, attach.Content);
                        if (file == null)
                        {
                            activity.UpdateActivitySycn(3);
                            return;
                        }

                        attach.Link = new Uri($"{Persistence.SoaresPiconSharePoint.SiteUrl}{file.ServerRelativeUrl}");
                        attach.UpdateLinkOnZion();
                    }

                    if ((folder.Name != numberFolder.Split('/').Last() || !folder.Name.StartsWith(numberFolder.Split('/').Last())))
                    {
                        folder = manager.GetFolder(collection, numberFolder);
                    }

                    activity.Sharepoint = new Uri($"{Persistence.SoaresPiconSharePoint.SiteUrl}/{folder.ServerRelativeUrl}").AbsoluteUri;
                    activity.UpdateActivityFieldValue(@"Link do Sharepoint", activity.Sharepoint);

                    if (string.IsNullOrEmpty(emailContent))
                    {
                        activity.UpdateActivitySycn(2);
                        return;
                    }

                    HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                    htmlDoc.LoadHtml(emailContent);

                    string result = htmlDoc.DocumentNode.InnerHtml;

                    string to = activity.EmailTo ?? @"consultas@soarespicon.adv.br";
                    string from = @"consultas@soarespicon.adv.br";
                    string subject = emailSubject;
                    string body = result;
                    string tempDir = @"C:\Temp\Email";

                    using (System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient())
                    {
                        System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage(from, to, subject, body);

                        msg.IsBodyHtml = true;
                        msg.BodyEncoding = System.Text.Encoding.UTF8;

                        client.UseDefaultCredentials = true;
                        client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.SpecifiedPickupDirectory;
                        client.PickupDirectoryLocation = tempDir;

                        try
                        {
                            client.Send(msg);
                        }
                        catch (Exception ex)
                        {
                            System.Environment.Exit(-1);
                        }
                    }

                    System.IO.FileInfo msgTemp = new
                       System.IO.DirectoryInfo(tempDir).GetFiles()
                          .OrderByDescending(f => f.LastWriteTime)
                          .First();

                    file = null;
                    file = manager.UploadFile(folder, $"{subject}.eml", msgTemp.FullName);

                    if (file == null)
                    {
                        activity.UpdateActivitySycn(3);
                        return;
                    }

                    System.IO.File.Delete(msgTemp.FullName);

                    activity.UpdateActivitySycn(2);
                }
                catch (Exception ex)
                {

                    activity.UpdateActivitySycn(12);
                }

            });

            Main.Start();
        }
        public void CreateSubActivity(Models.ZFlow.Activity activity)
        {
            this.Activity = activity;
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> createActivityActions = new List<Models.Source.Action>();

                //this.DictionaryValues.Add(@"ActivityUrl", activity.ParentDataJuri);

                /*if(activity.Group.ToUpper() == "CONSULTAS")
                {
                    createActivityActions = Source.BlockElements.Where(be => be.Name == @"CreateConsultaActivity").FirstOrDefault().Actions;

                    this.DictionaryValues.Add(@"UrlToCreate", activity.ParentDataJuri ?? activity.CaseURL);
                } else
                {

                    createActivityActions = Source.BlockElements.Where(be => be.Name == @"CreateActivity").FirstOrDefault().Actions;

                    this.DictionaryValues.Add(@"UrlToCreate", activity.ParentDataJuri ?? activity.ProcessURL);
                    
                    if (!string.IsNullOrEmpty(activity.Content))
                    {
                        this.DictionaryValues.Add(@"Content", activity.Content);
                    }

                }*/

                createActivityActions = Source.BlockElements.Where(be => be.Name == @"CreateActivity").FirstOrDefault().Actions;

                this.DictionaryValues.Add(@"UrlToCreate", activity.ParentDataJuri ?? activity.CaseURL ??  activity.ProcessURL);

                if (!string.IsNullOrEmpty(activity.Content))
                {
                    try
                    {
                        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                        doc.LoadHtml(activity.Content);
                        this.DictionaryValues.Add(@"Content", doc.DocumentNode.InnerText.Replace("&nbsp;", string.Empty));
                    }
                    catch (Exception)
                    {
                        this.DictionaryValues.Add(@"Content", activity.Content);
                    }
                }

                //this.DictionaryValues.Add(@"ActivityUrl", activity.ParentDataJuri);
                this.DictionaryValues.Add(@"ZionId", activity.Id.ToString());
                this.DictionaryValues.Add(@"Responser", activity.Sponsor);
                this.DictionaryValues.Add(@"ResponserEmail", activity.SponsorEmail);
                this.DictionaryValues.Add(@"Subject", activity.Subject);
                this.DictionaryValues.Add(@"Date", Helpers.Shift.formatDate(activity.Date, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"DateFinal", Helpers.Shift.formatDate(activity.DateFinal, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"Group", activity.Group);
                this.DictionaryValues.Add(@"SearchElements.Fields.Tipo", @"Publicação");

                if (!string.IsNullOrEmpty(activity.Hour))
                {
                    this.DictionaryValues.Add(@"Hour", activity.Hour);
                }

                foreach (Models.Source.Action action in createActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if(this.dictionaryValues.ContainsKey("URL da atividade"))
                {
                    activity.DataJuri = this.dictionaryValues["URL da atividade"];
                    activity.UpdateActivityUrl();
                    activity.UpdateActivitySycn(2);

                } else
                {
                    activity.UpdateActivitySycn(5);

                }
            });

            Main.Start();
        }
        public void CreateCase(Models.ZFlow.Activity activity)
        {
            this.Activity = activity;
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateCase").FirstOrDefault().Actions;

                HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                htmlDoc.LoadHtml(activity.EmailContent);
                string result = htmlDoc.DocumentNode.InnerText;

                this.DictionaryValues.Add(@"CaseURL", activity.CaseURL);
                this.DictionaryValues.Add(@"Responser", activity.Sponsor);
                this.DictionaryValues.Add(@"ResponserEmail", activity.SponsorEmail);
                this.DictionaryValues.Add(@"Area", this.translateArea(activity.Subject));
                this.DictionaryValues.Add(@"CreatedAt", Helpers.Shift.formatDate(activity.CreatedAt, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"EmailSubject", activity.EmailSubject);
                this.DictionaryValues.Add(@"EmailContent", result);
                this.DictionaryValues.Add(@"Priority", activity.Priority);
                this.DictionaryValues.Add(@"Sharepoint", activity.Sharepoint);
                this.DictionaryValues.Add(@"Client", activity.Client);
                this.DictionaryValues.Add(@"FolderNumber", activity.ProcessNumber);

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                if (this.dictionaryValues.ContainsKey("CaseUrl"))
                {
                    activity.CaseURL = this.dictionaryValues["CaseUrl"];
                    activity.UpdateActivityFieldValue(@"Link do Caso", activity.CaseURL);
                    activity.UpdateActivitySycn(2);

                }
                else
                {
                    activity.UpdateActivitySycn(5);

                }

            });

            Main.Start();
        }
        public void CloseCase(Models.ZFlow.Activity activity)
        {
            this.Activity = activity;
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;

                List<Models.Source.Action> UpdateActivityActions =
                    Source.BlockElements.Where(be => be.Name == @"CloseCase").FirstOrDefault().Actions;

                HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                htmlDoc.LoadHtml(activity.EmailReplyContent);
                string result = htmlDoc.DocumentNode.InnerText;

                this.DictionaryValues.Add(@"CaseUrl", activity.CaseURL);
                this.DictionaryValues.Add(@"Responser", activity.Sponsor);
                this.DictionaryValues.Add(@"Client", activity.Client);
                this.DictionaryValues.Add(@"SyncCreateAt", Helpers.Shift.formatDate(activity.SyncCreateAt, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"EmailReplyContent", result);

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                activity.UpdateActivitySycn(2);

            });

            Main.Start();
        }
        private string translateArea(string area)
        {
            switch (area)
            {
                case "Trabalhista - Justa Causa":
                case "Trabalhista - Outras Sanções":
                case "Trabalhista - Contrato de Trabalho":
                case "Trabalhista - Estágio":
                case "Trabalhista - Afastamento INSS":
                case "Trabalhista - Outros":
                    return @"Trabalhista";
                case "Contratos - Prestação de Serviços":
                case "Contratos - Locação":
                case "Contratos - Compra e Venda":
                case "Contratos - Plano de saúde (Convênios)":
                case "Contratos - Internacional":
                case "Contratos - Outros":
                    return @"Contratos";
                default:
                    return area;
            }
        }
        public void UpdateActivity(Models.ZFlow.Activity activity)
        {
            this.Activity = activity;
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;
                List<Models.Source.Action> UpdateActivityActions = activity.Status == "2" ?
                    Source.BlockElements.Where(be => be.Name == @"FinalizeActivity").FirstOrDefault().Actions :
                    Source.BlockElements.Where(be => be.Name ==
                        (activity.CaseURL != null ? @"UpdateActivityConsulta" : @"UpdateActivity")).FirstOrDefault().Actions;

                this.DictionaryValues.Add(@"ZionId", activity.Id.ToString());
                this.DictionaryValues.Add(@"ActivityUrl", activity.DataJuri);
                this.DictionaryValues.Add(@"Responser", activity.Sponsor);
                this.DictionaryValues.Add(@"ResponserEmail", activity.SponsorEmail);
                this.DictionaryValues.Add(@"Subject", activity.Subject);
                this.DictionaryValues.Add(@"Date", Helpers.Shift.formatDate(activity.Date, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"DateFinal", Helpers.Shift.formatDate(activity.DateFinal, @"dd/MM/yyyy"));
                this.DictionaryValues.Add(@"Group", activity.Group);
                this.DictionaryValues.Add(@"SearchElements.Fields.Tipo", @"Publicação");
                this.DictionaryValues.Add(@"ActivityStatus", this.translateActivityStatus(activity.Status));
                this.DictionaryValues.Add(@"Client", activity.Client);
                this.DictionaryValues.Add(@"FolderNumber", activity.ProcessNumber);

                if (!string.IsNullOrEmpty(activity.Hour))
                {
                    this.DictionaryValues.Add(@"Hour", activity.Hour);
                }

                if (!string.IsNullOrEmpty(activity.Content))
                {
                    try
                    {
                        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                        doc.LoadHtml(activity.Content);
                        this.DictionaryValues.Add(@"Content", doc.DocumentNode.InnerText.Replace("&nbsp;", string.Empty));
                    }
                    catch (Exception)
                    {
                        this.DictionaryValues.Add(@"Content", activity.Content);
                    }
                }

                if (activity.Comment != null)
                {
                    this.DictionaryValues.Add(@"CommentResponser", activity.CommentCreateBy);
                    this.DictionaryValues.Add(@"CommentSubject", activity.Subject);
                    this.DictionaryValues.Add(@"CommentValue", activity.Comment);
                }

                if (!string.IsNullOrEmpty(activity.Parecer))
                {
                    HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
                    htmlDoc.LoadHtml(activity.Parecer);
                    string result = htmlDoc.DocumentNode.InnerText;
                    this.DictionaryValues.Add(@"ActivityParecer",result);
                }

                foreach (Models.Source.Action action in UpdateActivityActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                activity.UpdateActivitySycn(2);

            });

            Main.Start();
        }
        private string translateActivityStatus(string status)
        {
            switch (status)
            {
                case "":
                case "0":
                    status = "Cancelado";
                    break;
                case "2":
                case "3":
                    status = "Concluído";
                    break;
                case "4":
                    status = "Aguardando";
                    break;
                default:
                    status = "Não iniciado";
                    break;
            }

            return status;
        }
        public void SyncActivityCanceling(Models.ZFlow.Activity activity)
        {
            System.Windows.Application.Current.Dispatcher.Invoke((System.Action)delegate
            {
                this.Visibility = Visibility.Visible;
                this.ShowInTaskbar = true;
                //this.Visibility = Visibility.Hidden;
                //this.ShowInTaskbar = false;
                this.Show();
                this.terminate = false;
            });

            main = new System.Threading.Thread(() =>
            {
                bool execute = true;
                //this.DictionaryValues.Add(@"ActivityUrl",
                                   //Persistence.DataJuri.Host + Persistence.DataJuri.Activity + activity.DataJuri);
                this.DictionaryValues.Add(@"ActivityUrl", activity.DataJuri);
                
                /*foreach (Models.Source.ActionsElement actionElement in Source.ActionsElements)
                {
                    foreach (Models.Source.Action action in actionElement.Actions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;
                    }
                }*/

                List<Models.Source.Action> authenticateActions =
                    Source.BlockElements.Where(be => be.Name == @"Authenticate").FirstOrDefault().Actions;

                foreach (Models.Source.Action action in authenticateActions)
                {
                    Task<bool> task = executeAction(action);
                    task.Wait();
                    execute = task.Result;
                }

                List<Models.Source.Action> createCommentActions =
                    Source.BlockElements.Where(be => be.Name == @"CreateComment").FirstOrDefault().Actions;

                if (createCommentActions != null)
                {
                    activity.Comments.OrderBy(c => c.CreatedAt).ToList().ForEach(comment =>
                    {
                        this.DictionaryValues.Add(@"CommentResponser", comment.CreatedByName);
                        this.DictionaryValues.Add(@"CommentSubject", comment.Subject);
                        this.DictionaryValues.Add(@"CommentValue", comment.Value);

                        foreach (Models.Source.Action action in createCommentActions)
                        {
                            Task<bool> task = executeAction(action);
                            task.Wait();
                            execute = task.Result;
                        }

                        this.DictionaryValues.Remove(@"CommentResponser");
                        this.DictionaryValues.Remove(@"CommentSubject");
                        this.DictionaryValues.Remove(@"CommentValue");

                    });
                }

                List<Models.Source.Action> cancelingActivityActions =
                        Source.BlockElements.Where(be => be.Name == @"CancelingActivity").FirstOrDefault().Actions;
                if (cancelingActivityActions != null)
                {
                    foreach (Models.Source.Action action in cancelingActivityActions)
                    {
                        Task<bool> task = executeAction(action);
                        task.Wait();
                        execute = task.Result;
                    }
                }

                activity.CanceledActivity();

            });

            Main.Start();
        }
        #endregion
        private async Task<bool> executeAction(Models.Source.Action action)
        {
            switch (action.Type.ToUpper())
            {
                case "BLOCK":
                    return executeBLock(action);
                case "NAVIGATE":
                    return await navigate(action);
                case "CHECKDOMAIN":
                    return checkDomain(action);
                case "CHECKINPUT":
                    return checkInput(action);
                case "READ":
                    return readResultsFromPage(action);
                case "READJSON":
                    return readJson(action);
                case "FILL":
                    return fillInput(action);
                case "SELECT":
                    return selectOption(action);
                case "CLICK":
                    return await clickButton(action);
                case "IF":
                    return executeIf(action);
                case "LOOP":
                    return action.Value == @"true" ?
                        await loopWithBoolean(action) : await loopWithOperator(action);
                case "INVOKE":
                    return invoke(action);
                case "GOBACK":
                    return await goBack(action);
                case "APPENDDATA":
                    return appendData(action);
                case "LOG":
                    return saveIntegrationLog(action);
                case "CHANGEATTRIBUTEVALUE":
                    return changeAttributeValue(action);
                case "APPENDFROMAPI":
                    return appendFromApi(action);
                case "CHECKDICTIONARYKEY":
                    return checkDictionaryKey(action);
                default:
                    throw new NotImplementedException();
            }
        }
        #region Actions Methods
        private List<mshtml.IHTMLElement> getHTMLElements(string where, mshtml.IHTMLElementCollection elementCollection = null)
        {
            var htmlDoc = GetHTMLDocument();

            if (htmlDoc.all == null && elementCollection == null)
                return new List<mshtml.IHTMLElement>();

            List<mshtml.IHTMLElementCollection> list = 
                new List<mshtml.IHTMLElementCollection>() { elementCollection != null ? elementCollection : htmlDoc.all };

            //browser.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new System.Action(() => {

            //    for (int i = 0; i < htmlDoc.frames.length; i++)
            //    {
            //        object index = i;
            //        mshtml.HTMLWindow2 doc = (mshtml.HTMLWindow2)htmlDoc.frames.item(ref index);

            //        if((mshtml.HTMLDocument)doc.document.body != null)
            //            list.Add(((mshtml.HTMLDocument)doc.document.body.document).all);

            //    }
            //}));

            return Helpers.CQuery.Find(where, list);
        }
        private bool checkDictionaryKey(Models.Source.Action action)
        {
            if (this.dictionaryValues.ContainsKey(action.Value) && action.ResultTrue.Count > 0)
            {
                action.ResultTrue.ForEach(a =>
                {
                    executeAction(a).Wait();
                });
                return true;
            }
            else if (action.ResultFalse.Count > 0)
            {
                action.ResultFalse.ForEach(a =>
                {
                    executeAction(a).Wait();
                });
                return true;
            }
            return false;
        }
        private bool appendFromApi(Models.Source.Action action)
        {
            try
            {
                string value = action.ReplaceWithDictionary(action.Where, DictionaryValues);

                
                var result = new ZionVault.WebService.Client(Persistence.WSProperties.UrlApi)._request("GET",
                    value,
                    Persistence.WSProperties.Token,
                    null,
                    string.Empty,
                    null);

                var jsonSerialiser = new System.Web.Script.Serialization.JavaScriptSerializer();

                var json = jsonSerialiser.Deserialize<Dictionary<string, string>>(result);

                json.ToList().ForEach(j => this.dictionaryValues.Add(j.Key, j.Value));

                return true;
            } catch (Exception ex)
            {
                return false;
            }
        }
        private bool changeAttributeValue(Models.Source.Action action)
        {
            mshtml.IHTMLElement element = getHTMLElements(action.Where).FirstOrDefault();

            if (element == null)
                return false;

            string[] parts = action.Value.Split(@"=".ToCharArray(), 2); ;

            element.setAttribute(parts[0], parts.Length == 1 ? string.Empty : parts[1]);

            return true;
        }
        private bool readJson(Models.Source.Action action)
        {
            try
            {
                using (System.Net.WebClient wc = new System.Net.WebClient() { Encoding = System.Text.Encoding.UTF8 })
                {
                    string result = ReplaceActionsValue(action);
                    string json = wc.DownloadString(result);

                    if (string.IsNullOrEmpty(json))
                        return false;

                    Models.AASP.IntimacoesCollection IC =
                        System.Text.Json.JsonSerializer.Deserialize<Models.AASP.IntimacoesCollection>(json,
                        new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true });


                    IC.Intimacoes.ForEach(intimacao =>
                    {
                        List<Models.Search.Element> listElements = new List<Models.Search.Element>();
                        source.SearchElements.ForEach(element =>
                        {
                            //string value = string.Empty;
                            //value = element.Where.ToUpper() == @"ALL" ? intimacao.GetAllParam() : intimacao.GetParamValue(element.Where);

                            element.Value = element.Where.ToUpper() == @"ALL" ? intimacao.GetParamAASP() : intimacao.GetParamValue(element.Where);

                            listElements.Add(
                                new Models.Search.Element(
                                    element.Name,
                                    element.Where,
                                    element.Value,
                                    element.GoTo,
                                    element.IsHtml,
                                    element.Attribute));
                        });
                        this.searchElements.Add(listElements);
                    });

                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
            
        }
        private bool invokeOnClick(Models.Source.Action action)
        {
            mshtml.IHTMLElement element = getHTMLElements(action.Where).FirstOrDefault();

            if (element != null)
            {
                return true;
            }

            return false;
        }

        private bool executeBLock(Models.Source.Action action)
        {
            Models.Source.BlockElement block = source.BlockElements.Where(b => b.Name == action.Value).FirstOrDefault();
            if (block != null)
            {
                foreach (Models.Source.Action a in block.Actions)
                {
                    //executeAction(a).Wait();
                    var task = executeAction(a);
                    task.Wait();
                    /*if (!task.Result)
                        return false;*/
                }
                /*block.Actions.ForEach(a =>
                {
                    executeAction(a).Wait();
                });*/
                return true;
            }
            return false;
        }

        private async Task<bool> navigate(Models.Source.Action action)
        {
            string val = ReplaceActionsValue(action);
           
                browser.Dispatcher.Invoke(() => {
                    try
                    {
                        Uri uri = new Uri(val);
                        browser.Navigate(uri.AbsoluteUri);
                    }
                    catch (Exception)
                    {
                        string text = string.Format("Id: {0} Type: {1} Url: {2} \n", 
                            this.Activity.Id, this.Activity.TypeId, this.Activity.DataJuri/*, this.dictionaryValues[@"ActivityUrl"]*/);
                        System.IO.File.AppendAllText(@"C:\Temp\ActivitySYNC.txt", text);
                        main.Abort();
                    }

                });
            
            wait = true;
            Wait();
            return true;
        }

        private bool readResultsFromPage(Models.Source.Action action)
        {
            List<mshtml.IHTMLElement> hElements = getHTMLElements(action.Where).ToList();

            if (hElements.Count == 0)
                return false;

            hElements.ForEach(hElement =>
            {
                //System.IO.File.AppendAllText(@"C:\Robot\SearchResults\AASP\20210107\texto.txt", ((mshtml.IHTMLElement)hElement.all).innerText + "\n -----------------\n");

                List<Models.Search.Element> listElements = new List<Models.Search.Element>();
                source.SearchElements.ForEach(element =>
                {
                    if (string.IsNullOrEmpty(element.Attribute))
                        element.Value = getHTMLElements(
                            element.Where, ((mshtml.IHTMLElementCollection)hElement.all)).FirstOrDefault()?.innerText ?? string.Empty;
                    else
                        element.Value = hElement.getAttribute(element.Attribute);


                    element.Value = Regex.Replace(element.Value, @"  Exibir comentários  Inserir comentários ", string.Empty);

                    if (element.IsHtml)
                    {
                        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                        doc.LoadHtml(element.Value);
                        element.Value = doc.DocumentNode.InnerText;
                        doc = null;
                    }

                    listElements.Add(new Models.Search.Element(element.Name, element.Where, element.Value, element.GoTo, element.IsHtml, element.Attribute));
                });

                this.searchElements.Add(listElements);
            });


            return true;
        }

        private bool invoke(Models.Source.Action action)
        {
            if (action.Where != null)
            {
                mshtml.IHTMLElement element = getHTMLElements(action.Where.Replace("@", "")).FirstOrDefault();

                if (element != null)
                {
                    string[] parts = ((string)element.getAttribute(@"href")).Split('(');
                    string scriptName = parts[0].Replace(@"javascript:", string.Empty);
                    string[] args = parts[1].Trim(')').Replace("'", string.Empty).Split(',');


                    var elementTemp = string.IsNullOrEmpty(action.Check) ? 
                        null : getHTMLElements(action.Check).First();

                    browser.Dispatcher.Invoke(() =>
                    {
                        browser.InvokeScript(scriptName, args);
                    });

                    //if (action.Check != null)
                    //{

                        if (elementTemp != null)
                        {
                            while (Helpers.CQuery.CompareInnerHtmlByElements(elementTemp, getHTMLElements(action.Check).First()))
                            {
                                System.Threading.Thread.Sleep(200);
                            }
                            return true;
                        }
                    //}

                    return true;
                }
            }

            if (action.Value != null)
            {
                if (System.Text.RegularExpressions.Regex.IsMatch(action.Value, @"javascript"))
                {
                    string[] parts = action.Value.Split('(');
                    string scriptName = parts[0].Trim().Replace(@"javascript:", string.Empty).Trim();
                    string[] args = parts[1].Trim(')').Replace("'", string.Empty).Split(',');

                    mshtml.IHTMLElement elementTemp = string.IsNullOrEmpty(action.Check) ? 
                                                        null : getHTMLElements(action.Check).First();

                    browser.Dispatcher.Invoke(() =>
                    {
                        browser.InvokeScript(scriptName, args);
                    });

                    if (elementTemp != null)
                    {
                        while (Helpers.CQuery.CompareInnerHtmlByElements(elementTemp, getHTMLElements(action.Check).First()))
                        {
                            System.Threading.Thread.Sleep(200);
                        }
                        return true;
                    }

                    /*if (action.Check != null)
                    {
                        var elementTemp = getHTMLElements(action.Check).First();

                        if (elementTemp != null)
                        {
                            while (Helpers.CQuery.CompareInnerHtmlByElements(elementTemp, getHTMLElements(action.Check).First()))
                            {
                                Thread.Sleep(200);
                            }
                            return true;
                        }
                    }*/

                    return true;
                }
            }

            return false;
        }

        private bool fillInput(Models.Source.Action action)
        {
            List<mshtml.IHTMLElement> elements = getHTMLElements(action.Where);
            if (elements.Count > 0)
            {
                elements.ForEach(element =>
                {
                    element.setAttribute("value", ReplaceActionsValue(action));
                });
                return true;
            }

            return false;
        }

        private bool checkInput(Models.Source.Action action)
        {
            mshtml.IHTMLElement element = getHTMLElements(action.Where).FirstOrDefault();

            if (element == null)
                return false;
            string value = ReplaceActionsValue(action);

            switch (value.ToUpper())
            {
                case "0":
                case "NÃO":
                    value = "False";
                    break;
                case "1":
                case "SIM":
                case "TRUE":
                    value = "True";
                    break;
                default:
                    value = "False";
                    break;
            }
            var x = bool.Parse(value);
            (element as mshtml.HTMLInputElement).@checked = bool.Parse(value);

            return true;
        }

        private bool selectOption(Models.Source.Action action)
        {
            string value = action.ReplaceWithDictionary(action.Where, DictionaryValues);
            mshtml.IHTMLElement element = getHTMLElements(value).FirstOrDefault();

            if (element != null)
            {
                element.setAttribute(@"selected", @"Selected");

                return true;
            };
            return false;
            //throw new Exception(@"selectOption - não achou elemento");
        }

        private async Task<bool> clickButton(Models.Source.Action action)
        {

            mshtml.IHTMLElement elementTemp = action.Check != null ? getHTMLElements(action.Check).First() : null;

            mshtml.IHTMLElement element =
                action.Index >= 0 ?
                getHTMLElements(action.Where)?[action.Index] ?? null :
                getHTMLElements(action.Where).FirstOrDefault();

            if (element != null)
            {
                element.click();

                if (elementTemp != null)
                {

                    var a = (elementTemp as mshtml.HTMLDocument).body.innerText;
                    var b = (getHTMLElements(action.Check).First() as mshtml.HTMLDocument).body.innerText;
                    while (Helpers.CQuery.CompareInnerHtmlByElements(elementTemp, getHTMLElements(action.Check).First()))
                    {
                        System.Threading.Thread.Sleep(200);
                    }
                    return true;
                }
                else
                {
                    if (action.Wait)
                    {
                        wait = true;
                    }
                    Wait();
                    return true;
                }
            };
            return false;
            //throw new Exception(@"clickButton - não achou elemento");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="action"></param>
        /// <operator name="==">Igual</operator>
        /// <operator name="!=">Diferente</operator>
        /// <operator name="===">IsMach</operator>
        /// <operator name="!==">! IsMach</operator>
        /// <operator name="=_=">Esxist o element</operator>
        /// <returns></returns>
        private bool executeIf(Models.Source.Action action)
        {
            string @operator =
            Regex.Matches(action.Value, @"([!=_<>]{1,2}=?)|\d+").Cast<Match>().Select(match => match.Value).First();

            string[] parts = action.Value.Split(new string[] { @operator }, StringSplitOptions.RemoveEmptyEntries);

            string value = string.Empty;
            if (parts.Count() > 0)
            {
                value = action.ReplaceWithDictionary(parts[0], DictionaryValues);

                value = value.Replace(@operator, string.Empty);
            }
            
            mshtml.IHTMLElement element = getHTMLElements(action.Where).FirstOrDefault();

            if (element != null)
            {
                var fa = element.innerText;
                var x = fa == value;
                var y = parts.Count();
                if (@operator == @"=_=" ||
                    (@operator == @"==" && element.innerText == value) ||
                    (@operator == @"==" && parts.Count() > 1 && 
                        action.ReplaceWithDictionary(parts[0], DictionaryValues) ==
                        action.ReplaceWithDictionary(parts[1], DictionaryValues)) ||
                    (@operator == @"===" && Regex.IsMatch(element.innerText, value)) ||
                    (@operator == @"!=" && element.innerText != value) ||
                    (@operator == @"!==" && !Regex.IsMatch(element.innerText, value))

                    )
                {
                    action.ResultTrue.ForEach(a =>
                    {
                        executeAction(a).Wait();
                    });
                    return true;
                }
                else if (action.ResultFalse.Count > 0)
                {
                    Console.WriteLine(@"ELLSEEEEEEE");
                    action.ResultFalse.ForEach(a =>
                    {
                        executeAction(a).Wait();
                    });
                    return true;
                }
            }
            
            
            return false;
        }

        private async Task<bool> loopWithOperator(Models.Source.Action action)
        {
            string val = action.ReplaceWithDictionary(action.Value, DictionaryValues);

            List<string> parts =
                Regex.Matches(val,
                    @"(&lt;=?|&gt;=?|[!=<>]{1}=?)|\d+").Cast<Match>().Select(match => match.Value).ToList();

            bool executeAllActions = true;
            int count = 0;
            while (
                (parts[0] == @"<" || parts[0] == @"&lt;") && count < int.Parse(parts[1]) ||
                (parts[0] == @"<=" || parts[0] == @"&lt;=") && count <= int.Parse(parts[1]) ||
                (parts[0] == @">" || parts[0] == @"&gt;") && count > int.Parse(parts[1]) ||
                (parts[0] == @">=" || parts[0] == @"&gt;=") && count >= int.Parse(parts[1]) ||
                parts[0] == @"==" && count == int.Parse(parts[1]) ||
                parts[0] == @"!=" && count != int.Parse(parts[1]))
            {

                foreach (Models.Source.Action a in action.InnerActions)
                {
                    if (!(await this.executeAction(a)))
                    {
                        break;
                    }
                }

                /*action.InnerActions.ForEach(innerAction =>
                {
                    //TODO: adicionar try catch
                    this.executeAction(innerAction).Wait();
                    executeAllActions = true;
                });*/
                count++;
            }
            return executeAllActions;
        }

        private async Task<bool> loopWithBoolean(Models.Source.Action action)
        {
            bool value = bool.Parse(action.Value);
            while (value)
            {
                foreach (Models.Source.Action a in action.InnerActions)
                {
                    if (!(await this.executeAction(a)))
                    {
                        value = false;
                        break;
                    }
                }
                /*action.InnerActions.ForEach(innerAction =>
                 {
                     //TODO: adicionar try catch
                     this.executeAction(innerAction).Wait();
                     value = true;
                 });*/
            }
            return true;
        }

        private bool checkDomain(Models.Source.Action action)
        {
            mshtml.HTMLDocument doc = null;
            string domain = null;

            browser.Dispatcher.Invoke(new System.Action(() => {
                doc = (mshtml.HTMLDocument)browser.Document;
                if (doc != null)
                    domain = doc.domain;
            }));

            if (domain == null || domain == string.Empty || domain != source.Domain)
            {
                action.ResultTrue.ForEach(a =>
                {
                    executeAction(a).Wait();
                });
                return true;
            }

            return true;
        }

        private async Task<bool> goBack(Models.Source.Action action)
        {
            browser.Dispatcher.Invoke(() => {
                browser.GoBack();
            });

            wait = true;
            Wait();
            return true;
        }

        private bool appendData(Models.Source.Action action)
        {
            string actionWhere = action.ReplaceWithDictionary(action.Where, DictionaryValues);
            if (actionWhere == @"currentUrl")
            {
                DictionaryValues.Add(action.Value, getUrl());
                return true;
            }

            mshtml.IHTMLElement element =
                action.Regex != null ?
                getHTMLElements(actionWhere)
                .Where(e => e.innerText != null && Regex.IsMatch(e.innerText, action.Regex))
                .Select(e => e).FirstOrDefault()
                :
                getHTMLElements(actionWhere).FirstOrDefault();

            if (element != null)
            {

                if (DictionaryValues.FirstOrDefault(x => x.Key == action.Value).Key != null)
                    DictionaryValues.Remove(action.Value);

                if (action.Attribute != null)
                {
                    var a = (string)element.getAttribute(action.Attribute);
                    DictionaryValues.Add(action.Value, a);
                }
                else
                {
                    DictionaryValues.Add(action.Value, element.innerText);
                }
                return true;
            }
            return false;
        }

        private bool saveIntegrationLog(Models.Source.Action action)
        {
            string value = ReplaceActionsValue(action);

            System.IO.File.AppendAllText(
                $"{Persistence.Basic.LogsFolder}IntegrationLog.csv",
                string.Format("{0}{1}\n", DateTime.Now, value));

            /*string nrProcesso = fields.Where(f => f.FullName == @"SearchElements.Fields.NrProcesso").FirstOrDefault().Value;
            string data = fields.Where(f => f.FullName == @"SearchElements.Fields.Data").FirstOrDefault().Value;
            string responsavel = dictionary[@"EmailResponsavel"];

            System.IO.File.AppendAllText(
                $"{Persistence.Basic.LogsFolder}\\IntegrationiLog.txt", 
                string.Format("{0};{1};{2}\n", nrProcesso, data, responsavel));*/

            return true;
        }

        #endregion


        private string getUrl()
        {
            string url = string.Empty;

            browser.Dispatcher.Invoke(new System.Action(() => {
                url = browser.Source.AbsoluteUri;
            }));

            return url;
        }

        private mshtml.HTMLDocument GetHTMLDocument()
        {
            mshtml.HTMLDocument doc = null;

            //browser.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new System.Action(() => {
            //    doc = (mshtml.HTMLDocument)browser.Document;

            //    var document = browser.Document as mshtml.HTMLDocument;
            //    var inputs = document.getElementsByTagName("input");
            //    foreach (mshtml.IHTMLElement element in inputs)
            //    {
            //        mshtml.HTMLDocument a = element.document as mshtml.HTMLDocument;
            //        string html = a.documentElement.outerHTML;
            //    }

            //}));

            browser.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new System.Action(() => {
                doc = (mshtml.HTMLDocument)browser.Document;

            }));

            return doc;
        }

        private bool hasLog(string text)
        {
            foreach (string r in Persistence.Logs.SearchLog.SearchResults)
            {
                foreach (string v in r.Split(new string[] { @"||" }, StringSplitOptions.None).ToList())
                {
                    var ab = text.Replace(Environment.NewLine, @"");
                    if (v == ab)
                    {
                        return true;
                    }

                    if (v == text)
                    {
                        return true;
                    }
                }
            };
            return false;
            /*return (from result in Persistence.Logs.SearchLog.SearchResults
                    where result.Split(new string[] { @"||" }, StringSplitOptions.None).ToList()
                    .Contains(text.Replace(Environment.NewLine, @""))
                    select result).Any();*/
        }

        private string ReplaceActionsValue(Models.Source.Action action)
        {
            string value = string.Empty;
            List<string> parts = Regex.Matches(action.Value, @"\{[^\}]*\}|([:=\[\(\{]{0}[a-zA-Z0-9_%@\-\.\/:?=&;]{1,})")
                                    .Cast<Match>().Select(m => m.Value).ToList();
            parts.ForEach(part =>
            {
                string temp = part.Trim('{').Trim('}');
                string add = string.Empty;

                if (Regex.IsMatch(temp, @"\$_Now"))
                {
                    DateTime dateNow = DateTime.Now;
                    int day = 0;
                    //verificar se tem condição Now>16?2:1 => {Now>16} {2:1}
                    string[] p = temp.Split('?');

                    //quando não tem doncição
                    if (p.Count() == 1)
                    { //verificar se tem '.' Now.1 
                        if (Regex.IsMatch(p[0], @"\."))
                        {
                            day = int.Parse(temp.Split('.').Last());
                        }
                    }
                    else
                    {
                        string @operator =
                                Regex.Matches(p[0], @"([!=<>]{1,2}[<>=]?)")
                                .Cast<Match>().Select(match => match.Value).First();

                        //Ex: p[0] = Now>16 => {Now}{16}
                        string[] s = p[0].Split(new string[] { @operator }, StringSplitOptions.RemoveEmptyEntries);

                        int hours = int.Parse(s[1]);

                        //Ex: p[1] = 2:1 => {2}{1}
                        string[] days = p[1].Split(':');

                        if (@operator == @"==" && dateNow.Hour == hours ||
                            @operator == @"!=" && dateNow.Hour != hours ||
                            @operator == @"<=" && dateNow.Hour <= hours ||
                            @operator == @">=" && dateNow.Hour >= hours ||
                            @operator == @">" && dateNow.Hour > hours ||
                            @operator == @"<" && dateNow.Hour < hours)
                        {
                            day = int.Parse(days[0]);
                        }
                        else
                        {
                            day = int.Parse(days[1]);
                        }
                    }
                    add = day == 0 ? dateNow.ToString("dd/MM/yyyy") : getBusinessDay(DateTime.Now, day).ToString("dd/MM/yyyy");
                }

                if (DictionaryValues.ContainsKey(temp))
                {
                    if (string.IsNullOrEmpty(DictionaryValues[temp]))
                    {
                        part = string.Empty;
                    }
                    else
                    {
                        //TODO TIRAR O CHUMBO
                        if (action.Where == @"input[id=data_da_disponibilizStr]" &&
                            DictionaryValues[@"SearchElements.Fields.Tipo"] == @"Publicação")
                        {
                            add += getBusinessDay(DateTime.Parse(DictionaryValues[temp]), -1).ToString(@"dd/MM/yyyy");
                        }
                        else if (action.Where == @"input[id=data_de_publicacaoStr]" &&
                             (DictionaryValues[@"SearchElements.Fields.Tipo"] == @"Disponibilização"
                                ||
                             DictionaryValues[@"SearchElements.Fields.Tipo"] == @"Divulgação")
                             )
                        {
                            add += getBusinessDay(DateTime.Parse(DictionaryValues[temp]), 1).ToString(@"dd/MM/yyyy");
                        }
                        else
                        {
                            add += DictionaryValues[temp];
                        }
                    }
                }

                if (add != string.Empty)
                    value += add;
                else
                    value += Regex.Replace(part, @"amp;", string.Empty);
            });

            //value = value != string.Empty ? value : action.Value;
            if (!string.IsNullOrEmpty(action.Replace))
            {
                List<string> replaces = action.Replace.Split(';').ToList();

                replaces.ForEach(replace =>
                {
                    string[] r = replace.Split(',');

                    value = Regex.Replace(value, r[0], r[1]);

                });

            }

            var a = value.Substring(0, Math.Min(value.Length, action.MaxLength));

            return action.MaxLength > 0 ? value.Substring(0, Math.Min(value.Length, action.MaxLength)) : value;
        }

        private DateTime getBusinessDay(DateTime dateTime, int day)
        {
            DateTime currentDay = dateTime;
            if (day >= 0)
            {
                List<DateTime> dates = Helpers.Shift.getDaysWithInterval(currentDay);
                currentDay = dates[day];
            } else
            {
                int count = 0;
                while (count > day)
                {
                    currentDay = currentDay.AddDays(-1);
                    if (Helpers.Shift.isDuringTheWeek(currentDay))
                    {
                        count--;
                    }
                }
            }
            return currentDay;
        }
    }
}
