using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;

namespace ZionVault.Util
{
    public class SharePointManager
    {
        private Microsoft.SharePoint.Client.ClientContext context;
        private Microsoft.SharePoint.Client.Site site;

        public string UserName;
        public string UserPassword;

        public SharePointManager(string userName, string userPassword)
        {
            UserName = userName;
            UserPassword = userPassword;
        }

        public void ConnectToSharePointOnline(string siteUrl)
        {
            try
            {
                if (context != null)
                    context.Dispose();

                // Namespace: Microsoft.SharePoint.Client    
                context = new Microsoft.SharePoint.Client.ClientContext(siteUrl);

                // Namespace: System.Security  
                SecureString secureString = new SecureString();
                UserPassword.ToList().ForEach(secureString.AppendChar);

                context.Credentials = new Microsoft.SharePoint.Client.SharePointOnlineCredentials(UserName, secureString);

                // Namespace: Microsoft.SharePoint.Client    
                site = context.Site;

                context.Load(site);
                context.ExecuteQuery();

                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine($"Connected to {siteUrl}");
            }
            catch (Exception ex)
            {

                throw;
            }
        }

        private void CreateFolder(Microsoft.SharePoint.Client.Folder RootFolder, string FolderName)
        {
            context.Load(RootFolder.Folders);
            RootFolder.Folders.Add(FolderName);
            RootFolder.Update();
            context.ExecuteQuery();
        }

        private void LoadFolders(Microsoft.SharePoint.Client.Folder RootFolder)
        {
            context.Load(RootFolder.Folders);
            context.ExecuteQuery();
        }

        public List<Microsoft.SharePoint.Client.List> GetCollections()
        {
            context.Load(context.Web.Lists);
            context.ExecuteQuery();
            return context.Web.Lists.ToList();
        }

        public Microsoft.SharePoint.Client.List GetCollection(string title)
        {
            context.Load(context.Web.Lists);
            context.ExecuteQuery();
            return context.Web.Lists.ToList().Where(item => item.Title == title).FirstOrDefault();
        }

        public Microsoft.SharePoint.Client.Folder GetFolder(Microsoft.SharePoint.Client.List list, string folder)
        {
            List<string> folders = folder.Split('/').ToList();

            Microsoft.SharePoint.Client.Folder currentFolder = null;

            foreach (var current in folders)
            {
                if (currentFolder == null)
                {
                    context.Load(list.RootFolder.Folders);
                    context.ExecuteQuery();
                    currentFolder = list.RootFolder.Folders.Where(f => System.Text.RegularExpressions.Regex.IsMatch(f.Name, current)).FirstOrDefault();
                    LoadFolders(currentFolder);
                }
                else
                {
                    Microsoft.SharePoint.Client.Folder x = null;
                    currentFolder.Folders.ToList().ForEach(f =>
                    {
                        if (System.Text.RegularExpressions.Regex.IsMatch(f.Name, current))
                            x = f;

                    });

                    var temp = currentFolder.Folders.Where(f => System.Text.RegularExpressions.Regex.IsMatch(f.Name, current) || f.Name.StartsWith(current)).FirstOrDefault();
                    if (temp != null)
                    {
                        currentFolder = temp;
                        LoadFolders(currentFolder);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            return currentFolder;
        }

        public Microsoft.SharePoint.Client.Folder BuildFolder(Microsoft.SharePoint.Client.List list, string folder)
        {
            List<string> folders = folder.Split('/').ToList();

            Microsoft.SharePoint.Client.Folder currentFolder = null;
            int i = 0;


            while (i < folders.Count)
            {
                char[] charsToTrim = { ',', '.', ' ', '#', '%', '*', ':', '<', '>', '?', '/', '|' };
                string current = folders[i].TrimEnd(charsToTrim);
                if (currentFolder == null)
                {
                    context.Load(list.RootFolder.Folders);
                    context.ExecuteQuery();
                    currentFolder = list.RootFolder.Folders.Where(f => System.Text.RegularExpressions.Regex.IsMatch(f.Name, current)).FirstOrDefault();
                    LoadFolders(currentFolder);
                }
                else
                {
                    var temp = currentFolder.Folders.Where(f => System.Text.RegularExpressions.Regex.IsMatch(f.Name, current) || f.Name.StartsWith(current)).FirstOrDefault();
                    if (temp != null)
                    {
                        currentFolder = temp;
                        LoadFolders(currentFolder);
                    }
                    else
                    {
                        string tmp = current;
                        if (folders.Last() == current)
                        {
                            tmp = current;
                        }
                        CreateFolder(currentFolder, tmp);
                        LoadFolders(currentFolder);
                        i--;
                    }
                }

                i++;
            }

            return currentFolder;
        }

        public Microsoft.SharePoint.Client.File UploadFile(Microsoft.SharePoint.Client.Folder folder, string fileName, string path)
        {
            try
            {
                context.Load(folder.Files);
                context.ExecuteQuery();

                fileName = System.Text.RegularExpressions.Regex.Replace(fileName, @"[^0-9a-zA-Z._ ]", string.Empty);

                string uploadedFileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
                string uploadedFileExtension = Path.GetExtension(fileName);

                int index = 1;

                string newFileName = uploadedFileNameWithoutExtension;

                while (folder.Files.Where(f => f.Name == String.Concat(newFileName, uploadedFileExtension)).Count() > 0)
                {
                    newFileName = uploadedFileNameWithoutExtension + $" ({index})";
                    index++;
                }

                newFileName += uploadedFileExtension;

                byte[] FileContent = null;

                if (System.IO.File.Exists(path))
                {
                    FileContent = System.IO.File.ReadAllBytes(path);
                }
                else
                {
                    FileContent = Convert.FromBase64String(path);
                }


                Microsoft.SharePoint.Client.FileCreationInformation fileCreationInformation = new Microsoft.SharePoint.Client.FileCreationInformation();
                fileCreationInformation.ContentStream = new MemoryStream(FileContent);
                fileCreationInformation.Url = newFileName;

                Microsoft.SharePoint.Client.File file = folder.Files.Add(fileCreationInformation);

                context.Load(file);
                context.ExecuteQuery();

                return file;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public string DownloadFile(Microsoft.SharePoint.Client.Folder folder, string name, string downloadTo = "./")
        {
            try
            {
                context.Load(folder.Files);
                context.ExecuteQuery();

                Microsoft.SharePoint.Client.File file = folder.Files.Where(f => f.Name == name).FirstOrDefault();

                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine(file.ServerRelativeUrl);

                var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(context, file.ServerRelativeUrl);

                var fileName = Path.Combine(downloadTo, (string)file.Name);

                using (var fileStream = System.IO.File.Create(fileName))
                {
                    fileInfo.Stream.CopyTo(fileStream);
                }

                return fileName;
            }
            catch
            {
                return string.Empty;
            }
        }
    }
}
