using System;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using AyaNova.Util;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Models;

namespace AyaNova.Biz
{

    internal class GlobalOpsBackupSettingsBiz : BizObject
    {

        internal GlobalOpsBackupSettingsBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
        {
            ct = dbcontext;
            UserId = currentUserId;
            UserTranslationId = userTranslationId;
            CurrentUserRoles = UserRoles;
            BizType = AyaType.Backup;
        }

        internal static GlobalOpsBackupSettingsBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext = null)
        {
            if (httpContext != null)
                return new GlobalOpsBackupSettingsBiz(ct, UserIdFromContext.Id(httpContext.Items), UserTranslationIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
            else
                return new GlobalOpsBackupSettingsBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_TRANSLATION_ID, AuthorizationRoles.BizAdminFull);
        }




        ////////////////////////////////////////////////////////////////////////////////////////////////
        /// GET

        //Get one
        internal async Task<GlobalOpsBackupSettings> GetAsync(bool logTheGetEvent = true)
        {
            //first try to fetch from db
            var ret = await ct.GlobalOpsBackupSettings.SingleOrDefaultAsync(m => m.Id == 1);
            if (logTheGetEvent && ret != null)
                await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, 1, BizType, AyaEvent.Retrieved), ct);
            //expected to exists because it's created on boot if not present
            if (ret == null)
                throw new System.Exception("GlobalOpsBackupSettings::GetAsync -> Backup settings object not found in database!!");

            return ret;
        }



        ////////////////////////////////////////////////////////////////////////////////////////////////
        //UPDATE
        //

        //put
        internal async Task<GlobalOpsBackupSettings> PutAsync(GlobalOpsBackupSettings putObject)
        {
            var dbObject = await ct.GlobalOpsBackupSettings.FirstOrDefaultAsync(m => m.Id == 1);
            if (dbObject == null)
                throw new System.Exception("GlobalOpsBackupSettings::PutAsync -> Global settings object not found in database!!");


            // //testing UTC fuckiness
            // var utcNow = DateTime.UtcNow;

            // var desiredBackupTime = new DateTime(2020, 5, 23, 23, 55, 0).ToUniversalTime();

            // var NextBackup = new DateTime(utcNow.Year, utcNow.Month, utcNow.Day, putObject.BackupTime.Hour, putObject.BackupTime.Minute, 0, DateTimeKind.Utc);
            // if (NextBackup < utcNow) NextBackup = NextBackup.AddDays(1);
            // //theory if nexxtbacup at the end of the adjustment is in the past then add a day to it


            //If backup time has changed then reset last backup as well as it might block from taking effect
            var ResetLastBackup = (putObject.BackupTime.Hour != dbObject.BackupTime.Hour || putObject.BackupTime.Minute != dbObject.BackupTime.Minute);

            CopyObject.Copy(putObject, dbObject, "Id");
            ct.Entry(dbObject).OriginalValues["Concurrency"] = putObject.Concurrency;
            Validate(dbObject);
            if (HasErrors)
                return null;

            try
            {
                await ct.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
                return null;
            }

            await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, 1, BizType, AyaEvent.Modified), ct);
            //Update the static copy for the server
            ServerGlobalOpsSettingsCache.Backup = dbObject;
            if (ResetLastBackup)
            {
                ServerGlobalOpsSettingsCache.NextBackup = DateTime.MinValue;
                ServerGlobalOpsSettingsCache.SetNextBackup();
            }
            return dbObject;
        }



        ////////////////////////////////////////////////////////////////////////////////////////////////
        //VALIDATION
        //

        //Can save or update?
        private void Validate(GlobalOpsBackupSettings inObj)
        {

            //currently nothing to validate
        }




        /////////////////////////////////////////////////////////////////////

    }//eoc


}//eons

