using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Sockeye.Util;
using Sockeye.Api.ControllerHelpers;
using Sockeye.Models;
using System.Collections.Generic;

namespace Sockeye.Biz
{

    internal class GlobalBizSettingsBiz : BizObject
    {

        internal GlobalBizSettingsBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
        {
            ct = dbcontext;
            UserId = currentUserId;
            UserTranslationId = userTranslationId;
            CurrentUserRoles = UserRoles;
            BizType = SockType.Global;
        }

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




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

        //Get one
        internal async Task<GlobalBizSettings> GetAsync(bool logTheGetEvent = true)
        {
            //first try to fetch from db
            var ret = await ct.GlobalBizSettings.AsNoTracking().SingleOrDefaultAsync(m => m.Id == 1);
            if (logTheGetEvent && ret != null)
            {
                //Log
                await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, 1, BizType, SockEvent.Retrieved), ct);
            }

            //not in db then get the default
            if (ret == null)
            {
                throw new System.Exception("GlobalBizSettingsBiz::GetAsync -> Global settings object not found in database!!");
            }
            return ret;
        }



        ////////////////////////////////////////////////////////////////////////////////////////////////
        //UPDATE
        //
        internal async Task<GlobalBizSettings> PutAsync(GlobalBizSettings putObject)
        {
            var dbObject = await GetAsync(false);
            if (dbObject == null)
                throw new System.Exception("GlobalBizSettingsBiz::PutAsync -> Global settings object not found in database. Contact support immediately!");

            if (dbObject.Concurrency != putObject.Concurrency)
            {
                AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
                return null;
            }
            Validate(putObject, dbObject);
            if (HasErrors) return null;

            List<string> originalTags = dbObject.AllTags();
            List<string> newTags = putObject.AllTags();

            ct.Replace(dbObject, putObject);


            try
            {
                await ct.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
                return null;
            }
            //Update cache
            ServerGlobalBizSettings.Initialize(putObject, null);

            //Log modification and save context
            await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, 1, BizType, SockEvent.Modified), ct);
            await TagBiz.ProcessUpdateTagsInRepositoryAsync(ct, newTags, originalTags);

            return putObject;
        }



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

        //Can save or update?
        private void Validate(GlobalBizSettings proposedObj, GlobalBizSettings currentObj)
        {
            //currently nothing to validate
        }





        //IMPORT FROM ROCKFISH

        public async Task ImportRockfish()
        {
            //connect to rockfish
            //in the correct order retrieve every object and if it's not already present in sockeye, import it
            //this should be callable any time and it will just update so it can be test live in sync / parallel until ready to switch over
await Task.CompletedTask;

        }
        /////////////////////////////////////////////////////////////////////

    }//eoc


}//eons

