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 BaseChildItemHandler<TEntity, TParent, TUpdateMsg>(IApiServer server)
    : BaseHandler<TEntity, TUpdateMsg>(server)
    where TEntity : class, IDataObject
    where TParent : 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 parent)
    {
        IQueryable<TEntity> list;

        if (parent != 0 && server.Manager.Find(parent, out TParent? parentEntity))
            list = GetChilds(parentEntity).AsQueryable();
        else
            list = server.Manager.Get<TEntity>();

        return list.ToList().Select(ToClient).ToItemsResult();
    }

    public virtual ApiResult Post(int parent, TUpdateMsg msg)
    {
        if (!server.Manager.Find(parent, out TParent? parentEntity))
            return ApiResult.NotFound();
        var entity = CreateNewEntity(msg);
        if (UpdateEntity(entity, msg) is ApiResult result)
            return result;
        GetChilds(parentEntity).Add(entity);
        server.Manager.Save(parentEntity, true);
        return ToClient(entity).ToItemResult(HttpStatusCode.Created);
    }

    public abstract IList<TEntity> GetChilds(TParent parent);
}
