using Pilz.Data;
using Pilz.Extensions.Reflection;
using Pilz.Net.Extensions;
using System.Diagnostics;
using System.Net;

namespace Pilz.Net.Api.Server;

public abstract class BaseItemHandler<TEntity, TUpdateMsg>(IApiServer server)
    : BaseHandler<TEntity, TUpdateMsg>(server)
    where TEntity : class, IDataObject
    where TUpdateMsg : ApiMessage
{
    protected virtual bool RegisterGetAll => true;
    protected virtual bool RegisterPost => true;

    public override void Initialize(IApiServer server)
    {
        base.Initialize(server);
        var t = GetType();
        if (RegisterGetAll)
            server.RegisterHandler(t.GetMethod(nameof(GetAll))!.CreateDelegate(this), new(Route, "GET"), Debugger.IsAttached);
        if (RegisterPost)
            server.RegisterHandler(t.GetMethod(nameof(Post))!.CreateDelegate(this), new(Route, "POST"), Debugger.IsAttached);
    }

    public virtual ApiResult GetAll(int offset, int amount)
    {
        var entities = SortEntities(server.Manager.Get<TEntity>());
        if (offset > 0)
            entities = entities.Skip(offset);
        if (amount > 0)
            entities = entities.Take(amount);
        return entities.ToList().Select(ToClient).ToItemsResult();
    }

    public virtual ApiResult Post(TUpdateMsg msg, ApiRequestInfo req)
    {
        var entity = CreateNewEntity(msg);
        var update = new EntityUpdate(entity, msg, req);
        if (UpdateEntity(update) is ApiResult result)
            return result;
        if (OnSave(update) is ApiResult result2)
            return result2;
        return ToClient(entity).ToItemResult(HttpStatusCode.Created);
    }

    protected virtual IQueryable<TEntity> SortEntities(IQueryable<TEntity> entities)
    {
        return entities;
    }
}
