using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using AyaNova.Util;
using AyaNova.Api.ControllerHelpers;
using AyaNova.Models;
using AyaNova.DataList;


namespace AyaNova.Biz
{


    internal class DataListTemplateBiz : BizObject
    {

        internal DataListTemplateBiz(AyContext dbcontext, long currentUserId, long userLocaleId, AuthorizationRoles UserRoles)
        {
            ct = dbcontext;
            UserId = currentUserId;
            UserLocaleId = userLocaleId;
            CurrentUserRoles = UserRoles;
            BizType = AyaType.DataListFilter;
        }

        internal static DataListTemplateBiz GetBiz(AyContext ct, Microsoft.AspNetCore.Http.HttpContext httpContext)
        {
            return new DataListTemplateBiz(ct, UserIdFromContext.Id(httpContext.Items), UserLocaleIdFromContext.Id(httpContext.Items), UserRolesFromContext.Roles(httpContext.Items));
        }

        // //Version for internal use
        // internal static DataListTemplateBiz GetBizInternal(AyContext ct)
        // {
        //     return new DataListTemplateBiz(ct, 1, ServerBootConfig.AYANOVA_DEFAULT_LANGUAGE_ID, AuthorizationRoles.BizAdminFull);
        // }



        ////////////////////////////////////////////////////////////////////////////////////////////////
        /// GET       
        internal async Task<DataListTemplate> GetAsync(string DataListKey, bool log, IAyaDataList dataList)
        {
            //DataListKey always exists, if not in db then in default form          
            var ret = await ct.DataListTemplate.SingleOrDefaultAsync(m => m.DataListKey == DataListKey);
            //Not in db?  then put it in the db with the default then return it
            if (ret == null)
            {
                ret = new DataListTemplate();
                ret.DataListKey = dataList.ListKey;
                ret.Template = dataList.DefaultDataListDisplayTemplate;
                await ct.DataListTemplate.AddAsync(ret);
                await ct.SaveChangesAsync();
            }

            if (log)
            {
                //Log
                await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, ret.Id, BizType, AyaEvent.Retrieved), ct);
            }
            return ret;
        }



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

        //put
        internal async Task<bool> PutAsync(DataListTemplate dbObj, DataListTemplate inObj, IAyaDataList dataList)
        {

            //Replace the db object with the PUT object
            CopyObject.Copy(inObj, dbObj, "Id");
            //Set "original" value of concurrency token to input token
            //this will allow EF to check it out
            ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = inObj.ConcurrencyToken;

            if (!dataList.ValidateTemplate(dbObj.Template))
            {
                AddError(ApiErrorCode.VALIDATION_INVALID_VALUE, "Template");
            }
            if (HasErrors)
                return false;

            await ct.SaveChangesAsync();

            //Log modification and save context
            await EventLogProcessor.LogEventToDatabaseAsync(new Event(UserId, dbObj.Id, BizType, AyaEvent.Modified), ct);

            return true;
        }


        ////////////////////////////////////////////////////////////////////////////////////////////////
        //DELETE
        //
        internal async Task<bool> DeleteAsync(DataListTemplate dbObj)
        {
            //no validation required, we have defaults so this is ok anytime
            ct.DataListTemplate.Remove(dbObj);
            await ct.SaveChangesAsync();

            //Event log process delete
            await EventLogProcessor.DeleteObjectLogAsync(UserId, BizType, dbObj.Id, dbObj.DataListKey, ct);
            return true;
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////
        //VALIDATION
        // nothing special required here, it's all tightly controlled and datalist has validation code built in





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

    }//eoc


}//eons

