using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json.Linq;
using Sockeye.Util;
using Sockeye.Models;


namespace Sockeye.Biz
{

    //Prime the database with initial, minimum required data to boot and do things (SuperUser account, translations)
    public static class PrimeData
    {

        /// <summary>
        /// Prime the database with SuperUser account
        /// </summary>    
        public static async Task PrimeSuperUserAccount(AyContext ct)
        {
            //get a db and logger
            //ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger("PrimeData");
            User u = new User();
            u.Active = true;
            u.AllowLogin = true;
            u.Name = "Sockeye SuperUser";
            u.Salt = Hasher.GenerateSalt();
            u.Login = "ss";
            u.Password = Hasher.hash(u.Salt, "ss");
            u.Roles = AuthorizationRoles.Accounting | AuthorizationRoles.BizAdmin | AuthorizationRoles.Inventory | AuthorizationRoles.OpsAdmin | AuthorizationRoles.Sales | AuthorizationRoles.Service;


            u.UserType = UserType.NotService;
            u.UserOptions = new UserOptions();
            u.UserOptions.TranslationId = ServerBootConfig.SOCKEYE_DEFAULT_TRANSLATION_ID;//Ensure primeTranslations is called first
            await ct.User.AddAsync(u);
            await ct.SaveChangesAsync();

        }

        /// <summary>
        /// Prime the database with ShareIt / MyCommerce Vendor account
        /// </summary>    
        public static async Task PrimeVendor(AyContext ct)
        {
            Vendor u = new Vendor();
            u.Active = true;
            u.Name = "MyCommerce";
            await ct.Vendor.AddAsync(u);
            await ct.SaveChangesAsync();

        }



        // //used during development so I don't need to keep installing licenses over and over
        // //just to refresh the translations
        // public static async Task RePrimeTranslations()
        // {
        //     //delete all the translations
        //     using (AyContext ct = ServiceProviderProvider.DBContext)
        //     {
        //         await ct.Database.ExecuteSqlRawAsync("delete from  atranslationitem;");
        //         await ct.Database.ExecuteSqlRawAsync("delete from  atranslation;");
        //     }
        //     //replace
        //     await PrimeTranslations();
        // }


        /// <summary>
        /// Prime the Translations
        /// This may be called before there are any users on a fresh db boot 
        /// </summary>    
        public static async Task PrimeTranslations()
        {//


            //Read in each stock translation from a text file and then create them in the DB
            var ResourceFolderPath = Path.Combine(ServerBootConfig.SOCKEYE_CONTENT_ROOT_PATH, "resource");
            if (!Directory.Exists(ResourceFolderPath))
            {
                throw new System.Exception($"E1012: \"resource\" folder not found where expected: \"{ResourceFolderPath}\", installation damaged?");
            }


            await ImportTranslation(ResourceFolderPath, "en");
            await ImportTranslation(ResourceFolderPath, "es");
            await ImportTranslation(ResourceFolderPath, "fr");
            await ImportTranslation(ResourceFolderPath, "de");

            //Ensure Translations are present, not missing any keys and that there is a server default translation that exists 
            using (AyContext ct = ServiceProviderProvider.DBContext)
            {
                TranslationBiz lb = TranslationBiz.GetBiz(ct);
                await lb.ValidateTranslationsAsync();
            }

        }

        private static async Task ImportTranslation(string resourceFolderPath, string translationCode)
        {
            using (AyContext ct = ServiceProviderProvider.DBContext)
            {
                var TranslationPath = Path.Combine(resourceFolderPath, $"{translationCode}.json");
                if (!File.Exists(TranslationPath))
                {
                    throw new System.Exception($"E1013: stock translation file \"{translationCode}\" not found where expected: \"{TranslationPath}\", installation damaged?");
                }

                JObject o = JObject.Parse(await File.ReadAllTextAsync(TranslationPath));

                Translation l = new Translation();
                l.Name = translationCode;
                l.BaseLanguage = translationCode;
                l.Stock = true;
                l.CjkIndex = false;

                foreach (JToken t in o.Children())
                {
                    var key = t.Path;
                    var display = t.First.Value<string>();
                    l.TranslationItems.Add(new TranslationItem() { Key = key, Display = display });
                }

                await ct.Translation.AddAsync(l);
                await ct.SaveChangesAsync();
            }
        }



        /// <summary>
        /// Prime the Report Templates
        /// </summary>    
        public static async Task PrimeReportTemplates()
        {
            //Read in each stock translation from a text file and then create them in the DB
            var ReportFilesPath = Path.Combine(ServerBootConfig.SOCKEYE_CONTENT_ROOT_PATH, "resource", "rpt", "stock-report-templates");
            if (!Directory.Exists(ReportFilesPath))
            {
                throw new System.Exception($"E1012: \"stock-report-templates\" folder not found where expected: \"{ReportFilesPath}\", installation damaged?");
            }

            //iterate all ayrt files and import each one
            using (AyContext ct = ServiceProviderProvider.DBContext)
            {
                ReportBiz r = ReportBiz.GetBiz(ct);

                System.IO.DirectoryInfo di = new DirectoryInfo(ReportFilesPath);
                foreach (FileInfo file in di.EnumerateFiles())
                {
                    if (file.Extension.ToLowerInvariant() == ".ayrt")
                        await r.ImportAsync(JObject.Parse(await File.ReadAllTextAsync(file.FullName)), true);
                }
            }
        }

    }//eoc

}//eons