<?php

declare(strict_types=1);

namespace PrettyLinks\Pro\Rest;

use PrettyLinks\Pro\Repositories\Categories as CategoriesRepo;
use PrettyLinks\Rest\Controllers\BaseController;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

class CategoriesController extends BaseController
{
    /**
     * Register the categories REST routes.
     *
     * @return void
     */
    public function register(): void
    {
        register_rest_route($this->namespace(), '/categories', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'index'],
                'permission_callback' => $this->permission(),
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'create'],
                'permission_callback' => $this->permission(),
            ],
        ]);

        register_rest_route($this->namespace(), '/categories/(?P<id>\d+)', [
            [
                'methods'             => WP_REST_Server::EDITABLE,
                'callback'            => [$this, 'update'],
                'permission_callback' => $this->permission(),
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [$this, 'delete'],
                'permission_callback' => $this->permission(),
            ],
        ]);
    }

    /**
     * Return all categories.
     *
     * @return WP_REST_Response
     */
    public function index(): WP_REST_Response
    {
        return new WP_REST_Response($this->repo()->all());
    }

    /**
     * Create a category from the request body.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function create(WP_REST_Request $request): WP_REST_Response
    {
        $data = (array) $request->get_json_params();
        $row  = $this->repo()->create($data);
        return new WP_REST_Response($row, 201);
    }

    /**
     * Update a category by id.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function update(WP_REST_Request $request): WP_REST_Response
    {
        $id   = (int) $request['id'];
        $data = (array) $request->get_json_params();
        $row  = $this->repo()->update($id, $data);
        if ($row === null) {
            return new WP_REST_Response(['error' => 'not_found'], 404);
        }
        return new WP_REST_Response($row);
    }

    /**
     * Delete a category by id.
     *
     * @param WP_REST_Request $request Incoming REST request.
     *
     * @return WP_REST_Response
     */
    public function delete(WP_REST_Request $request): WP_REST_Response
    {
        $id = (int) $request['id'];
        $ok = $this->repo()->delete($id);
        return new WP_REST_Response(['success' => $ok]);
    }

    /**
     * Resolve the categories repository from the container.
     *
     * @return CategoriesRepo
     */
    private function repo(): CategoriesRepo
    {
        return $this->container->get(CategoriesRepo::class);
    }
}
