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

namespace Sockeye.Biz
{

    //## This class manages personal form settings for users

    internal class FormUserOptionsBiz : BizObject
    {
        internal FormUserOptionsBiz(AyContext dbcontext, long currentUserId, long userTranslationId, AuthorizationRoles UserRoles)
        {
            ct = dbcontext;
            UserId = currentUserId;
            UserTranslationId = userTranslationId;
            CurrentUserRoles = UserRoles;
            BizType = SockType.FormUserOptions;
        }

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

        ////////////////////////////////////////////////////////////////////////////////////////////////
        //EXISTS 
        internal async Task<bool> ExistsAsync(long id)
        {
            return await ct.FormUserOptions.AnyAsync(z => z.Id == id);
        }

        ////////////////////////////////////////////////////////////////////////////////////////////////
        //CREATE   
        //
        internal async Task<FormUserOptions> UpsertAsync(FormUserOptions newObject)
        {
            //Validate(newObject, null);
            newObject.UserId=UserId;//always defaults to currently logged in user
            if (HasErrors)
                return null;
            else
            {
                //remove any prior version that might exist (or might not)
                await DeleteAsync(newObject.FormKey);
                newObject.Options = JsonUtil.CompactJson(newObject.Options);
                await ct.FormUserOptions.AddAsync(newObject);
                await ct.SaveChangesAsync();
                return newObject;
            }
        }



        ////////////////////////////////////////////////////////////////////////////////////////////////
        //GET 
        //      
        internal async Task<FormUserOptions> GetAsync(string formKey)
        {
            var ret = await ct.FormUserOptions.AsNoTracking().SingleOrDefaultAsync(m => m.FormKey == formKey && m.UserId == UserId);
            return ret;
        }

        // ////////////////////////////////////////////////////////////////////////////////////////////////
        // //UPDATE
        // //
        // internal async Task<FormUserOptions> PutAsync(FormUserOptions putObject)
        // {
        //     var dbObject = await GetAsync(putObject.FormKey);
        //     if (dbObject == null)
        //     {
        //         AddError(ApiErrorCode.NOT_FOUND, "formKey");
        //         return null;
        //     }
        //     if (dbObject.Concurrency != putObject.Concurrency)
        //     {
        //         AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
        //         return null;
        //     }

        //     putObject.Options = JsonUtil.CompactJson(putObject.Options);
        //     Validate(putObject, dbObject);
        //     if (HasErrors) return null;
        //     ct.Replace(dbObject, putObject);
        //     try
        //     {
        //         await ct.SaveChangesAsync();
        //     }
        //     catch (DbUpdateConcurrencyException)
        //     {
        //         if (!await ExistsAsync(putObject.Id))
        //             AddError(ApiErrorCode.NOT_FOUND);
        //         else
        //             AddError(ApiErrorCode.CONCURRENCY_CONFLICT);
        //         return null;
        //     }

        //     return putObject;
        // }

        ////////////////////////////////////////////////////////////////////////////////////////////////
        //DELETE
        //
        internal async Task<bool> DeleteAsync(string formKey)
        {
            // using (var transaction = await ct.Database.BeginTransactionAsync())
            // {
            var dbObject = await GetAsync(formKey);
            if (dbObject == null)
            {
                return true;
            }
            // ValidateCanDelete(dbObject);
            if (HasErrors)
                return false;
            ct.FormUserOptions.Remove(dbObject);
            await ct.SaveChangesAsync();
            // await transaction.CommitAsync();
            return true;
            // }
        }



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

        // private void Validate(FormUserOptions proposedObj, FormUserOptions currentObj)
        // {
        //     if (proposedObj.UserId != UserId)
        //     {
        //         AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "A user can only modify their own personal form settings. UserId does not match current api user logged in.");
        //     }
        // }

        // private void ValidateCanDelete(FormUserOptions inObj)
        // {
        //     if (inObj.UserId != UserId)
        //     {
        //         AddError(ApiErrorCode.NOT_AUTHORIZED, "generalerror", "A user can only modify their own personal form settings. UserId does not match current api user logged in.");
        //     }

        // }


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

    }//eoc


}//eons

