<?php

namespace apexl\Io\modules\user\classes;

use apexl\Io\enums\HttpMethod;
use apexl\Io\includes\Controller;
use apexl\Io\includes\Entity;
use apexl\Io\includes\RouteManager;
use apexl\Io\modules\user\enums\permissions\Common;
use apexl\Io\modules\user\interfaces\PermissionInterface;
use apexl\Io\recommendedIncludes\apiModule;

class userManagedApiModule extends apiModule
{
    /**
     * Method to add a route, allows the module to have a base path configured and for easy overrides.
     * This Method adds one extra option over the base, to permissions protect a route.
     */
    protected function addProtectedActionRoute(
        RouteManager $routeManager,
        HttpMethod $verb,
        string $name,
        string $pattern,
        $callable,
        PermissionInterface $permission = Common::ALLOW_ALL,
    ): static {
        $this->addActionRoute($routeManager, $verb, $name, $pattern, $callable);
        $routeManager->addRouteArg($name, 'permission', serialize($permission));

        return $this;
    }

    protected function addProtectedAdminActionRoute(
        RouteManager $routeManager,
        HttpMethod $verb,
        string $name,
        string $pattern,
        $callable,
        PermissionInterface $permission = Common::ALLOW_ALL,
    ): static {
        $this->addActionRoute($routeManager, $verb, $name, 'admin/' . $pattern, $callable);
        $routeManager->addRouteArg($name, 'permission', serialize($permission));

        return $this;
    }

    /**
     * Method to add a route, allows the module to have a base path configured and for easy overrides.
     * This Method adds one extra option over the base, to permissions protect a route.
     */
    protected function addProtectedDataRoute(
        RouteManager $routeManager,
        HttpMethod $verb,
        string $name,
        string $pattern,
        $callable,
        PermissionInterface $permission = Common::ALLOW_ALL,
    ): static {
        $this->addDataRoute($routeManager, $verb, $name, $pattern, $callable);
        $routeManager->addRouteArg($name, 'permission', serialize($permission));

        return $this;
    }

    /**
     * Declare intention to build routes for this entity. Will take defaults if not previously defined.
     */
    /**
     * @param class-string<Entity> $entityClass
     */
    protected function addProtectedEntityRoutes(RouteManager $routeManager, string $entityClass, $callables = null, array $patterns = []): static
    {
        $this->setEntityPatterns($entityClass, $patterns);

        foreach ($this->entityPatterns[$entityClass::entityName()] as $verb => $pattern) {
            $this->setEntityCallable($entityClass, $verb, ($callables[$verb][0] ?? Controller::class . ':' . $verb));
        }

        //build the routes.
        $this->buildEntityRoutes($routeManager, $entityClass);
        //protect the built routes
        foreach ($this->entityPatterns[$entityClass::entityName()] as $verb => $pattern) {
            $routeManager->addRouteArg(
                $entityClass::entityName() . '.' . strtolower((string) $verb),
                'permission',
                serialize($callables[$verb][1] ?? Common::ALLOW_ALL)
            );
            $routeManager->addRouteArg(
                $entityClass::entityName() . '.' . strtolower((string) $verb),
                'entity',
                $entityClass
            );
        }

        return $this;
    }
}
