using FoodsharingSiegen.Contracts;
using FoodsharingSiegen.Contracts.Entity;
using FoodsharingSiegen.Contracts.Enums;
using FoodsharingSiegen.Server.Auth;
using Microsoft.EntityFrameworkCore;

namespace FoodsharingSiegen.Server.Data.Service
{
    /// <summary>
    /// The audit service class (a. beging, 23.05.2022)
    /// </summary>
    /// <seealso cref="ServiceBase"/>
    public class AuditService : ServiceBase
    {
        #region Setup/Teardown

        /// <summary>
        /// Initializes a new instance of the <see cref="AuditService"/> class
        /// </summary>
        /// <param name="context">The context (ab)</param>
        /// <param name="authService"></param>
        public AuditService(FsContext context, AuthService authService) : base(context, authService) { }

        #endregion

        #region Public Method Insert

        /// <summary>
        /// Inserts the type (a. beging, 23.05.2022)
        /// </summary>
        /// <param name="type">The type</param>
        /// <param name="data1">The data</param>
        /// <param name="data2">The data</param>
        /// <returns>A task containing an operation result of audit</returns>
        public async Task<OperationResult<Audit>> Insert(AuditType type, string? data1 = null, string? data2 = null)
        {
            try
            {
                var audit = new Audit
                {
                    Created = DateTime.Now,
                    Type = type,
                    UserID = CurrentUser?.Id,
                    Data1 = data1,
                    Data2 = data2
                };

                Console.WriteLine();
                Console.WriteLine(DateTime.Now.ToString() + " " + CurrentUser?.Name + " " + AuditHelper.CreateText(audit));
                Console.WriteLine();

                Context.Audits?.Add(audit);
                var saveR = await Context.SaveChangesAsync();
            
                if (saveR > 0)
                    return new(audit);
            
                return new(new Exception("Couldn't add audit"));
            }
            catch (Exception e)
            {
                return new(e);
            }
        }

        #endregion

        #region Public Method GetCount

        /// <summary>
        /// Gets the total count (ab)
        /// </summary>
        /// <param name="type">The type</param>
        /// <returns>A task containing an operation result of count</returns>
        public async Task<OperationResult<int>> GetCount(AuditType? type = null)
        {
            try
            {
                var query = Context.Audits?.AsQueryable();

                if (type != null)
                    query = query?.Where(x => x.Type == type);

                if (query == null) return new(0);

                var count = await query.CountAsync();
                return new(count);
            }
            catch (Exception e)
            {
                return new(e);
            }
        }

        #endregion

        #region Public Method LoadPage

        /// <summary>
        /// Loads the page of audits (ab)
        /// </summary>
        /// <param name="skip">The skip count</param>
        /// <param name="take">The take count</param>
        /// <param name="type">The type</param>
        /// <returns>A task containing an operation result of list audit</returns>
        public async Task<OperationResult<List<Audit>>> LoadPage(int skip, int take, AuditType? type = null)
        {
            try
            {
                var query = Context.Audits?.Include(x => x.User).OrderByDescending(x => x.Created).AsQueryable();

                if (type != null)
                    query = query?.Where(x => x.Type == type);

                query = query?.Skip(skip).Take(take);

                var mat = await query!.ToListAsync();

                if (mat != null) return new(mat);

                return new(new Exception("Couldn't load audits"));
            }
            catch (Exception e)
            {
                return new(e);
            }
        }

        #endregion
    }
}